# Specular highlights on water

This topic is 2593 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,
I am using animated normalmaps and usual specular calculation result looks not that good,
Is there a way to make specular highlights on water look better and natural?

Thanks

##### Share on other sites

I take it you already tried doing it the "right" way, so if you're interested in other approaches...

Super Mario Sunshine's Water Effect
Super Mario Sunshine uses strongly-colored ocean floors and a waving water mesh with a special noise texture. This texture is used in combination with a shader calculation to define where the shines on this water mesh will happen. An analytical view of this texture:

Notice it is mip-mapped, which means that under distance it will look different based on which pair of stages are being interpolated. The second stage is the brightest, so areas at a medium distance will be stronger than closer or really far away ones. Also note that the texture itself is completely blank, so there's no way the water will shine near the camera; only where the mip levels are used.
Anyway, SMS uses a single instance of that texture tiled over the entire water mesh (just one texture unit), but this texture is sampled twice, with two different UV values; these UV values should be scrolled in different directions and at different speeds in your game code, so that when they sample the same texture they can be added together and give an entirely unique, composited value. The water mesh also performs a waving animation with its vertices.
The shader then compares this unique color value (you can use any of the RGB channels, since the texture is grayscale) against a constant threshold\cutoff value - if the composited value is whiter\stronger than the cutoff value, it's discarded or rendered as transparent. Optionally, you can also set a lower cutoff value as the code below exemplifies:

float4 PS(
float4 Diff : COLOR0,
float4 Spec : COLOR1,
float4 Vert : TEXCOORD0,
float2 Tex1 : TEXCOORD1,
float2 Tex2 : TEXCOORD2 ) : COLOR
{
float4 waterTex0 = tex2D(baseSampler,Tex1); // The same texture, sampled twice to simulate...
float4 waterTex1 = tex2D(baseSampler,Tex2); // ...two scrolling textures without using 2 texture units.

float water = ((waterTex0.r + waterTex1.r) * Vert.r); // Composited value from the two samples.

if((water >= cutoff_bottom && water <= cutoff_top))

return float4(water,water,water,1.0f);
}

The resulting fragment will be blended with the ocean floor, thus acquiring that water-like color while giving the impression of a shine. If it fails the cutoff values, you just get the ocean floor's color. You can see this in that screenshot at the top of the post. The water mesh doesn't cover all of the visible ocean, just an area around the player - most likely to increase the performance of this effect on the GameCube. You can shape this technique to achieve whatever result you want: adding different parameters, using a 1D texture instead of that "IF" shader instruction (might be faster) etc.

I wouldn't know all this if it weren't for the ingeniousness of Arthur Carvalho (nicked "Yoasakura") of the Dolphin-Emulator forums, so big thanks to him.

Bye.

Edited by Kryzon

##### Share on other sites
thanks for sharing this

##### Share on other sites
I am using animated normalmaps and usual specular calculation result looks not that good,
Is there a way to make specular highlights on water look better and natural?
That depends on what is not good-looking about it... Can you post a picture?

If the problem is specular aliasing, then mipmapping your normal maps with a toksvig factor, or using LEAN mapping, will help.

##### Share on other sites
I am just trying to create sparkles, little specular highlights on water surface, what I am having looks more like a flat disc with little distortion.
I am using fresnel term to blend refraction and reflection maps, should I use this for specular heighlights too?

##### Share on other sites
I second Hodgman's question - please post a picture. It'll be loads easier to tell what's wrong.

##### Share on other sites
Hi Hiyar, I can see now what needs improvement. You said you wanted more noise, that it's looking "flat" the way it is. What you're missing right now is one major coloring factor: the lighting. All the noise you need is stored in those animated normal-maps; you just need something to compare them with.

There is a quick and easy way to implement something in this style. I'd like you to do the following:

• Define the sun's vector. This is a constant Float3 value, with a negative Y axis since it's pointing down. Prefer a vector that points in the same direction as the sun in your environment.

• Choose a deep-water color. This is a constant Float4 value. I suggest something in the lines of RGBA (0.0, 0.23, 0.31, 1.0).

• Compute the Dot product of the sun's vector with the current fragment's normal (taken from the animated normal-map), but transfer the result to the '1.0 ~ 0.0' range:
 float lighting = (dot(sunVector, normalSample.rgb) + 1.0) * 0.5 // Transfer the dot result from '1.0 ~ -1.0' to the '1.0 ~ 0.0' range. 
• Add a small offset to the lighting factor so the water doesn't perfectly reflect the environment - so it doesn't look like a flawless mirror:
 lighting = max(lighting - 0.1, 0.0) 
• Use that computed lighting factor to Lerp between 'deep-water color' and 'reflection map':
 return lerp(deepWaterColor, reflectionSample, lighting) 
• Consider that Lerp as your final fragment color.

This doesn't represent what goes on in reality, but it's a good substitute. If this doesn't look good I'll suggest you another method.
If you can, please post a picture of above in action so we can see if it's working.

##### Share on other sites
I am not sure if I understand you correctly.
What exactly do you mean by deepwater color? I am using height based fog for underwater and I am using refraction map too.
You can not see this in the picture maybe
See this

for the lerp blending I am using fresnel term.
I think I am just going to experiment with different normal maps, should I use fresnel for this additional specular highlights too?

1. 1
2. 2
Rutin
19
3. 3
khawk
15
4. 4
5. 5
A4L
13

• 13
• 26
• 10
• 11
• 44
• ### Forum Statistics

• Total Topics
633744
• Total Posts
3013654
×