[Solved] Help converting a GLSL shader Topic is solved

Problems building or running the engine, queries about how to use features etc.
User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 156

Re: [13.5.3] Help converting a GLSL shader

Post by sercero »

Perhaps you have already seen it, but it might be helpful to know also the theory behind the shader and water rendering in general.

I have been looking at this tutorials from ThinMatrix which is a very good YouTube channel.
https://www.youtube.com/watch?v=HusvGeE ... qhnalNTNZh

I'm also struggling with water rendering, another thing you can take a look is at OgreWater from lingfors.
viewtopic.php?t=63077&hilit=ogrewater

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Help converting a GLSL shader

Post by tritonas00 »

sercero wrote: Sun Jan 15, 2023 1:36 am

I'm also struggling with water rendering, another thing you can take a look is at OgreWater from lingfors.
viewtopic.php?t=63077&hilit=ogrewater

The sources for that are here https://bitbucket-archive.softwareherit ... tachments/, though its HLSL only so i can't test on linux without converting first.

It would be great if we had a sample with it.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Help converting a GLSL shader

Post by tritonas00 »

One last tryout in the Fresnel sample. Reflection/Refraction work now and also fix the positioning thing. Still not the expected results.
Shader code is now almost 1:1. Only thing is missing is depth sampler, not sure if that will change much though :?

Last edited by tritonas00 on Sun Jan 22, 2023 10:08 pm, edited 1 time in total.
tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Help converting a GLSL shader

Post by tritonas00 »

Noticed that blender does this

Code: Select all

#texture background color
bgR = 0.1
bgG = 0.2
bgB = 0.8
bgA = 0.0

g.reflection.source.background = [int(bgR*255),int(bgG*255),int(bgB*255),int(bgA*255)]
g.refraction.source.background = [int(bgR*255),int(bgG*255),int(bgB*255),int(bgA*255)]

Is it possible to set the same in Ogre, here https://github.com/OGRECave/ogre/blob/m ... snel.h#L85 or in the material?

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Help converting a GLSL shader

Post by tritonas00 »

Figured it out, finally.

:D

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

Having fun

User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 156

Re: [SOLVED] Help converting a GLSL shader

Post by sercero »

Nice!

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

Thanks lol.

If anyone is interested here is my progress so far https://github.com/tritonas00/rigs-of-r ... mits/water (GLSL only for now, will migrate to OgreUnifiedShader.h)

Last edited by tritonas00 on Sun Feb 05, 2023 1:18 am, edited 1 time in total.
tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

Almost there :)

Image

Image

Image

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

Hi again! I'm trying to fade out using alpha based on projectionCoord.z so the water blends nicely in the scene. I'm doing this in the fragment shader:

Code: Select all

color.a = 1.0 - clamp((projectionCoord.z / 1000.0), 0.0, 1.0);

This works great

Before:
Image
After:
Image

You can see the edge smoothed out.

The issue is that when i zoom out the alpha reduction spreads out to the whole plane and if i zoom out a lot, the whole water comes invisible. Is there anyway to prevent this behavior? Maybe use something else instead of worldviewproj_matrix?

projectionCoord.z is set in the vertex shader:

Code: Select all

attribute vec4 position;

gl_Position = worldViewProjMatrix * position;

// Projective texture coordinates, adjust for mapping
mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0, 
                     0.0, -0.5, 0.0, 0.0,
                     0.0, 0.0, 0.5, 0.0,
                     0.5, 0.5, 0.5, 1.0);

projectionCoord = scalemat * gl_Position;

and worldViewProjMatrix is set in the material:

Code: Select all

param_named_auto worldViewProjMatrix worldviewproj_matrix

Thanks!

Last edited by tritonas00 on Sat Nov 11, 2023 7:39 pm, edited 1 time in total.
rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: [SOLVED] Help converting a GLSL shader

Post by rpgplayerrobin »

I would use the camera position and then alter its Y value to the same Y value of the plane.
Then I would fade using that position compared to the current pixels position.

That is essentially how normal fog also works, but there you have the problem that you are also seeing (that if you go up in the scene, fog will affect the water), but if you alter the Y position to be the same as the water, the fog would be unaffected by you moving up (or down) in the scene.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

rpgplayerrobin wrote: Sat Nov 11, 2023 7:37 pm

