Sign in to follow this  
WiredCat

Phong reflection on a water surface.

Recommended Posts

I try to implement a reflection on a water waves so  (something similar to the reflection of the sun on the water surface)

 

now i get this what is below:

 

(top left, bottom right)

 

 

bottom left shows another shader (lighting shader - which shows normal direction) - so i assume somewhat normals are calculated properly

 

top right the mesh with all normals set to 0, 1, 0 (as in a mirror) and the result 

 

now top left and bottom right is actually that top right one but with normals calculated that way showed in bottom left image

 

maybe the thing is because i way too much stretch the mesh (64x64 grid is stretched to 512x512) - ah red thing indicates light position

 

arti1.jpg

 

 

any suggestions how can i fix that>?

 

 

basically i aim for this:

 

 

oce.png

 

 

 

NOTE i jus scaled the heightmap gemoetry when i was calculating nromals and it looks now like:

 

 

 

mayb.png

shader somewhat looks like this


float PhongReflection(vec3 DirFromVertToLight, vec3 surfnormal, vec3 PerfectlyReflectedDir, vec3 DirVertexCam)
{
return 0.5*dot(DirFromVertToLight,surfnormal) + 0.8*dot(PerfectlyReflectedDir,DirVertexCam);
}


gl_FragColor = vec4(reflection_color,1.0)*PhongReflection(dfvtl, u_normalMap, Reflect(-dfvtl, vertex_normal), dvc);



Edited by WiredCat

Share this post


Link to post
Share on other sites


shader somewhat looks like this


float PhongReflection(vec3 DirFromVertToLight, vec3 surfnormal, vec3 PerfectlyReflectedDir, vec3 DirVertexCam)
{
return 0.5*dot(DirFromVertToLight,surfnormal) + 0.8*dot(PerfectlyReflectedDir,DirVertexCam);
}


gl_FragColor = vec4(reflection_color,1.0)*PhongReflection(dfvtl, u_normalMap, Reflect(-dfvtl, vertex_normal), dvc);

 

I'm assuming the 0.5 and 0.8 are intensity tweaks?

 

One thing that comes to mind is that you're not clamping your dot products to 0-1 range. That means your specular result will be removing from your diffuse light whenever the dot product is negative. Same goes for diffuse.

 

Also the phong result should also be multiplied by the lambertian term for correctness, and taken to a power for glossiness.

 

It should look more like this (I've added your 0.5 and 0.8 to this, but I'm not sure you need or even want those):

float PhongReflection(vec3 DirFromVertToLight, vec3 surfnormal, vec3 PerfectlyReflectedDir, vec3 DirVertexCam)
{
float nDotL = clamp(dot(DirFromVertToLight,surfnormal), 0.0, 1.0);
float rDotV = clamp(dot(PerfectlyReflectedDir,DirVertexCam), 0.0, 1.0);
return 0.5*nDotL + (0.8 * nDotL * pow(rDotV, 32.0));
}

The 32 is the "glossiness". Higher = sharper highlights. Currently you're just using 1 which gives you a super spread out highlight.

 

Also, what is "reflection_color"? If all you want is the reflection highlight and not direct/diffuse lighting, then you don't need to add "0.5*nDotL" to that last line at all.

Edited by Styves

Share this post


Link to post
Share on other sites
Phong shading produces perfectly round highlights. You probably want to use Blinn-Phong shading, which correctly stretches highlights on rough surfaces at glancing angles (producing the characteristic streaky reflections seen on water or wet roads).

Share this post


Link to post
Share on other sites

Also the phong result should also be multiplied by the lambertian term for correctness, and taken to a power for glossiness.
It should look more like this (I've added your 0.5 and 0.8 to this, but I'm not sure you need or even want those): 



float PhongReflection(vec3 DirFromVertToLight, vec3 surfnormal, vec3 PerfectlyReflectedDir, vec3 DirVertexCam)
{
float nDotL = clamp(dot(DirFromVertToLight,surfnormal), 0.0, 1.0);
float rDotV = clamp(dot(PerfectlyReflectedDir,DirVertexCam), 0.0, 1.0);
return 0.5*nDotL + (0.8 * nDotL * pow(rDotV, 32.0));
}

 
as long as DirFromVertToLight , surfnormal , PerfectlyReflectedDir and DirVertexCam are normalized (and they should be) the results of dot products are in the range of [-1,1]  so no clamping is needed the code should be :

 
float PhongReflection(vec3 DirFromVertToLight, vec3 surfnormal, vec3 PerfectlyReflectedDir, vec3 DirVertexCam)
{
float nDotL = max(dot(DirFromVertToLight,surfnormal), 0.0);
float rDotV = max(dot(PerfectlyReflectedDir,DirVertexCam), 0.0);
return 0.5*nDotL + (0.8 * nDotL * pow(rDotV, 32.0));
}

and as hodgman said you should use blinn-phong shading:
http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model

 

and also I guess you should give the ratios "0.5" and "0.8" as a material to the shader

Edited by IYP

Share this post


Link to post
Share on other sites

HLSL's saturate(x) or GLSL's clamp(x,0.0,1.0) is usually implemented as a free instruction modifier, whereas max(x,0.0) is an independent instruction.
e.g.
c=clamp(a+b,0,1)
will compile into
add_sat c a b
But
c=max(a+b, 0)
will compile into
add c a b
max c c 0


So even though it seems more complex than is required here, it's probably actually simpler after the compiler is done with the code smile.png

Share this post


Link to post
Share on other sites

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

Sign in to follow this