Displacement Mapping (Shift map)
Another application of Normal maps is displacement mapping, in which the increase in detail is no longer achieved through virtual illumination, but rather a real change in the vertices of the model. When using displacement mapping, the vertex is translated along its normal vector, and the value of the normal is specified by a displacement map. A displacement map is a highly textured map with only one channel value and a height size. Figure 9.4 is the stone wall texture used in this chapter, corresponding to a displacement map.
So displacement is only a 8-bit data channel, so it appears as a gray area.
Figure 9.4 A color map (left) and displacement map (right) for a stone wall. (Textures by Nick Zuccarello, Florida Interactive Entertainment Academy.)
Depending on the result sampled from the displacement map, a vertex is shifted either along the normal or outward. Use the following formula to perform an outward shift: Position = Position0 + (Normal * Scale * displacementmagnitude)
Where scale is a shader constant that adjusts the magnitudes stored in the displacement map. For inward displacement, use the following formula:
Position = Position0 + (Normal * Scale * displacementmagnitude 1)
A Displacement Mapping Effect
Listing 9.2 lists some of the code for the displacement map effect, mainly vertex shader part of the code.
List 9.2 An abbreviated displacement Mapping Effect (Note: This provides a complete displacement map Effect code, which is also required for the exercise of question 2nd).
#include "include\\common.fxh" Cbuffer cbufferperframe {float4 Ambientcolor:ambient < string uiname = "Ambient
Light ";
String uiwidget = "Color";
> = {1.0f, 1.0f, 1.0f, 1.0f};
FLOAT4 Lightcolor:color < string Object = "LightColor0";
String uiname = "Light Color";
String uiwidget = "Color";
> = {1.0f, 1.0f, 1.0f, 1.0f};
FLOAT3 Lightposition:position < string Object = "PointLight0";
String uiname = "Light Position";
String space = "the World";
> = {0.0f, 0.0f, 0.0f};
Float Lightradius < String uiname = "Light Radius";
String uiwidget = "Slider";
float uimin = 0.0;
float Uimax = 100.0;
float Uistep = 1.0;
> = {10.0f}; FLOAT3 Cameraposition:cameraposition < string uiwidget= "None";
>;
} cbuffer cbufferperobject {float4x4 worldviewprojection:worldviewprojection < string uiwidget= ' None '; >; float4x4 World:world < string uiwidget= "None";
>; FLOAT4 Specularcolor:specular < string UInAme = "Specular Color";
String uiwidget = "Color";
> = {1.0f, 1.0f, 1.0f, 1.0f};
Float Specularpower:specularpower < String uiname = "specular power";
String uiwidget = "Slider";
float Uimin = 1.0;
float Uimax = 255.0;
float Uistep = 1.0;
> = {25.0f};
Float Displacementscale < string uiname = "Displacement Scale";
String uiwidget = "Slider";
float uimin = 0.0;
float Uimax = 2.0;
float uistep = 0.01;
> = {0.0f};
} texture2d colortexture < string resourcename = "Default_color.dds";
String uiname = "Color texture";
String resourcetype = "2D";
>;
Texture2d DisplacementMap < string uiname = "Displacement Map";
String resourcetype = "2D";
>;
Samplerstate Trilinearsampler {Filter = min_mag_mip_linear;
Addressu = WRAP;
ADDRESSV = WRAP;
};
Rasterizerstate disableculling {cullmode = NONE;
/************* Data Structures *************/struct Vs_input {float4 objectposition:position; FLOAT2 texturecoordinate: Texcoord;
FLOAT3 Normal:normal;
FLOAT3 tangent:tangent;
};
struct Vs_output {float4 position:sv_position;
FLOAT3 Normal:normal;
FLOAT3 tangent:tangent;
FLOAT3 Binormal:binormal;
FLOAT2 texturecoordinate:texcoord0;
FLOAT3 Lightdirection:texcoord1;
FLOAT3 Viewdirection:texcoord2;
};
/************* Vertex Shader *************/vs_output vertex_shader (vs_input in) {vs_output out = (vs_output) 0;
Float2 texturecoordinate = Get_corrected_texture_coordinate (in.
Texturecoordinate);
if (Displacementscale > 0.0f) {Float displacement = DisplacementMap.
Samplelevel (Trilinearsampler, texturecoordinate, 0); In. OBJECTPOSITION.XYZ + + in.
Normal * Displacementscale * (displacement-1); } out. Position = Mul (in.
Objectposition, worldviewprojection); Out.
Texturecoordinate = texturecoordinate; Out. Normal = Normalize (Mul (FLOAT4) (in.
Normal, 0), world). xyz); FLOAT3 worldposition = Normalize (Mul (in.
Objectposition, World)).
xyz Out. viewdirection = NormAlize (cameraposition-worldposition); Out.
Lightdirection = Get_light_data (lightposition, worldposition, Lightradius);
return out;
/************* Pixel Shader *************/float4 pixel_shader (vs_output in): sv_target {float4 out = (float4) 0; FLOAT3 normal = normalize (in.
Normal); FLOAT3 viewdirection = Normalize (in.
Viewdirection); FLOAT4 color = colortexture.sample (Trilinearsampler, in.
Texturecoordinate);
FLOAT3 ambient = get_vector_color_contribution (Ambientcolor, COLOR.RGB);
Light_contribution_data Lightcontributiondata;
Lightcontributiondata.color = Color;
Lightcontributiondata.normal = Normal;
Lightcontributiondata.viewdirection = viewdirection; Lightcontributiondata.lightdirection = Float4 (in.
Lightdirection, 1);
Lightcontributiondata.specularcolor = Specularcolor;
Lightcontributiondata.specularpower = Specularpower;
Lightcontributiondata.lightcolor = Lightcolor;
FLOAT3 light_contribution = get_light_contribution (Lightcontributiondata); OUT.RGB = AMBient + light_contribution;
OUT.A = 1.0f;
return out; }/************* Techniques *************/technique10 Main10 {pass P0 {SetVertexShader (Compileshader, Vs_4_0
Ex_shader ()));
Setgeometryshader (NULL);
SetPixelShader (Compileshader (Ps_4_0, Pixel_shader ()));
Setrasterizerstate (disableculling);
}
}