[C++] Reflective Water (conversion from .NET)

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

Spintz wrote:I've been working on a new water scene node for IrrSpintz. I like the screenshots for this. I'm gonna try to get it working with SVN Irrlicht and if I can, I can fix the DX HLSL shaders.
Hi Spintz. I synced with SVN today and the event callback was broken, but I posted a fix for that earlier.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

I noticed a "node leak" during a debug build (trying to track that pesky DX9 error down!).

There's a

Code: Select all

plane->drop();
missing after

Code: Select all

parallaxplane->setMaterialType((E_MATERIAL_TYPE)parallax);
Of course, .NET's gc catches this stuff... :wink:
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

sio2 wrote:
Spintz wrote:I've been working on a new water scene node for IrrSpintz. I like the screenshots for this. I'm gonna try to get it working with SVN Irrlicht and if I can, I can fix the DX HLSL shaders.
Hi Spintz. I synced with SVN today and the event callback was broken, but I posted a fix for that earlier.
Yeah, I don't get that. It's much better to have the events passed as const references, don't know why they changed back to the old way.
Image
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

:cry:
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

hybrid wrote::cry:
Stop it, please...that's just too much technical information for my brain to comprehend. :lol: :lol: :lol: :lol: :lol:
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

Maybe I should point out that the DX9 issues are with the demo in *this* snippet. The demo I posted in the other "reflected water" snippet seems to work just fine in DX9 (it is the vanilla PerPixelLighting demo but with a layer of reflective water).

The issue with this demo is that it was originally targeted for OpenGL and not really finished for DX9 use (as it uses GLSL shaders).
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

:cry: : (I just expressed my sadness about the loss of constness)
belfegor
Posts: 383
Joined: Mon Sep 18, 2006 7:22 pm
Location: Serbia

Post by belfegor »

Hey sio2 nice effect with water shader i tried your "PerPixelLighting demo"
it looks great.Iv like to make sugestion if i may:
could you(or whoever wrote this shader) make water transparent +
make turbulance look like seen in HL2 water(in there there is
turbulent underwater view + reflected view).

edit: just to mention when i am not in full screen i get errors in console and water is full of strange artifacts.but in full screen its ok.I use DX9(HLSL).
Small FPS demo made using Irrlicht&NewtonDEMO
InfoHERE
Its at very early stage but i think im crazy enough to finish it all alone.
DeusXL
Posts: 114
Joined: Sun Mar 14, 2004 9:37 am
Contact:

Post by DeusXL »

Water is transparent (change the variable called "RefractionFactor" from 0.51, mostly transparent to 1, not transparent).
Turbulent water would be great but would need a lot of stuff like dudv maps and things like that. I wanted the water to work with nothing else but I'm sure that, by modifying values, you can have a nice effect ;)
Irrlicht .NET complete and Cross Platform Wrapper
The kid on my avatar wrote:A painless lesson is one without any meaning
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Ok, I fixed the HLSL code ( and also small enahancement to the GLSL code ).

HLSL -

Code: Select all

uniform float Time;
float4x4 mWorldViewProj;
float WaveHeight;
float WaveLength;
float WaveSpeed;
float4 AddedColor;
float4 MultiColor;
float UnderWater;
float WaveDisplacement;
float WaveRepetition;
float RefractionFactor;

struct VS_OUTPUT
{
    float4 Position : POSITION;
    float4 TexCoord : TEXCOORD0;
    float  Addition : TEXCOORD1;
};

VS_OUTPUT vertexMain( float4 vPosition : POSITION,
                      float2 texCoord : TEXCOORD0 )
{
    VS_OUTPUT Output;
    Output.Position = mul( vPosition, mWorldViewProj );
	Output.Addition = ( sin( ( vPosition.x / WaveLength ) + ( Time * WaveSpeed / 10000.0 ) ) ) +
					  ( cos( ( vPosition.z / WaveLength ) + ( Time * WaveSpeed / 10000.0 ) ) );
	Output.TexCoord = Output.Position;
	Output.TexCoord.y += Output.Addition * WaveHeight;
    return Output;
}