I would use the camera position and then alter its Y value to the same Y value of the plane.
Then I would fade using that position compared to the current pixels position.

That is essentially how normal fog also works, but there you have the problem that you are also seeing (that if you go up in the scene, fog will affect the water), but if you alter the Y position to be the same as the water, the fog would be unaffected by you moving up (or down) in the scene.

Thanks for the reply! Not sure if i understand correctly, do you mean something like this?

Code: Select all

vec3 alter_cameraPos = vec3(cameraPos.x, 0.0, cameraPos.z);
float fade_factor = length(alter_cameraPos - projectionCoord.xyz);
fade_factor = clamp(fade_factor / 1000.0, 0.0, 1.0);

color.a = 1.0 - fade_factor;

Got the same results

As long i'm down all good:
Image

But when up far away it affects the whole plane (you can see the terrain below)
Image

rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: [SOLVED] Help converting a GLSL shader

Post by rpgplayerrobin »

I am not sure what "projectionCoord.xyz" is, I was thinking about the actual pixel position instead. I guess you are sending it through from the vertex shader, which in turn gives you an interpolated per-pixel position that you can use instead of "projectionCoord.xyz".
You might also not have to use the camera position actually, since the shader might have the camera centered, which means you can probably use the position only (like my fog shader handles it).
So it would be something like this I guess:

Code: Select all

vec3 alteredPixelPosition = vec3(position.x, 0.0, position.z);
const float alphaStart = 100.0;
const float alphaEnd = 150.0;
// MIGHT NOT BE NEEDED, TRY WITHOUT IT FIRST:
// vec3 alteredCameraPosition = vec3(cameraPos.x, 0.0, cameraPos.z);
float distanceFromCamera = length(alteredPixelPosition); // length(alteredPixelPosition - alteredCameraPosition);
color.a = 1.0 - clamp((alphaEnd - distanceFromCamera) / (alphaEnd - alphaStart), 0.0, 1.0);
tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Help converting a GLSL shader

Post by tritonas00 »

rpgplayerrobin wrote: Sun Nov 12, 2023 3:50 am

I am not sure what "projectionCoord.xyz" is, I was thinking about the actual pixel position instead. I guess you are sending it through from the vertex shader, which in turn gives you an interpolated per-pixel position that you can use instead of "projectionCoord.xyz".
You might also not have to use the camera position actually, since the shader might have the camera centered, which means you can probably use the position only (like my fog shader handles it).
So it would be something like this I guess:

Code: Select all

vec3 alteredPixelPosition = vec3(position.x, 0.0, position.z);
const float alphaStart = 100.0;
const float alphaEnd = 150.0;
// MIGHT NOT BE NEEDED, TRY WITHOUT IT FIRST:
// vec3 alteredCameraPosition = vec3(cameraPos.x, 0.0, cameraPos.z);
float distanceFromCamera = length(alteredPixelPosition); // length(alteredPixelPosition - alteredCameraPosition);
color.a = 1.0 - clamp((alphaEnd - distanceFromCamera) / (alphaEnd - alphaStart), 0.0, 1.0);

Works like a charm, thanks!
Image

in vertex:

Code: Select all

attribute vec4 position;
varying vec4 ppos;

void main()
{
    ...
    ppos = position;
    ...
}

in fragment

Code: Select all

varying vec4 ppos;

