Lee Stemkoski Lee Stemkoski - 11 months ago 137
Javascript Question

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.

// 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);
}


enter image description here

Live example at 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. I (incorrectly) assumed that this would involve changing the values of
x
and
y
to
x = v.x / width
and
y = v.y / height
(where
width
and
height
store the window's width and 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?

Answer Source

Your variable v is in clip space. You need to apply the perspective divide to map that to normalized device coordinate ( NDC ) space, which takes values in the range [ -1, 1 ]. Then, you need to map that value to the range [ 0, 1 ] like so:

    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/

three.js r.62

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download