struct PS_OUTPUT
{
    float4 RGBColor : COLOR0;
};

texture ReflectionTexture;
sampler MySampler = sampler_state
{
    Texture = ReflectionTexture;
    AddressU = CLAMP;
    AddressV = CLAMP;
};

PS_OUTPUT pixelMain( VS_OUTPUT In )
{
	PS_OUTPUT Output;
	
	float4 projCoord = In.TexCoord / In.TexCoord.w;
	projCoord += float4( 1.0, 1.0, 1.0, 1.0 );
	projCoord *= 0.5;
	projCoord.x += sin( In.Addition * WaveRepetition ) * ( WaveDisplacement / 1000.0 );
	projCoord.y += cos( In.Addition * WaveRepetition ) * ( WaveDisplacement / 1000.0 );
	projCoord = clamp( projCoord, 0.001, 0.999 );

	if( UnderWater == 1.0 )
		projCoord.y = 1.0 - projCoord.y;

	float4 refTex = tex2D( MySampler, projCoord );
	refTex = (refTex + AddedColor) * MultiColor;
	Output.RGBColor = refTex;

	if( UnderWater == 1.0 )
		Output.RGBColor *= (MultiColor / 1.1);

	Output.RGBColor.a = RefractionFactor;
	return Output;
}

GLSL Vert -

Code: Select all

uniform float Time;
uniform float WaveHeight;
uniform float WaveLength;
uniform float WaveSpeed;
varying float addition;

void main()
{
	gl_Position = ftransform();
	gl_TexCoord[0] = gl_Position;
	addition = ( sin( ( gl_Vertex.x / WaveLength ) + ( Time * WaveSpeed / 10000.0 ) ) ) +
			   ( cos( ( gl_Vertex.z / WaveLength ) + ( Time * WaveSpeed / 10000.0 ) ) );
	gl_TexCoord[0].y += addition * WaveHeight;
}
GLSL Frag -

Code: Select all

uniform sampler2D ReflectionTexture;
uniform vec4 AddedColor;
uniform vec4 MultiColor;
uniform float UnderWater;
uniform float WaveDisplacement;
uniform float WaveRepetition;
uniform float RefractionFactor;
varying float addition;

void main()
{
	vec4 projCoord = gl_TexCoord[0] / gl_TexCoord[0].w;
	projCoord += vec4( 1.0 );
	projCoord *= 0.5;
	projCoord.x += sin( addition * WaveRepetition ) * ( WaveDisplacement / 1000.0 );
	projCoord.y += cos( addition * WaveRepetition ) * ( WaveDisplacement / 1000.0 );
	projCoord = clamp( projCoord, 0.001, 0.999 );

	if( UnderWater == 0.0 )
		projCoord.y = 1.0 - projCoord.y;

	vec4 refTex = texture2D( ReflectionTexture, vec2( projCoord ) );
	refTex = (refTex + AddedColor) * MultiColor;
	gl_FragColor = refTex;

	if( UnderWater == 1.0 )
		gl_FragColor *= ( MultiColor / 1.1 );

	gl_FragColor.a = RefractionFactor;
}
So now, DX works exactly like OpenGL. There is still 1 problem though, with both DX and OpenGL. If you are very close to the water height, the reflections get really screwed up. I'll try to get a video of this, will explain it best.
Image
DeusXL
Posts: 114
Joined: Sun Mar 14, 2004 9:37 am
Contact:

Post by DeusXL »

