简体   繁体   English

Three.js-一个顶点着色器,可根据屏幕上像素的位置进行着色

[英]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). 我(错误地)假设这将涉及将xy的值更改为x = vx / widthy = vy / height (其中widthheight存储窗口的宽度和高度)。 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。

顶点位置计算错误

jsFiddle 的jsfiddle

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM