## XNA 4.0 Shader Programming #6–Simple Ocean

Welcome back to my tutorial. Today, we are not going to learn anything new (almost), but instead put together a scene that uses some different shaders in order to see how powerful shaders can be.

The island

The island is a 3D model created by a friend of mine, Espen Nordahl. The island use a normal map and the same shader covered in tutorial 4, to make the model look more detailed.

The ocean

The ocean is a plane built up by many vertexes. We use the technique described in tutorial 5 (Deform shader) to create the ocean waves, and using normal map from tutorial 4 to make tinier waves on top of this. I used one normal maps, but sampling in in two different locations and moving each in different directions to make small detail waves ripple on the waves:

Normal = (Normal + Normal2)/2;

Here I take the two normals, adding them together and using the avg. of these normals when calculating lighting, diffuse and specular( Tutorial 3 ).

I also move the texture coordinates on the color map, making it look like there is some stream in the water.

Shouldn’t be anything new. The ocean is very large so I started the shader by multiplying the texture-coordinate with 20, making the texture repeat 20 times in both the X and Y direction. I then sample the color for the given pixel.

Next I move the texture-coordinate a bit before sampling a normal, and store it in normalMap. I do the same again after sampling in the other direction and store it in normalMap2.

Then I take the average normal and use that as the normal when calculating the rest of the lighting.

I also hacked a bit with the specular-calculations so it will be visible on small waves.

Remember, this is a quick and dirty way to create ocean. It’s quite cheap and easy to implement and looks OK when water is not in focus. In a later tutorial I will show how you can create a much better, but a lot more expensive water/ocean shader.

Let’s look at the code..

```// The Pixel Shader
{
input.TexCoord.x = input.TexCoord.x*20.0f + sin(TotalTime*3+10)/256;
input.TexCoord.y = input.TexCoord.y*20.0f;

float4 color = tex2D(ColorMapSampler, input.TexCoord);

input.TexCoord.y += (sin(TotalTime*3+10)/256)+(TotalTime/16);
float3 normalMap = 2.0 *(tex2D(NormalMapSampler, input.TexCoord)) - 1.0;

input.TexCoord.y -= ((sin(TotalTime*3+10)/256)+(TotalTime/16))*2;
float3 normalMap2 =(2 * (tex2D(NormalMapSampler, input.TexCoord))) - 1.0;

normalMap = (normalMap + normalMap2) / 2;

normalMap = normalize(mul(normalMap, input.WorldToTangentSpace));
float4 normal = float4(normalMap,1.0);

float4 diffuse = saturate(dot(-LightDirection,normal));
float4 reflect = normalize(2*diffuse*normal-float4(LightDirection,1.0));
float4 specular = pow(saturate(dot(reflect,input.View)),28);

float4 finalColor =  color * AmbientIntensity +
color * DiffuseIntensity * diffuse +
specular*250;

finalColor.a = 0.3f;
return finalColor;
}

```

This entry was posted in Tutorial, XNA, XNA Shader Tutorial. Bookmark the permalink.

### 5 Responses to XNA 4.0 Shader Programming #6–Simple Ocean

1. gamanf says:
2. jane says:
3. emsleyan says:

nice example 😀

4. Looks like from an old game, but still cool!

This site uses Akismet to reduce spam. Learn how your comment data is processed.