The bug you are talking about (the reflection that gets really bad when you're near the water) is only appearing in the DirectX shader with my version. OpenGL is working perfectly.
I'd bet the problem is due to a bad position in vertex/pixel shaders. Let me explain :
I translated the clamp shader from GLSL to HLSL and with HLSL, it makes edge disappear whereas with GLSL, it makes pixel disappear... Of course, the OpenGL render is a lot better.
Here's the DirectX clamp shader image :
http://deusxl.free.fr/water/screendx.jpg
And the OpenGL :
http://deusxl.free.fr/water/screengl.jpg
Irrlicht .NET complete and Cross Platform Wrapper
The kid on my avatar wrote:A painless lesson is one without any meaning
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

That's not the same bug. I'll get a video of it up so you can see whats happening, and it happens in both OpenGL and DX
Image
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Maybe the DX bug(clamp shader cutting polys) is due to using vertex colours rather than texcoords for passing the height data to the pixel shader(clamp), maybe interpolation in dx on the texcoords is btter than vertex colours.

This shader would look pretty cool if you add parallax to it, have a height map of some waves deform that slightly using the trig functions on time.

add up the RGB of the deformed height map into one float, this will give the height, now use a simple parllax equation to shift the reflection and give a 3d look to the waves

reflection tex coord=height * eye + oldTexCoord

eye is the eye vector to the vertex, this is interpolated per fragment when it reaches the pixel shader
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

The new HLSL shader I posted does use TexCoords for passing values from the vertex shader to the pixel shader, not the diffuse anymore. That wasn't the problem, if you compare the old to the new, you'll notice in the HLSL that the projCoord is calculated per pixel rather than per vertex, which I think helps to fix the old problem.

I'll see tonight if I can get a video up of the other problem I'm having....
Image
belfegor
Posts: 383
Joined: Mon Sep 18, 2006 7:22 pm
Location: Serbia

Post by belfegor »

my knowlege of shaders is not good but
i know what spinz is talking about(i dont have a screenshot). In DX(didnt try OPENGL) when my camera is close to the water at the edges of the screen shows up a artifatcs like streched textures(cant explain correctly).
Also i noticed same artifact on this water shader (whitch i found on the net
and modified long time ago).

float4x4 matWorldViewProj;
float4 matWorld;
float4 vecViewPos;
float variab;

struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
float3 eyeLinear: TEXCOORD1;
float4 fresnel: COLOR0;
};

VS_OUTPUT vertexMain(float4 Pos: POSITION)
{
VS_OUTPUT Out;
float4 pos = float4(1 * Pos.x, 1 * Pos.y - 1, 1 * Pos.z, 1);
float4 pPos = mul(float4(pos.xyz,1), matWorldViewProj);
Out.Pos = pPos;
Out.texCoord.x = Pos.x * 0.5;
Out.texCoord.y = Pos.z * 0.5;
Out.eyeLinear.x = 0.5 * (pPos.z + pPos.x);
Out.eyeLinear.y = 0.5 * (pPos.z - pPos.y);
Out.eyeLinear.z = pPos.z * 1;
float3 PositionWorld = mul(Pos, matWorld);
float dist=distance(PositionWorld, vecViewPos);

if (dist <= 300)
{
Out.fresnel.xyzw = dist * 0.005;
}

if (dist>300)
{
Out.fresnel.xyzw = 1.0;
}
return Out;
}
float time;
float wave_speed;
sampler noise_map;
sampler reflection_map;

float4 pixelMain( float2 texCoord: TEXCOORD0,float3 eyeLinear: TEXCOORD1, float4 fresnel: COLOR0) : COLOR
{
float2 waterCoord = texCoord.xy * 0.001 * variab;
waterCoord.x += wave_speed * time;
float4 bump = tex2D(noise_map, waterCoord) * 2 - 1;
bump = normalize(bump);
float2 mid = eyeLinear.xy / eyeLinear.z + bump.xy * 0.1f;
float4 reflection = tex2D(reflection_map, mid);
float4 final = reflection;
float3 watercolor = (0.82,0.93,0.92);
final.rgb *= watercolor;
final.w = (1 * fresnel) * 0.93;
return final;
}


sorry for jumping in.
Small FPS demo made using Irrlicht&NewtonDEMO
InfoHERE
Its at very early stage but i think im crazy enough to finish it all alone.
Post Reply