|Direct3D 9 Parallax Normal Mapping Demo.
This Windows demo implements tangent space parallax normal mapping with offset limiting using a series of Direct3D High Level Shading Language (HLSL) shaders. A single D3DX Effect file (.fx) is provided with three techniques that implements parallax normal mapping for each of the three Direct3D light types: directional, point, and spot lights.
The demo consists of a single cube centered at the world origin. The cube consists of only 6 faces with each face composed of 2 triangles.
Parallax mapping is a method for approximating the correct appearance of uneven surfaces by modifying the texture coordinate for each pixel. Normal mapping is commonly used to provide surfaces with very detailed shading without requiring additional geometry to be added to the polygonal model. However such normal mapped surfaces often still appear flat. Parallax mapping corrects this by providing the illusion of depth to such surfaces. Parallax mapping is commonly used in conjunction with normal mapping because parallax mapping is a relatively inexpensive means to enhance the normal mapping effect.
The original idea for parallax mapping came from a paper by Tomomichi Kaneko et al (2001) titled "Detailed Shape Representation with Parallax Mapping". Later Terry Welsh (2004) introduced an offset limiting term to the original parallax mapping technique in his paper titled "Parallax Mapping with Offset Limiting: A Per Pixel Approximation of Uneven Surfaces".
This demo was built using the June 2010 update of the Microsoft DirectX SDK. The required end-user runtimes can be downloaded here.
To learn more about normal mapping check out the Direct3D 9 Normal Mapping Demo.
1. This demo requires shader model 2.0 or higher support.
2. This demo requires the Visual C++ 2010 Library Runtimes. Download instructions can be found here
Download executable, source, and Visual C++ 2010 solution files.
10 July 2010.
Added missing .vcxproj.filters file to the project.
13 June 2010.
Updated solution to Microsoft Visual Studio 2010.
25 March 2008.
Fixed memory leak in CreateNullTexture() function where 'pSurface' was not being released.
2 February 2008.
Updated solution to Microsoft Visual Studio 2008.
4 January 2008.
parallax_normal_mapping.fx: Added light attenuation comments. Changed vector outputs from the vertex shaders to float3. Fixed bug in vertex shaders where the worldInverseTransposeMatrix was not being cast to a float3x3. Updated the pixel shaders to use the float3 vector outputs from the vertex shaders.
main.cpp: Added mouse wheel support. Renamed the constant MOUSE_ORBIT_SPEED to MOUSE_ROTATE_SPEED. Added the constant MOUSE_WHEEL_DOLLY_SPEED. Removed g_targetPos global variable. Added g_cubePos global variable. Removed UpdateLighting() function. In the ProcessMouseInput() function renamed CameraMode enum to MouseMode. Updated enum constants accordingly. The ProcessMouseInput() function now updates the g_cubePos not the g_cameraPos. The camera is fixed in space now. Only the cube moves. In the RenderText() function changed help text to indicate that the mouse manipulates the cube. Added additional help text for the mouse wheel. In the UpdateEffect() function added a translation transformation to the world matrix calculations.
2 January 2008.
parallax_normal_mapping.fx: Fixed bug where all 4 components of the normal map normal was being normalized instead of just the rgb components. Removed use of the lit() intrinsic function. Removed separate specular support.
main.cpp: Changed the material's shininess.
26 December 2007.
parallax_normal_mapping.fx: Removed attenuation member from the Light structure. Added radius member to the Light structure. Replaced existing light attenuation model with a simpler one based on a light radius using the formula: attenuation factor = 1 - ((distance * distance) / (radius * radius)). Fixed a bug in the directional lighting vertex shader where the half angle vector was being incorrectly calculated.
main.cpp: Added DOLLY_MIN and DOLLY_MAX constants. Removed the Light structure's attenuation member. Replaced with with a light radius member. Improved the font rendering by supporting ClearType quality when available. Renamed DrawFrame(), DrawCube(), and DrawText() to RenderFrame(), RenderCube(), and RenderText().
5 November 2007.
This is a major rewrite of the Direct3D 9 HLSL Parallax Bump Mapping demo. This demo has now been renamed Direct3D 9 Parallax Normal Mapping demo to more accurately describe the shader technique that it implements. This new demo contains many critical bug fixes.
main.cpp: The cube model no longer contains a bitangent vertex attribute. The bitangent is now calculated in the vertex shader. Only the tangent vector is calculated and stored in the cube now. The CalcTangentVector() function now calculates the handedness of the local tangent space coordinate system at each vertex and stores it in the tangent vector's 'w' component.
parallax_normal_mapping.fx: The bitangent vector is now calculated in the vertex shader. Fixed a bug where the transpose of the tbnMatrix was being used. This effect file now contains 6 techniques: 3 parallax normal mapping techniques for each of the 3 standard light types, and 3 normal mapping techniques for each of the 3 standard light types.
21 January 2007.
parallax_bump_mapping.fx: Removed initialization of global light and material structures. The application now does this. Removed PS_INPUT and PS_INPUT_SPOT structures. Pixel shaders now use the vertex shader output structures VS_OUTPUT and VS_OUTPUT_SPOT as input structures. Added scaleBias global uniform variable.
main.cpp: Replaced D3D9 versions of the Light and Material structures with those from the parallax_bump_mapping.fx effect file. Added 'g_scaleBias' global variable and added ability to allow users to modify the scale and bias at runtime. Added ability to enable and disable parallax mapping. See the source code for a list of updated keyboard commands.
15 January 2007.
parallax_bump_mapping.fx: Removed all semantics except for those used by the vertex and pixel shader input and output structures. Changed the BIAS from -0.02 to -0.03. This seems to reduce the parallax mapping artifacts for the stone texture maps used in this demo. Pixel shaders now normalize the normal fetched from the normal map texture. This gives a slight improvement to the visual quality