void main()
{
    ....
    vec3 alteredPixelPosition = vec3(ppos.x, 0.0, ppos.z);
    const float alphaStart = 1500.0;
    const float alphaEnd = 5000.0;
    float distanceFromCamera = length(alteredPixelPosition);

    if (cameraPos.y > 0.0)
    {
        color.a = clamp((alphaEnd - distanceFromCamera) / (alphaEnd - alphaStart), 0.0, 1.0);
    }
    ....

Btw i converted the shader to HLSL also, so if anyone wants to collaborate/improve it will be great
https://github.com/tritonas00/rigs-of-r ... ts/water-2

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [Solved] Help converting a GLSL shader

Post by tritonas00 »

New challenge! (and probably the last one) :D

So i render a refraction depth texture using PF_DEPTH16 and with that the water now knows when it is inside or outside a terrain. Inside the terrain is more refracted and caustics are rendered, outside the terrain is more ocean style. So far it works:

Image

Depth detection code so far is only:

Code: Select all

float depth = texture2D(depthMap, fragCoord).r;

and i use that value to set the refraction power. Currently its just in or outside the terrain. Is there any way to make a fade in/out effect so the transition will be smooth? Something like this:

Image

right side -> inside terrain
left side -> outside terrain
between -> desired fade effect

Does depth gives values from 0-1?

Thanks!

User avatar
Crystal Hammer
Gnome
Posts: 317
Joined: Sat Jun 23, 2007 5:16 pm
x 77
Contact:

Re: [Solved] Help converting a GLSL shader

Post by Crystal Hammer »

I think it's a matter of clearing that depth texture to high value (deep) first, because it won't render there outside terrain and that value will stay to give deep water.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [Solved] Help converting a GLSL shader

Post by tritonas00 »

Ok some progress. If multiply the depth by some factor and clamp it to 0.0-1.0 i get the desired result. The bigger the factor the more the refraction is limited close to the shore. The issue i noticed though, is the depth texture varies with the camera, the further i move down, it has no effect. Video of the issue:

I project the depth map like this:

in material:

Code: Select all

param_named_auto worldViewProjMatrix worldviewproj_matrix

in vertex:

Code: Select all

attribute vec4 position;
uniform mat4 worldViewProjMatrix;
varying vec4 projectionCoord;

void main()
{
    gl_Position = worldViewProjMatrix * position;

    // Projective texture coordinates, adjust for mapping
    mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0, 
                     0.0, -0.5, 0.0, 0.0,
                     0.0, 0.0, 0.5, 0.0,
                     0.5, 0.5, 0.5, 1.0);

    projectionCoord = scalemat * gl_Position;

}

in fragment:

Code: Select all

uniform sampler2D depthMap;
varying vec4 projectionCoord;

void main()
{
    vec2 fragCoord = projectionCoord.xy / projectionCoord.w;

    float depth = texture2D(depthMap, fragCoord).r;

    float factor = 20.0;

    gl_FragColor = vec4(clamp(depth * factor, 0.0, 1.0));

}

Close:

Image

Far:

Image

Any idea how to prevent this behaviour?

paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: [Solved] Help converting a GLSL shader

Post by paroj »

I am afraid you will need to understand "depth" actually means to get this right. Start here: https://developer.nvidia.com/content/de ... visualized

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [Solved] Help converting a GLSL shader

Post by tritonas00 »

Welp, don't hate me but something like:

Code: Select all

float d = clamp(depth * (projectionCoord.z * debug), 0.0, 1.0);

seem to provide nice results across the board :)

But i will research better.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [Solved] Help converting a GLSL shader

Post by tritonas00 »

Ok it seems i have a hard time doing this: Depth relative to object, instead of the camera. Related issue described here https://stackoverflow.com/questions/263 ... -to-object

So i try:

vertex

Code: Select all

attribute vec4 position;

uniform mat4 worldViewProjMatrix; // in material: param_named_auto worldViewProjMatrix worldviewproj_matrix

varying vec4 projectionCoord;
varying float distToCamera;

void main()
{
    vec4 esVert = gl_ModelViewMatrix * gl_Vertex; // temporary, will replace with uniforms
    distToCamera = -esVert.z;


    gl_Position = worldViewProjMatrix * position;

    // Projective texture coordinates, adjust for mapping
    mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0, 
                     0.0, -0.5, 0.0, 0.0,
                     0.0, 0.0, 0.5, 0.0,
                     0.5, 0.5, 0.5, 1.0);

    projectionCoord = scalemat * gl_Position;
}

fragment

Code: Select all

uniform sampler2D depthMap; // PF_DEPTH16

varying vec4 projectionCoord;
varying float distToCamera;

