0

I have applied a noise effect to a texture using this pixel shader.

float2 noisePower;
float noiseFrequency;

float camMoveX;
float camMoveY;

texture noiseTexture;
sampler2D noiseSampler = sampler_state
{
    Texture = <noiseTexture>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

texture water;
sampler2D waterSampler = sampler_state
{
    Texture = <water>;
};


float4 MainPS(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 texCoord : TEXCOORD0) : COLOR
{
    float2 camMove = float2(camMoveX, camMoveY);
    //float4 camMoveTransform = mul(WorldViewProjection, camMove);

    float4 noise = tex2D(noiseSampler, texCoord.xy * noiseFrequency);
    float2 offset = (noisePower * (noise.xy - 0.5f) * 2.0f);

    float4 color = tex2D(waterSampler, texCoord.xy + offset.xy);
    return color;

}

technique oceanRipple
{
    pass P0
    {
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

I am trying to offset the noise by my camera's movement in game.

I'm thinking it would look something like this:

float4 noise = tex2D(noiseSampler, (texCoord.xy - camMove.xy) * noiseFrequency);

So if the camera moves by the vector (1, 0) for one frame (in world space), I would hope to offset where noise is sampled by this amount, so that it samples the same world water position when the camera is moved.

I'm having troubles converting this distance vector to something HLSL can use.

Since HLSL looks at coords as being normalized between 0 and 1, I have tried setting camMoveX and Y like so in XNA:

camDisX = (camMove.X / GameOptions.PrefferedBackBufferWidth) 

and then passing these values to the shader.

Unfortunately, this is not working. How should I go about converting this distance vector to something HLSL can use? Should I be using a vertex shader and the worldViewProj matrix to solve this?

Here is a short clip to demonstrate.

2 Answers 2

0

Instead of using the camera movement distance between frames to calculate an offset, use the camera position instead, which can be extracted from the last column of the transpose of the view matrix, or can be calculated by accumulating the camera movement per frame.

float4 noise = tex2D(noiseSampler, (texCoord.xy + camPos.xy) * noiseFrequency);

Intuitively this makes more sense: If the camera is (a, b) away from some origin point, the textures would need to be sampled at (a, b) away from that origin point as well to appear stationary. This is irrespective of the speed of camera movement.

0

Updating this since I landed on a solution. I ended up with the following:

    camMove.X = ((_cam.Position.X % GameOptions.PrefferedBackBufferWidth) / (GameOptions.PrefferedBackBufferWidth));
    camMove.Y = ((_cam.Position.Y % GameOptions.PrefferedBackBufferHeight) / (GameOptions.PrefferedBackBufferHeight));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.