webgl2 方法解析: shaderSource()

在 WebGL 2 中,shaderSource() 是一个非常重要的方法,用于向 WebGL 程序的着色器对象中加载着色器代码。以下是关于 shaderSource() 的详细说明:

1. 方法定义

shaderSource() 是 WebGL 2 API 的一部分,用于将着色器代码(通常是用 GLSL 编写的)加载到着色器对象中。它是一个 WebGLRenderingContext 的方法。

2. 语法

arduino 复制代码
void gl.shaderSource(shader, source);

参数

  • shader

    • 类型:WebGLShader
    • 指定要加载着色器代码的着色器对象。着色器对象可以通过 gl.createShader() 创建。
  • source

    • 类型:string
    • 包含着色器代码的字符串。着色器代码是用 GLSL(OpenGL Shading Language)编写的,用于定义顶点着色器或片段着色器的逻辑。

3. 使用场景

在 WebGL 中,渲染管线分为两个主要阶段:顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。每个着色器都需要一段 GLSL 代码来定义其行为。shaderSource() 的作用就是将这些代码加载到对应的着色器对象中。

4. 示例代码

以下是一个完整的示例,展示如何使用 shaderSource() 加载着色器代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebGL2 - Render a Triangle</title>
  <style>
    canvas {
      display: block;
      margin: 0 auto;
      border: 1px solid black;
    }
  </style>
</head>
<body>
  <canvas id="glCanvas" width="640" height="480"></canvas>
  <script>
    // 获取 canvas 元素
    const canvas = document.getElementById('glCanvas');
    const gl = canvas.getContext('webgl2');
​
    if (!gl) {
      alert('WebGL2 不被支持');
      throw new Error('WebGL2 不被支持');
    }
​
    // 顶点着色器代码
    const vertexShaderSource = `#version 300 es
      in vec4 a_position;
      void main() {
        gl_Position = a_position;
      }
    `;
​
    // 片段着色器代码
    const fragmentShaderSource = `#version 300 es
      precision highp float;
      out vec4 outColor;
      void main() {
        outColor = vec4(1.0, 0.5, 0.2, 1.0); // 橙色
      }
    `;
​
    // 创建着色器
    function createShader(gl, type, source) {
      const shader = gl.createShader(type);
      gl.shaderSource(shader, source);
      gl.compileShader(shader);
      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.error('着色器编译失败:', gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
      }
      return shader;
    }
​
    // 创建程序
    function createProgram(gl, vertexShader, fragmentShader) {
      const program = gl.createProgram();
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      gl.linkProgram(program);
      if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        console.error('程序链接失败:', gl.getProgramInfoLog(program));
        gl.deleteProgram(program);
        return null;
      }
      return program;
    }
​
    // 创建顶点着色器和片段着色器
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
​
    // 创建程序并使用
    const program = createProgram(gl, vertexShader, fragmentShader);
    gl.useProgram(program);
​
    // 顶点数据
    const vertices = new Float32Array([
      -0.5, -0.5, 0.0,  // 顶点1
       0.5, -0.5, 0.0,  // 顶点2
       0.0,  0.5, 0.0   // 顶点3
    ]);
​
    // 创建缓冲区对象
    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // 绑定缓冲区对象到 ARRAY_BUFFER
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); // 传输顶点数据到缓冲区
​
    // 获取顶点属性位置并启用
    const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
    gl.enableVertexAttribArray(positionAttributeLocation);
​
    // 设置顶点属性指针
    gl.vertexAttribPointer(
      positionAttributeLocation, // 属性位置
      3,                         // 每个顶点的分量数量
      gl.FLOAT,                  // 数据类型
      false,                     // 是否归一化
      0,                         // 每个顶点的字节偏移量
      0                          // 数据起始偏移量
    );
​
    // 设置视口大小
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
​
    // 清空画布
    gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置背景颜色为黑色
    gl.clear(gl.COLOR_BUFFER_BIT);
​
    // 绘制三角形
    gl.drawArrays(gl.TRIANGLES, 0, 3);
​
  </script>
</body>
</html>

5. 注意事项

  • 着色器代码格式shaderSource() 的第二个参数是一个字符串,因此需要确保 GLSL 代码格式正确,且没有语法错误。
  • 编译错误处理 :加载着色器代码后,需要调用 gl.compileShader() 编译着色器,并通过 gl.getShaderParameter()gl.getShaderInfoLog() 检查编译是否成功。
  • 着色器类型shaderSource() 的第一个参数必须是一个有效的 WebGLShader 对象,且其类型(顶点着色器或片段着色器)必须与代码匹配。
相关推荐
GISer_Jing8 小时前
WebGL跨端兼容实战:移动端适配全攻略
前端·aigc·webgl
Aurora@Hui3 天前
WebGL & Three.js
webgl
CC码码5 天前
基于WebGPU实现canvas高级滤镜
前端·javascript·webgl·fabric
ct9785 天前
WebGL 图像处理核心API
图像处理·webgl
ct9787 天前
Cesium 矩阵系统详解
前端·线性代数·矩阵·gis·webgl
ct97810 天前
WebGL Shader性能优化
性能优化·webgl
棋鬼王10 天前
Cesium(一) 动态立体墙电子围栏,Wall墙体瀑布滚动高亮动效,基于Vue3
3d·信息可视化·智慧城市·webgl
Longyugxq13 天前
Untiy的Webgl端网页端视频播放,又不想直接mp4格式等格式的。
unity·音视频·webgl
花姐夫Jun13 天前
cesium基础学习-坐标系统相互转换及相应的场景
学习·webgl
ct97814 天前
WebGL开发
前端·gis·webgl