Environment Mapping
Texture cubes的另一種應用是environment mapping。Environment mapping也稱為reflection mapping,用於近似類比reflective surfaces(反光表面),比如汽車上的鍍了一層金屬物的保險杠。
Environment mapping的處理過程比skybox稍微複雜一些,因為需要計算光線與表面的反射向量。反射向量主要由view direction(限入射角向量)和表面的法向量計算得到。具體的公式如下:
R = I – 2 * N * (I N)
其中,I表示入射向量,N指表面的法向量。列表8.2列出了一種environment mapping effect的代碼。
列表8.2 EnvironmentMapping.fx
#include "include\\Common.fxh"/************* Resources *************/cbuffer CBufferPerFrame{float4 AmbientColor : AMBIENT <string UIName = "Ambient Light";string UIWidget = "Color";> = {1.0f, 1.0f, 1.0f, 0.0f};float4 EnvColor : COLOR <string UIName = "Environment Color";string UIWidget = "Color";> = {1.0f, 1.0f, 1.0f, 1.0f };float3 CameraPosition : CAMERAPOSITION < string UIWidget="None"; >;}cbuffer CBufferPerObject{float4x4 WorldViewProjection : WORLDVIEWPROJECTION < string UIWidget="None"; >;float4x4 World : WORLD < string UIWidget="None"; >;float ReflectionAmount <string UIName = "Reflection Amount";string UIWidget = "slider";float UIMin = 0.0;float UIMax = 1.0;float UIStep = 0.05;> = {0.5f};}Texture2D ColorTexture <string ResourceName = "default_color.dds";string UIName = "Color Texture";string ResourceType = "2D";>;TextureCube EnvironmentMap <string UIName = "Environment Map";string ResourceType = "3D";>;SamplerState TrilinearSampler{Filter = MIN_MAG_MIP_LINEAR;};RasterizerState DisableCulling{CullMode = NONE;};/************* Data Structures *************/struct VS_INPUT{float4 ObjectPosition : POSITION;float3 Normal : NORMAL;float2 TextureCoordinate : TEXCOORD;};struct VS_OUTPUT{float4 Position : SV_Position;float2 TextureCoordinate : TEXCOORD0; float3 ReflectionVector : TEXCOORD1;};/************* Vertex Shader *************/VS_OUTPUT vertex_shader(VS_INPUT IN){VS_OUTPUT OUT = (VS_OUTPUT)0;OUT.Position = mul(IN.ObjectPosition, WorldViewProjection);OUT.TextureCoordinate = get_corrected_texture_coordinate(IN.TextureCoordinate);float3 worldPosition = mul(IN.ObjectPosition, World).xyz;float3 incident = normalize(worldPosition - CameraPosition);float3 normal = normalize(mul(float4(IN.Normal, 0), World).xyz);// Reflection Vector for cube map: R = I - 2*N * (I.N)OUT.ReflectionVector = reflect(incident, normal);return OUT;}/************* Pixel Shader *************/float4 pixel_shader(VS_OUTPUT IN) : SV_Target{float4 OUT = (float4)0;float4 color = ColorTexture.Sample(TrilinearSampler, IN.TextureCoordinate);float3 ambient = get_vector_color_contribution(AmbientColor, color.rgb);float3 environment = EnvironmentMap.Sample(TrilinearSampler, IN.ReflectionVector).rgb;float3 reflection = get_vector_color_contribution(EnvColor, environment);OUT.rgb = lerp(ambient, reflection, ReflectionAmount);OUT.a = color.a;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);}}
更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/extra/