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 对象,且其类型(顶点着色器或片段着色器)必须与代码匹配。
相关推荐
刘一说19 小时前
腾讯位置服务JavaScript API GL地图组件库深度解析:Vue生态中的地理空间可视化利器
javascript·vue.js·信息可视化·webgl·webgis
烛阴1 天前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
WebGISer_白茶乌龙桃2 天前
Cesium实现“悬浮岛”式,三维立体的行政区划
javascript·vue.js·3d·web3·html5·webgl
烛阴2 天前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
WebGISer_白茶乌龙桃3 天前
Vue3 + Mapbox 加载 SHP 转换的矢量瓦片 (Vector Tiles)
javascript·vue.js·arcgis·webgl
ThreePointsHeat7 天前
Unity WebGL打包后启动方法,部署本地服务器
unity·游戏引擎·webgl
林枫依依8 天前
电脑配置流程(WebGL项目)
webgl
冥界摄政王10 天前
CesiumJS学习第四章 替换指定3D建筑模型
3d·vue·html·webgl·js·cesium
温宇飞12 天前
高效的线性采样高斯模糊
javascript·webgl
冥界摄政王13 天前
Cesium学习第一章 安装下载 基于vue3引入Cesium项目开发
vue·vue3·html5·webgl·cesium