Advertisement

[GLSL] Having trouble with a graphical glitch in my shader

Started by October 28, 2018 04:11 AM
1 comment, last by Servant of the Lord 6 years, 3 months ago

I'm making a 2D river, and shifting the texture coordinates of the water based on a low resolution "flow map". Each pixel in the flow map is 24x24 pixels on-screen.

Everything is mostly working fine, but I'm getting a weird distortion where pixels are interpolating between the flow map.
I'm animating the tex coords based on time, and passing in the time via a uniform, from 0.0 to 1.0.

What's weird is that the distortion is non-existent at a time of 0.0, and gets worse and worse until 1.0.

At time = 0.0, no distortions

EjqLOwr.jpg

 

At time = ~0.5, some distortions

1KxdoxJ.jpg

 

At time = ~1.0, lots of distortion

xveMFHv.jpg

 

[YouTube video demonstrating the glitch] 

(Notice it snap back around the 5-second mark of the video - that's when uWaterCycle reaches 0.0 again)

I tried to simplify the shader as much as possible to narrow in on what's going on, but something is eluding me.
I understand the texture won't line up perfectly, since the texture only tiles at the seams, but here it'll be sampling arbitrarily. Regardless, I don't understand why the lines are all streaky and seemingly moving sideways?


uniform float uWaterCycle; //Goes from 0.0 to 1.0, based on time.

void main()
{
    //=======================================================================================

    //...snip irrelevancies...
  
    //=======================================================================================
    
  	//The "flow map", where each pixel represents the water flow of a 24x24 pixel area on-screen.
    vec4 areaWaterCell  = texture2D(Area_WaterCellTexture, fArea_WaterCellCoord);
  
    //Water direction.
    vec2 waterDirection = areaWaterCell.rg;

    //Convert from (0 - 1), to (-1 to 1)
    waterDirection = (((waterDirection) * 2.0) - 1.0);
    //Multiply to increase water flow speed.
    vec2 waterDirectionX10 = (waterDirection * 10.0);

    //Get the primary water texture.
    vec4 waterDiffuseFrag = texture2D(Water_DiffuseTexture, fWater_DiffuseCoord + (waterDirectionX10 * -uWaterCycle)) * Water_Coloration;

    //=======================================================================================

    //...snip irrelevancies...

    //Set this color as the output.
    ColorBufferOutput = waterDiffuseFrag;

    //=======================================================================================
}

 

I fixed the problem by sampling each of the four corners of the cell, and interpolating between them.


    //Sample four different corners of each 24x24 area water cells.
    vec4 waterColorTL = GetWaterColor(fArea_WaterCellCoord + (vec2(-1.0, -1.0) * Area_WaterCellHalfSize), sineWave);
    vec4 waterColorTR = GetWaterColor(fArea_WaterCellCoord + (vec2( 1.0, -1.0) * Area_WaterCellHalfSize), sineWave);
    vec4 waterColorBL = GetWaterColor(fArea_WaterCellCoord + (vec2(-1.0,  1.0) * Area_WaterCellHalfSize), sineWave);
    vec4 waterColorBR = GetWaterColor(fArea_WaterCellCoord + (vec2( 1.0,  1.0) * Area_WaterCellHalfSize), sineWave);

    //Interpolate between the horizontal samples.
    vec4 waterColorTop    = AlphaBlend(waterColorTL, waterColorTR, amountThroughCell2D.x);
    vec4 waterColorBottom = AlphaBlend(waterColorBL, waterColorBR, amountThroughCell2D.x);

    //Interpolate between the vertical samples.
    vec4 waterColor = AlphaBlend(waterColorTop, waterColorBottom, amountThroughCell2D.y);

You can see a video of it working here:

https://twitter.com/JaminGrey/status/1056672921048006657

This topic is closed to new replies.

Advertisement