You need to enable JavaScript to run this app. WebGL2中如何实现雨效与环形点群绘制对象共享同一顶点着色器?
优惠活动
大模型
产品
解决方案
定价
更多

WebGL2中如何实现雨效与环形点群绘制对象共享同一顶点着色器?

两种可落地的合并实现方案

方案1:单着色器分支路由(一次绘制调用完成)

核心逻辑是利用gl_VertexID做顶点区间分流,把两类顶点的生成逻辑合并到同一个顶点着色器内,全程不需要外部顶点缓冲区传入数据。

  • 对原两个着色器的uniform做去重重命名,避免同名变量冲突:将原雨效的numVerts改为rainCount,原环形的numVerts改为circleCount,合并后所有uniform为:rainCount、circleCount、time、resolution
  • 着色器内通过顶点ID判断当前属于哪类对象,执行对应位置、点大小的计算逻辑
    合并后的完整顶点着色器代码如下:
#version 300 es
uniform int rainCount;
uniform int circleCount;
uniform float time;
uniform vec2 resolution;

#define PI radians(180.0)

float hash(float p) {
  vec2 p2 = fract(vec2(p * 5.3983, p * 5.4427));
  p2 += dot(p2.yx, p2.xy + vec2(21.5351, 14.3137));
  return fract(p2.x * p2.y * 95.4337);
}

void main() {
  int vid = gl_VertexID;
  if (vid < rainCount) {
    // 雨效生成逻辑
    float u = float(vid) / float(rainCount);
    float off = floor(time + u) / 1000.0;
    float x = hash(u + off) * 2.0 - 1.0;
    float y = fract(time + u) * -2.0 + 1.0;
    gl_Position = vec4(x, y, 0, 1);
    gl_PointSize = 2.0;
  } else {
    // 环形点生成逻辑
    int circleVid = vid - rainCount;
    float u = float(circleVid) / float(circleCount);
    float angle = u * PI * 2.0;
    float radius = 0.8;
    vec2 pos = vec2(cos(angle), sin(angle)) * radius;
    float aspect = resolution.y / resolution.x;
    vec2 scale = vec2(aspect, 1);
    gl_Position = vec4(pos * scale, 0, 1);
    gl_PointSize = 5.0;
  }
}

JS端调用时只需发起1次绘制调用,总顶点数为rainCount + circleCount,不需要绑定任何顶点缓冲区:

// 单次绘制总顶点数为两类顶点之和
gl.drawArrays(gl.POINTS, 0, rainCount + circleCount);

方案2:同上下文独立程序连续绘制(零着色器改动)

如果不想修改原有两个独立着色器的代码,可直接在同一个WebGL2上下文内连续发起两次绘制,共享同一个画布帧缓冲,两类绘制的着色器逻辑完全隔离,不会出现gl_Position、gl_PointSize的逻辑冲突:

  1. 分别为雨效、环形图案编译两个独立的着色器程序,保留原有代码完全不变
  2. 每帧渲染流程:
    • 激活雨效对应的着色器程序,传入numVerts、time两个uniform值,执行gl.drawArrays(gl.POINTS, 0, 雨效顶点数)
    • 激活环形图案对应的着色器程序,传入numVerts、resolution两个uniform值,执行gl.drawArrays(gl.POINTS, 0, 环形顶点数)
  • 该方案完全兼容原有“顶点全靠着色器内部gl_VertexID生成、无外部缓冲区传入”的模式,不需要调整原有生成逻辑。
  • 可通过调整两次drawArrays的调用顺序控制图层上下层级,比如将雨效绘制放在环形绘制之后,即可实现雨效在环形图案上方叠加的效果。

两种方案的选择依据:

  • 追求低状态切换开销、单次绘制效率优先,选方案1
  • 要最大程度保留原有独立着色器的可维护性、零改动成本优先,选方案2

内容的提问来源于stack exchange,提问作者AngryWeeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 19:54:04