[英]Three.js - a vertex shader to color based on location of pixel on screen
使用Three.js,我编写了一个顶点着色器,根据着色像素在屏幕上的象限,为平面中的每个点着色。
// vertex shader
uniform float width;
uniform float height;
varying float x;
varying float y;
void main()
{
vec4 v = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
x = v.x;
y = v.y;
gl_Position = v;
}
// fragment shader
varying float x;
varying float y;
void main()
{
gl_FragColor = vec4(x, y, 0.0, 1.0);
}
jsFiddle的实时示例: http : //jsfiddle.net/Stemkoski/ST4aM/
我想修改此着色器,以使x
在屏幕的左侧等于0,在屏幕的右侧等于1,类似地, y
等于顶部等于0,底部等于1。 我(错误地)假设这将涉及将x
和y
的值更改为x = vx / width
和y = vy / height
(其中width
和height
存储窗口的宽度和高度)。 但是,通过此更改,在平面上放大和缩小时,每个屏幕像素处的颜色似乎都发生了变化。
如何修复着色器代码以获得所需的效果?
您的变量v
在剪辑空间中。 您需要应用透视图划分,以将其映射到标准化设备坐标(NDC)空间,该空间的取值范围为[-1,1]。 然后,您需要将该值映射到[0,1]范围,如下所示:
vec4 v = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
x = v.x / v.z;
y = v.y / v.z;
gl_FragColor = vec4( 0.5 * x + 0.5, - 0.5 * y + 0.5, 0.0, 1.0 );
小提琴: http : //jsfiddle.net/ST4aM/4/
three.js r.62
只是WestLangley答案的补充。
我遇到了一个小错误,该错误表明我的顶点位置计算有点错误。 似乎在(-1.1,1.1)范围内。 因此,经过实验后,发现vz
并非完全正确,它取决于近场剪辑平面,人们通常在相机设置中将其保留为1。 因此,在vz
添加2似乎可以解决此问题。 我不明白为什么2而不是1。
x = v.x / (v.z + 2.0); // depth + 2 x near clip space plane dist (camera setting)
因此,如果您正在使用大型物体(如WestLangley的示例),则不会注意到它,但是如果物体较小且靠近相机,则错误将很明显。
我已经修改了上面的示例,如果Y的位置不在(0,1)内,并且X的计算固定,则可以裁剪颜色。平面大小为20,相机距离为30。
它仍然不是完美的。 如果物体非常靠近相机,它仍然会弄乱位置,但这至少可以使它与中等大小的物体配合使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.