【问题标题】:Drawing multiple objects while making them share a shader绘制多个对象,同时让它们共享一个着色器
【发布时间】:2021-07-17 05:42:45
【问题描述】:

我想将两个绘图对象组组合到一个画布中,一个雨效果层和一个形成圆圈的点。这些是他们的顶点着色器代码,取自this website

// Rain effect
const vs = `#version 300 es
uniform int numVerts;
uniform float time;

// hash function from https://www.shadertoy.com/view/4djSRW
// given a value between 0 and 1
// returns a value between 0 and 1 that *appears* kind of random
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() {
  float u = float(gl_VertexID) / float(numVerts);  // goes from 0 to 1
  float off = floor(time + u) / 1000.0;            // changes once per second per vertex
  float x = hash(u + off) * 2.0 - 1.0;             // random position
  float y = fract(time + u) * -2.0 + 1.0;          // 1.0 ->  -1.0

  gl_Position = vec4(x, y, 0, 1);
  gl_PointSize = 2.0;
}
`;
// Points forming a circle
const vs = `#version 300 es
uniform int numVerts;
uniform vec2 resolution;

#define PI radians(180.0)

void main() {
  float u = float(gl_VertexID) / float(numVerts);  // goes from 0 to 1
  float angle = u * PI * 2.0;                      // goes from 0 to 2PI
  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;
}
`;

两个着色器为 gl_Position 和 gl_PointSize 分配不同的值。我想不出一种将它们组合在一个顶点着色器下而不会发生冲突的方法。顶点数据集完全在现场生成,在着色器内部而不是从缓冲区传递,这无济于事。

【问题讨论】:

标签: glsl webgl webgl2


【解决方案1】:

向着色器添加一个统一变量,指示使用哪种算法。

#version 300 es
uniform int numVerts;
uniform float time;

uniform int mode; // 0 or 1

// hash function 
// [...]

void main() {
    float u = float(gl_VertexID) / float(numVerts);  // goes from 0 to 1
  
    vec2 pos;
    float pointSize;
    if (mode == 0) {
         float off = floor(time + u) / 1000.0;            // changes once per second per vertex
         float x = hash(u + off) * 2.0 - 1.0;             // random position
         float y = fract(time + u) * -2.0 + 1.0;          // 1.0 ->  -1.0

         pos = vec2(x, y);
         pointSize = 2.0
    }
    else {
        float angle = u * PI * 2.0;                      // goes from 0 to 2PI
        float radius = 0.8;
        float aspect = resolution.y / resolution.x;
        vec2 scale = vec2(aspect, 1);

        pos = vec2(cos(angle), sin(angle)) * radius * scale;
        pointSize = 5.0;
    }
 
    gl_Position = vec4(pos, 0, 1);
    gl_PointSize = pointSize;
}

【讨论】:

    猜你喜欢
    • 2021-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    相关资源
    最近更新 更多