Displacement Mapping(移位贴图)
Normal maps的另一个应用是displacement mapping,在这个应用中,细节的增加不再是通过虚拟光照得到的,而是真正的改变模型的vertices。使用displacement mapping时,vertex沿着它的法线向量平移,该法线的值由一个displacement map指定。一个displacement map就是一个高度纹理图,只有一个通道值,并且存储了高度的大小。图9.4就是本章一直使用的stone wall texture,对应的一种displacement map。
因此displacement只一个8位的数据通道,因此显示为一块灰色区域。
图9.4 A color map (left) and displacement map (right) for a stone wall. (Textures by Nick Zuccarello, Florida Interactive Entertainment Academy.)
根据从displacement map中采样的结果,对一个vertex移位时,要么沿着法线向内,要么向外。使用如下的公式执行向外移位: Position = Position0 + (Normal * Scale * DisplacementMagnitude)
其中,Scale是一个shader constant,用于调整存储在displacement map中的magnitudes。对于向内移位,使用下面的公式:
Position = Position0 + (Normal * Scale * DisplacementMagnitude 1)
A Displacement Mapping Effect
列表9.2列出了displacement map effect的部分代码,主要是vertex shader部分的代码。
列表9.2 An Abbreviated Displacement Mapping Effect(注:这里提供了完整的displacement map effect代码,也是练习第2题的要求)
#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 = "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, vertex_shader())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_4_0, pixel_shader())); SetRasterizerState(DisableCulling); } }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, float
, 1.0
floating
requestmapping、mapping、servlet mapping、requestmapping参数、requestmapping详解,以便于您获取更多的相关知识。