matrix WorldMatrix : WorldMatrix; matrix ViewMatrix : ViewMatrix; matrix ProjectionMatrix : ProjectionMatrix; float3 CameraPosition : CamPos; float3 CameraDirection : CamDir; float3 LightPos : LightPosition; float4 LightColor : LightColor; Texture2D Diffuse : Diffuse; Texture2D Normal : Normal; SamplerState samLinear { Filter = ANISOTROPIC; AddressU = Wrap; AddressV = Wrap; }; DepthStencilState RenderWithStencilState { StencilEnable = false; DepthEnable = TRUE; DepthWriteMask = ALL; }; RasterizerState EnableCulling { CullMode = BACK; }; struct COLOR_PAIR { float4 Diffuse : COLOR0; float4 Specular : COLOR1; }; COLOR_PAIR CalculatePointLight(float3 vPosition, float3 vNormal, float3 vViewDir, float3 vLightPos, float LightRange, float4 LightColor, float2 SpecularValue) { COLOR_PAIR rResult = (COLOR_PAIR)0; float3 vLightDir = normalize(vLightPos - vPosition); // calc LightDirection float fDiffuse = dot(vNormal, vLightDir); // get diffuse float3 vReflect = reflect(vNormal, vLightDir); float fSpecular = dot(vReflect, vViewDir); if (fSpecular > 0) fSpecular = pow( abs(fSpecular), SpecularValue.x) * SpecularValue.y; else fSpecular = 0; float fAtten = 1.0f; float LD = length(vPosition - vLightPos); if(LD > LightRange) { fAtten = 0.f; } else { fAtten *= 1.f/(0 + 1*LD + 0*LD*LD); fAtten = min(1.0f, fAtten); } rResult.Diffuse = max(0.0f, fAtten * fDiffuse * LightColor); rResult.Specular = max(0.0f, fAtten * fSpecular * LightColor); return rResult; } struct VS_OUTPUT { float4 Pos : SV_POSITION; float3 Norm : NORMAL; float2 Tex : TEXCOORD0; float3 WorldPos : TEXCOORD1; float3 ViewDir : TEXCOORD2; }; struct VSN_OUTPUT { float4 Pos : SV_POSITION; float3 Norm : NORMAL; float2 Tex : TEXCOORD0; float3 WorldPos : TEXCOORD1; float3 ViewDir : TEXCOORD2; float3 Tangent : TEXCOORD3; float3 Binormal : TEXCOORD4; }; VS_OUTPUT VS(float4 Pos : POSITION, float3 Norm : NORMAL, float2 Tex : TEXCOORD) { VS_OUTPUT output = (VS_OUTPUT)0; output.Pos = mul( Pos, WorldMatrix ); output.Pos = mul( output.Pos, ViewMatrix ); output.Pos = mul( output.Pos, ProjectionMatrix ); output.Norm = mul(float4(Norm, 0.0), WorldMatrix).xyz; output.Tex = Tex; output.WorldPos = mul(Pos, WorldMatrix).xyz; output.ViewDir = mul(Pos, WorldMatrix).xyz - CameraPosition; return output; } VSN_OUTPUT NormalMappingVS(float4 Pos : POSITION, float3 Norm : NORMAL, float3 Tangent : TANGENT, float2 Tex : TEXCOORD) { VSN_OUTPUT output = (VSN_OUTPUT)0; output.Pos = mul( Pos, WorldMatrix ); output.Pos = mul( output.Pos, ViewMatrix ); output.Pos = mul( output.Pos, ProjectionMatrix ); output.Norm = mul(float4(Norm, 0.0), WorldMatrix).xyz; output.Tangent = mul(float4(Tangent, 0.0), WorldMatrix).xyz; output.Binormal = cross(output.Norm, output.Tangent); output.Tex = Tex; output.WorldPos = mul(Pos, WorldMatrix).xyz; output.ViewDir = mul(Pos, WorldMatrix).xyz - CameraPosition; return output; } float4 NormalMappingPS( VSN_OUTPUT input) : SV_Target { float3x3 objToTangentSpace = float3x3( normalize(input.Tangent), normalize(input.Binormal), normalize(input.Norm) ); float4 base = Diffuse.Sample(samLinear, input.Tex); float4 bump = Normal.Sample(samLinear, input.Tex); bump.xyz = normalize(bump.xyz * 2 - 1); float3 normal = mul(objToTangentSpace, bump.xyz); float3 lightpos = mul(objToTangentSpace, LightPos); COLOR_PAIR LightResult = CalculatePointLight(input.WorldPos, normal, normalize(input.ViewDir), lightpos, 1000.0f, LightColor, float2(16.0f, 1.0f)); float4 color = Diffuse.Sample(samLinear, input.Tex) * LightResult.Diffuse + LightResult.Specular; return color; } float4 PS( VS_OUTPUT input) : SV_Target { COLOR_PAIR LightResult = CalculatePointLight(input.WorldPos, normalize(input.Norm), normalize(input.ViewDir), LightPos, 1000.0f, LightColor, float2(16.0f, 1.0f)); float4 color = Diffuse.Sample(samLinear, input.Tex) * LightResult.Diffuse + LightResult.Specular; return color; } float4 LightPS( VS_OUTPUT input) : SV_Target { return float4(LightColor.x, LightColor.y, LightColor.z,1); } //-------------------------------------------------------------------------------------- technique10 Render { pass P0 { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, PS() ) ); SetDepthStencilState( RenderWithStencilState, 0 ); SetBlendState( NULL, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); SetRasterizerState( EnableCulling ); } } technique10 NormalMapping { pass P0 { SetVertexShader( CompileShader( vs_4_0, NormalMappingVS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, NormalMappingPS() ) ); SetDepthStencilState( RenderWithStencilState, 0 ); SetBlendState( NULL, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); SetRasterizerState( EnableCulling ); } } technique10 Light { pass P0 { SetVertexShader( CompileShader( vs_4_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_4_0, LightPS() ) ); SetDepthStencilState( RenderWithStencilState, 0 ); SetBlendState( NULL, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); SetRasterizerState( EnableCulling ); } }