无需调试,只需尝试理解一些概念性的事情。
我正在按照 this 教程来根据文本纹理的 Alpha 值创建实例化粒子。我对着色器还是新手,所以你可能会想象我只在
sampler2D
中使用了 texture2D
和 fragment shader
以及所需的 UV
s。
本教程是我第一次看到
vertex shader
中使用的纹理。我确实明白图像不能仅通过在顶点阶段采样来“显示”在屏幕上,他只是试图通过 Javascript 提供的变量 texCoord
抛出一堆 0 到 1 之间的随机点,如下所示:
const num = 20000;
let texCoord = new Float32Array(num * 2);
for (let i = 0; i < num; i++) {
// -0.5 to 0.5
let x = (Math.random() * 2 - 1) * 0.5;
let y = (Math.random() * 2 - 1) * 0.5;
// This is setting the pixel spots for texture picking in verter shader
texCoord.set([
x + 0.5,
y + 0.5
], i * 2);
}
我想了解:
如何通过在每个 num 个粒子上保存随机 xy 值,为具有变量
texCoord
的图像(这是一个具有透明度的 png)创建新的坐标系?我的意思是那些 texCoord
点在背景中没有平面来引用 0 到 1 剪切坐标。由于顶点着色器在每个顶点上运行,因此 texCoord
应该将 0-1 值映射到微小的实例平面上,而不是背景上。是吗?
它是如何使“TEXT”图像以某种方式占据顶点着色器中假想背景平面上的全屏(通过它我们提取它的alpha)。也许我缺少
sampler2D
函数的某些功能?
我的意思是,我期望创建一个占据整个场景的非实例平面,然后我们对其应用纹理,只有在那之后我们才能提取其 alpha 值。我花了几个小时研究和阅读,但没有找到可以解释这一点的文章和教程。
我恳请您用通俗的语言解释一下。谢谢。
顶点着色器:
// Bring attributes
attribute vec3 offset;
attribute vec2 texCoord;
attribute vec2 a_lineHeight;
void main() {
vec3 pos = position;
v_uv = uv;
// HERE the image is sampled using texCoord points.
float tex1 = step( .8, texture2D(u_tex1, texCoord).r );
v_alpha = tex1;
float scale = mix(a_lineHeight.x, a_lineHeight.y * 5., u_lineHeight);
pos.y *= scale;
pos.x *= u_thickness;
vec2 origin = texCoord * vec2(1., .5);
float alpha = 1. - v_alpha;
pos.xy += origin - vec2(0.5, 0.25) + alpha;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
片段着色器:
precision highp float;
varying float v_alpha;
uniform float u_time;
void main() {
vec3 color = vec3(1., 1., 1.);
gl_FragColor = vec4(color, v_alpha);
}
当然,纹理查找对几何体的位置没有影响。 然而,
texCoord
不仅用于采样纹理,还用于计算剪辑空间中的位置:
vec2 origin = texCoord * vec2(1., .5);
...
pos.xy += origin - vec2(0.5, 0.25) + alpha;
...
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
所以在这种情况下
texCoord
使用了两次。一旦进入 texture2D
并确定剪辑空间中的位置。