[英]Three.js - a vertex shader to color based on location of pixel on screen
Using Three.js, I have written a vertex shader that colors each point in a plane according to which quadrant of the screen a pixel is rendered. 使用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);
}
Live example at jsFiddle: http://jsfiddle.net/Stemkoski/ST4aM/ jsFiddle的实时示例: http : //jsfiddle.net/Stemkoski/ST4aM/
I would like to modify this shader so that x
is equal to 0 on the left side of the screen and 1 on the right side of the screen, and similarly y
equal to 0 on the top and 1 on the bottom. 我想修改此着色器,以使
x
在屏幕的左侧等于0,在屏幕的右侧等于1,类似地, y
等于顶部等于0,底部等于1。 I (incorrectly) assumed that this would involve changing the values of x
and y
to x = vx / width
and y = vy / height
(where width
and height
store the window's width and height). 我(错误地)假设这将涉及将
x
和y
的值更改为x = vx / width
和y = vy / height
(其中width
和height
存储窗口的宽度和高度)。 However, with this change the colors at each screen pixel seem to change when zooming in and out on the plane. 但是,通过此更改,在平面上放大和缩小时,每个屏幕像素处的颜色似乎都发生了变化。
How can I fix the shader code to have the desired effect? 如何修复着色器代码以获得所需的效果?
Your variable v
is in clip space. 您的变量
v
在剪辑空间中。 You need to apply the perspective divide to map that to normalized device coordinate ( NDC ) space, which takes values in the range [ -1, 1 ]. 您需要应用透视图划分,以将其映射到标准化设备坐标(NDC)空间,该空间的取值范围为[-1,1]。 Then, you need to map that value to the range [ 0, 1 ] like so:
然后,您需要将该值映射到[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 );
fiddle: http://jsfiddle.net/ST4aM/4/ 小提琴: http : //jsfiddle.net/ST4aM/4/
three.js r.62 three.js r.62
Just an addition to WestLangley's answer. 只是WestLangley答案的补充。
I encountered a small bug that my vertex position was being calculated slightly wrong. 我遇到了一个小错误,该错误表明我的顶点位置计算有点错误。 Seemed that it was in range of (-1.1, 1.1).
似乎在(-1.1,1.1)范围内。 So after experimenting it turned out that
vz
is not exactly correct, it is dependent on near field clip plane, which people usually leave as 1 in camera setup. 因此,经过实验后,发现
vz
并非完全正确,它取决于近场剪辑平面,人们通常在相机设置中将其保留为1。 So adding 2 to vz
seems have fixed it. 因此,在
vz
添加2似乎可以解决此问题。 I don't understand why 2 and not 1. 我不明白为什么2而不是1。
x = v.x / (v.z + 2.0); // depth + 2 x near clip space plane dist (camera setting)
So if you are working with large objects like in WestLangley's example, you won't notice it, but if your objects are small and close to camera then the error will be noticeable. 因此,如果您正在使用大型物体(如WestLangley的示例),则不会注意到它,但是如果物体较小且靠近相机,则错误将很明显。
I've modified above example to clip color if position is not within (0,1) for Y and fixed calculation for X. Plane size is 20, camera distance is 30. 我已经修改了上面的示例,如果Y的位置不在(0,1)内,并且X的计算固定,则可以裁剪颜色。平面大小为20,相机距离为30。
It's still not perfect. 它仍然不是完美的。 If object gets very close to the camera it still messes up the position, but at least this makes it work with medium sized objects.
如果物体非常靠近相机,它仍然会弄乱位置,但这至少可以使它与中等大小的物体配合使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.