void main()
{

    vec2 fragCoord = projectionCoord.xy / projectionCoord.w;

    float depth = texture2D(depthMap, fragCoord).r;

    float near = 0.1;
    float far = 1.0;

    float floor = 2.0 * near * far / (far + near - (2.0 * depth - 1.0) * (far - near));
    float dist = 2.0 * near * far / (far + near - (2.0 * (1.0/distToCamera) - 1.0) * (far - near));

    float whyissohard = (floor - dist)*1000.0;

    gl_FragColor = vec4(whyissohard, whyissohard, whyissohard, 1.0);

It seems the distToCamera part is wrong because the depth still varies when i move the camera:

What i do wrong? :( Just want the depth texture to stay stable no matter the camera position

rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: [Solved] Help converting a GLSL shader

Post by rpgplayerrobin »

What exactly are you attempting to do?

Using the depth texture, you should be able to get the current pixels distance from the camera, and you can even get the real world space position from that.
It all depends on what you need exactly.

You might want to try to get a static value of water depth by first getting the depth value, then remaking that into a world space position and then altering the Y value to the water level of your game.
Say that the water level is at 0 Y, then if your current pixels depth shows a position of 100, -10, 100, it means that it is 10 units/meters under the water.
Then you can use that value to alter the alpha or whatever you want to do.

But keep in mind that using screen space with water will never be perfect. I had trouble with this in my game where my water has foam when it is close to surfaces, but if there is a hard edge the depth buffer just cuts the foam off completely at that edge, making it look pretty ugly.
Screen space with water is therefore not perfect at all.

Some games use another camera that is looking straight down at a certain height, which can create perfect foam and perfect water alpha near edges, but that of course requires an entire new z-prepass on top of your normal render and your other normal z-prepass, which is not that great when it comes to performance. But if you only render the terrain in that z-prepass, it should be fine I guess, but I have not done it for my game as water is not a big part of my game, but it would get static depth values since the camera is always at the same height from the water/terrain.
But it would only work where that camera actually rendered, so far away water would not work with it as it would be at/outside the border of the z-prepass texture.

Here is my hlsl code to get a world space position from a depth value, in case you might need it: viewtopic.php?p=544242#p544242

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [Solved] Help converting a GLSL shader

Post by tritonas00 »

@rpgplayerrobin thanks for the reply!

Some games use another camera that is looking straight down at a certain height, which can create perfect foam and perfect water alpha near edges, but that of course requires an entire new z-prepass on top of your normal render and your other normal z-prepass, which is not that great when it comes to performance. But if you only render the terrain in that z-prepass, it should be fine I guess

Welp, i do exactly this actually. I use the refraction texture, a camera a bit lower than the water plane height (0) and render using PF_DEPTH16. The issue i have is that when i move the main camera up/down the depth texture varies as shown in the video, which i really dont want, i want to stay stable no matter the main camera movement. What i noticed is if i render using PF_FLOAT16_R it stays perfectly stable, no matter the main camera movement, but PF_FLOAT16_R isn't actually depth, you must prepare the terrain accordingly. So what i want is to have what PF_DEPTH16 gives me but not relative to the main camera.

So i think is something like depth(purple line) - distance to water plane (green line) and i think i cant get the green one right, based on the code above:

Attachments
kk.png
rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: [Solved] Help converting a GLSL shader

Post by rpgplayerrobin »

Welp, i do exactly this actually.

Probably not.

The issue i have is that when i move the main camera up/down the depth texture varies as shown in the video

In that case you did not understand what I wrote.
If you have a camera at a constant height (lets say +30 in Y compared to where the water level is) with a direction of 0, -1, 0, your depth texture will be constant each frame, regardless of how your own scene camera rotates.

If you do that, you then in the shader need to actually calculate a new matrix to be the same as the other cameras viewpoint, and then sample the depth, which is not that simple either, it would require you to try multiple approaches for hours to get it right.

I would instead attempt my first approach, and not this approach, since my first approach can still use the same system you have now but that you just need to convert the depth into a world position and then measure the depth compared to the water surface level, which should be very easy with the code I supplied.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [Solved] Help converting a GLSL shader

Post by tritonas00 »

rpgplayerrobin wrote: Sat Feb 17, 2024 12:25 pm

you just need to convert the depth into a world position and then measure the depth compared to the water surface level, which should be very easy with the code I supplied.

ok, i will try this approach, but i don't see how this will overcome the original issue, which is my depth texture (a typical refraction cam, placed in fixed position + 0.15 compared to the water level 0, rendering to texture using PF_DEPTH16) varies with the scene camera position, slightly but still varies.

same issue here https://community.khronos.org/t/water-d ... tion/76890, nobody replied sadly

but still im very noob to all this, possibly im talking nonsense :lol:

Post Reply