Per-Pixel Displacement
Category: Shaders
Author: Jonathan Kreuzer
Publish Date: July 30, 2006
Description :
- Uses a height map to displace the texture UVs in the pixel shader so a single polygon can look 3D by varying rendering with view angle.
- This shader accounts for occlusion when calculating the texture coordinate, by using ray casting in discrete steps.
- After the ray hits, it then adjusts the UV using percent between Height and Last Height to avoid seeing the slices.
-
Another possible method for avoiding slices after the ray hits is binary search. I decided against this because it's slower and I didn't notice a quality improvement.
It's still present but commented out, so you can switch back if you want to.
Screenshot
Files:
- Frag/displacement.cg
- Vert/displacement.cg
Fallback Chain :
- Displacement -> Parallax -> Normal Mapped -> Smooth( fixed-function )
Fallback Reasons:
- Not supported by graphics card
- Displacement render option is off
- if LOD is on, and viewer distance to the rendered chunk is > LOD distance
Inputs:
- Diffuse Map
- Height Map (1-channel)
- Normal Map (Tangent-Space)
Diffuse Map, Height Map, Normal Map (1024x1024 diplayed at 256x256)
Specular intensity map is taken from the Normal Map alpha channel.
An optional Overlay Map is supported, but only for the Diffuse Map.
Height Map Creation:
- Viewed as a gray-scale map, full white is the highest height, black the lowest. Dark colors "dig" into the texture.
- Make sure you use the full range of values. This results in a higher quality occlusion, since the ray casting steps across the full range.
- Use the Displacement Amount uniform input in the material editor to adjust the height of the displacement.
- Remember this map controls actual height, so unlike height maps used only for tangent space normal map creation, you need to make sure the heights are reasonable and avoid high frequency noise. Sometimes blurring or smoothing the map will help.
Limitations:
- Not for huge displacements. For those I recommend actual geometry =)
- Since fixed steps are used for occlusion, high displacements will cause noticeable slices where the ray misses. You can increase the quality of the displacement shader at the expense of speed.
- Significantly slower than simple normal/bump mapped shaders, although it can run at a good speed on recent graphics cards.
- In actual gameplay may be sometimes hard to notice. You don't need it on everything.
- Since the Diffuse Map is 2D, if you have very steep sides on the height map you may notice texture stretching.
3D Textures are not supported. They could be used to store a distance map, or to avoid the texture stretching problem with the diffuse map.
I chose to avoid them because of their size -- in a full game texture memory quickly becomes an issue.
Source:
This is the Cg source for the displacement shader for anyone interested. They will need to be changed to work outside CW3D but this might give readers a better idea of the inner workings.
Note : these contain macros that are replaced by code to compile variations of the shader.
3D Kingdoms Creator Documentation © 2006