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
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))
discard;
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.
I am using animated normalmaps and usual specular calculation result looks not that good,That depends on what is not good-looking about it... Can you post a picture?
Is there a way to make specular highlights on water look better and natural?
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.
lighting = max(lighting - 0.1, 0.0)
return lerp(deepWaterColor, reflectionSample, lighting)
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform. You can accept analytics or continue with necessary cookies only. Learn more