Jump to content

Water reflection shader going wrong


Einheit-101

Recommended Posts

Hi all, i am currently working on new water reflections (Because there is no good water shader with water reflections) and i am facing numerous problems.

One of the major problems is the fact that the reflection is always lagging 1 frame behind the actual image. Is it possible to fix that?

Link to comment

If you are not using scene reader in the Render Target from the shader, then in the “dxUpdateScreenSource” there is a resampleNow parameter. Which captures an image from a previous frame or current.
P.S. I would like to see the code in the future

Edited by XaskeL
Link to comment

This is part of my shader that is responsible for the reflection. I update the reflectionTexture as screenSource each "onHUDRender" because otherwise you have the User interface in the reflection image.

...

sampler2D envMapSampler = sampler_state
{
    Texture = <reflectionTexture>;
    AddressU = Mirror;
    AddressV = Mirror;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
};

...

// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType WaterVertexShader(VertexInputType input)
{
    PixelInputType output;
    matrix projection;

    // Create the view projection world matrix for reflection.
    projection = mul(gWorldViewProjection, gWorld);
    projection = mul(gWorld, projection);

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = MTACalcScreenPosition(input.position);
    output.worldPosition = MTACalcWorldPosition(input.position);
    output.lightDirection = normalize(gCameraPosition - sunPos);
    output.worldNormal = MTACalcWorldNormal(input.normal);

    // Store the texture coordinates for the pixel shader.
    output.textureCoords = input.textureCoords;

    // Calculate the input position against the projection matrix.
    output.refractionPosition = mul(input.position, projection);


    // compute the eye vector
    float4 vertexPosition = mul(input.position, gWorld);
    float4 eyeVector = vertexPosition - gViewInverse[3];
    output.skyTextureCoordinate = mul(eulRotate(skyRotate), eyeVector.xyz);

    float4 vPos = mul(vertexPosition, gView);   
    float4 pPos = mul(vPos, gProjection);

// I think here is a mistake, this should calculate the reflection positions
    output.reflectionPosition.x = 0.5 * (pPos.w + pPos.x);
    output.reflectionPosition.y = 0.5 * (pPos.w - pPos.y);
    output.reflectionPosition.z = pPos.w;

    output.Depth = output.position.z;
    output.vposition = mul(input.position, gWorldViewProjection);

    return output;
}

...

// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 WaterPixelShader(PixelInputType input) : COLOR0
{
// useless stuff going on....
// only reflection stuff now
    reflectTexCoord = float2(input.reflectionPosition.xy / input.reflectionPosition.z);

//flip the image to get a reflection (maybe here is the error? But how to flip otherwise?)
    reflectTexCoord.y = 1 - reflectTexCoord.y;

    reflectionColor = tex2D(envMapSampler, reflectTexCoord) * reflectionStrength;

.......
Link to comment
1 hour ago, Einheit-101 said:

Я понял, что просто перевернуть изображение с ног на голову с 


это неправильная попытка, отражение пространства экрана должно быть сделано по-другому ... <font style=?">

refleTexCoord.y = 1 - refleTexCoord.y;
refleTexCoord.y += gCameraDirection.z;

Link to comment

Into the SSLR account in Ren712 shaders (just from this Russian article). I myself am interested in the study of shaders, but I do not know much about mathematics.
Look on file: image4D_mir.fx
https://community.multitheftauto.com/index.php?p=resources&s=details&id=12052

1 hour ago, Einheit-101 said:

Now i see, what i actually want is this:

https://habr.com/ru/post/244367/

remi-genin.fr/blog/screen-space-plane-indexed-reflection-in-ghost-recon-wildlands/

And it seems to be quite complex to achieve....... It has nothing to do with that lame attempt that i am using currently. 

 

Edited by XaskeL
Link to comment

The problem with this is that Ren712 is using a shader that gets drawn on the screen with dxDrawImage but my water shader is applied to a texture. Applying his image4D_mir to a texture results in nothing, there is obviously something that needs to be changed in order to make it work with a regular texture. And i have no idea what that could be.

Link to comment
4 hours ago, Einheit-101 said:

The problem with this is that Ren712 is using a shader that gets drawn on the screen with dxDrawImage but my water shader is applied to a texture. Applying his image4D_mir to a texture results in nothing, there is obviously something that needs to be changed in order to make it work with a regular texture. And i have no idea what that could be.

You do not need to use its shader.  There is a calculation of Screen Space Reflection for flat surfaces (in fact, the code from that article is not very good and, not from a good life, people write their algorithms for their goals and objectives. In the end, you will always come across Information Lost, because  SSR is not a replacement, it is an addition.Even the author of the article has problems with the reflection itself, although I liked the result of the work of reflections on the water in your video (this is used on some meta projects and just the image is cropped a little when the player starts to raise the camera). although I myself have the problem of implementing the correct SSR on machines and I have ideas for calculations, but have not tried it yet.

Edited by XaskeL
Link to comment
  • 1 month later...

i use dxDrawImage due to the rendering order (world textures are drawn before screen source is updated). That's why applying it to world texture will always result in 1 frame lag. It's not that noticeable on vehicles but on bigger surfaces it is. I don't need to apply changed matrices to vertex shader, everything that's needed can be passed to pixel shader directly (look into water_refract from community) or recreated from scene depth. As for the method mentioned in the article - it produces nice results:sslr.jpg

  • Like 1
Link to comment
14 hours ago, Ren_712 said:

i use dxDrawImage due to the rendering order (world textures are drawn before screen source is updated). That's why applying it to world texture will always result in 1 frame lag. It's not that noticeable on vehicles but on bigger surfaces it is. I don't need to apply changed matrices to vertex shader, everything that's needed can be passed to pixel shader directly (look into water_refract from community) or recreated from scene depth. As for the method mentioned in the article - it produces nice results:sslr.jpg

The problem with dxDraw effects is that smoke and all other effects are drawn after dxDraw functions. When using, for example, a refract shader, you will always see the effects behind the dxDraw shader. That is especially annoying when players throw smoke grenades and you can clearly see the smoke being "refracted" when water is anywhere behind. Thats why i live with that 1-frame lag and apply all shaders directly to textures, if possible. 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...