Search code examples
javascriptthree.jsglslshaderfragment-shader

Change Points from squares to rectangles


I have an image which I split into particles. Those particles are by default squares. Now I want them to look like rectangles. I know that non-uniform scale is not possible for points but do you have a suggestion how to still achieve this goal?

Currently this is the custom fragment Shader:

vec2 pUv = gl_PointCoord;
pUv.y = 1. - pUv.y;
vec2 uv = vUv + vSize * pUv;
vec4 texColor = texture2D( texture, uv );
outgoingLight *= texColor.xyz;
gl_FragColor = vec4( outgoingLight, texColor.a * diffuseColor.a );

Now I would need each square to look like a rectangle with size: x: 0.7, y: 1. Could I achieve this by making the square partially transparent? I couldn't find an example where this has been already done.

Here is the example which I have so far: https://jsfiddle.net/7jtvkh0x/


Solution

  • Now I would need each square to look like a rectangle with size: x: 0.7, y: 1.

    To do what you want you've to scale the x component of the texture coordinate by '1.0/0.7`. As a result, the texture appears on the square as if it were it squeezed to rectangle. Modifying the coordinate by 0.5 before and -0.5 after, makes the squeezing symmetrically to the center of the quad.

    pUv.x = (pUv.x - 0.5) / 0.7 + 0.5;
    

    Could I achieve this by making the square partially transparent?

    Using the discard keyword in the fragment shader, causes the fragment's output values to be discarded. This means the fragments do not modify the framebuffer and appear as to be completely transparent.

    Discard the fragments with a x component of the modified texture coordinate above 1.0 or below 0.0, to clip the quad to a rectangle:

    if ( pUv.x > 1.0 || pUv.x < 0.0 )
        discard; 
    

    The final fragment shader may look like this:

    vec2 pUv = gl_PointCoord;
    pUv.y = 1. - pUv.y;
    pUv.x = (pUv.x - 0.5) / 0.7 + 0.5;
    if ( pUv.x > 1.0 || pUv.x < 0.0 )
          discard;
    
    vec2 uv = vUv + vSize * pUv;
    vec4 texColor = texture2D( texture, uv );
    outgoingLight *= texColor.xyz;
    gl_FragColor = vec4( outgoingLight, texColor.a * diffuseColor.a );