WebGL入门(十三)-通过片元着色器内置变量gl_FragCoord验证内插过程

通过片元着色器内置变量gl_FragCoord验证内插过程

1.demo效果

在这里插入图片描述

如上图,这个demo实现一个紫色渐变效果的三角形,通过使用内置变量FragCoord模拟内插过程实现的

2. 片元着色器的内置变量gl_FragCoord

类型和变量 描述
vec4 gl_FragCoord 该内置变量的第一参数表示片元在canvas坐标系中的横坐标,第二参数表示片元在canvas坐标系中的纵坐标

使用示例

'precision mediump float;\\n' + // 设置精度
'uniform float u_Width;\\n' + //声明uniform变量u_Width,用来接收canvas画布的宽度
'uniform float u_Height;\\n' + //声明uniform变量u_Height,用来接收canvas画布的高度
'void main(){\\n' +
//使用内置变量gl_FragCoord计算颜色并赋值给内置变量gl_FragColor
' gl_FragColor = vec4(gl_FragCoord.x/u_Width, 0.0, gl_FragCoord.y/u_Height, 1.0);\\n' +
'}\\n';

以上示例中片元的颜色取决于它的坐标位置,片元颜色会随着片元位置的变化而逐渐变化,所以呈现的图形颜色会有平滑的渐变效果

3. demo代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <!--通过canvas标签创建一个400px*400px大小的画布-->
  <canvas id="webgl" width="400" height="400"></canvas>

  <script>
    //顶点着色器
    var VSHADER_SOURCE = '' +
      'attribute vec4 a_Position;\\n' + //声明attribute变量a_Position,用来存放顶点位置信息
      'void main(){\\n' +
      '  gl_Position = a_Position;\\n' + //变量a_Position赋值给顶点着色器内置变量gl_Position
      '}\\n';

    //片元着色器
    var FSHADER_SOURCE = '' +
      'precision mediump float;\\n' + // 设置精度
      'uniform float u_Width;\\n' + //声明uniform变量u_Width,用来接收canvas画布的宽度
      'uniform float u_Height;\\n' + //声明uniform变量u_Height,用来接收canvas画布的高度
      'void main(){\\n' +
      //使用内置变量gl_FragCoord计算颜色并赋值给内置变量gl_FragColor
      ' gl_FragColor = vec4(gl_FragCoord.x/u_Width, 0.0, gl_FragCoord.y/u_Height, 1.0);\\n' +
      '}\\n';

    //初始化着色器函数
    function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE) {
      //创建顶点着色器对象
      var vertexShader = gl.createShader(gl.VERTEX_SHADER);
      //创建片元着色器对象
      var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      //引入顶点、片元着色器源代码
      gl.shaderSource(vertexShader, VSHADER_SOURCE);
      gl.shaderSource(fragmentShader, FSHADER_SOURCE);
      //编译顶点、片元着色器
      gl.compileShader(vertexShader);
      gl.compileShader(fragmentShader);

      //创建程序对象program
      var program = gl.createProgram();
      //附着顶点着色器和片元着色器到program
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      //链接program
      gl.linkProgram(program);
      //使用program
      gl.useProgram(program);
      gl.program = program
      //返回程序program对象
      return program;
    }

    function init() {
      //通过getElementById()方法获取canvas画布
      var canvas = document.getElementById('webgl');
      //通过方法getContext()获取WebGL上下文
      var gl = canvas.getContext('webgl');
      //初始化着色器
      initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE);

      // 设置canvas的背景色
      gl.clearColor(0.0, 0.0, 0.0, 1.0);

      //清空canvas
      gl.clear(gl.COLOR_BUFFER_BIT);

      //初始化顶点坐标和颜色
      var n = initVertexBuffers(gl)

      //绘制三角形
      gl.drawArrays(gl.TRIANGLES, 0, n)

    }

    //初始化顶点坐标和颜色
    function initVertexBuffers(gl) {
      var vertices = new Float32Array([
        0.0, 0.5,
        -0.5, -0.5,
        0.5, -0.5,
      ])

      //创建缓冲区对象
      var vertexBuffer = gl.createBuffer();
      if (!vertexBuffer) {
        console.log('创建缓冲区对象失败!')
        return -1
      }

      //将顶点坐标和颜色写入缓冲区对象
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

      //获取类型化数组中每个元素的大小
      var FSIZE = vertices.BYTES_PER_ELEMENT

      var vertexBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);


      //获取着色器attribute变量a_Position的存储地址, 分配缓存并开启
      var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 2, 0);
      gl.enableVertexAttribArray(a_Position);

      //获取着色器uniform变量u_Width的存储地址,并传值
      var u_Width = gl.getUniformLocation(gl.program, 'u_Width');
      gl.uniform1f(u_Width, gl.drawingBufferWidth);

      //获取着色器uniform变量u_Height的存储地址,并传值
      var u_Height = gl.getUniformLocation(gl.program, 'u_Height');
      gl.uniform1f(u_Height, gl.drawingBufferHeight);

      return vertices.length / 2
    }
    init()
  </script>
</body>

</html>

© 版权声明
THE END
喜欢就支持一下吧
点赞149 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容