// Compulsory lines for entry points // #o3d VertexShaderEntryPoint VS // #o3d PixelShaderEntryPoint PS // #o3d MatrixLoadOrder RowMajor // This shader uses the following inputs: // Position, Normal, Tangent, Binormal, UV Set #0 // // And the following samplers: // Diffuse, Normal // // If applies directionnal and ambient lighting // float4x4 worldViewProjection : WorldViewProjection; // The 4x4 world view projection matrix. float4x4 worldInverseTranspose : WorldInverseTranspose; float4x4 world : World; float4x4 viewInverse : ViewInverse; float4x4 view : VIEW; #include "../Data/Shaders/ShaderInterfaces/DirectionalLight.shader" #include "../Data/Shaders/ShaderInterfaces/AmbientLight.shader" sampler2D SamplerDiffuse; sampler2D SamplerNormal; //////////////////////////////////////////////////////////////// // struct VertexShaderInput { float4 Position : POSITION; float4 Normal : NORMAL; float4 Tangent : TANGENT; float4 Binormal : BINORMAL; float2 UV : TEXCOORD0; }; struct PixelShaderInput { float4 Position : POSITION; float2 UV : TEXCOORD0; float3 Normal : TEXCOORD1; float3 Tangent : TEXCOORD2; float3 Binormal : TEXCOORD3; float3 WorldPosition : TEXCOORD4; }; //////////////////////////////////////////////////////////////// // PixelShaderInput VS( VertexShaderInput _Input ) { PixelShaderInput output; // Transform Position into clip space. output.Position = mul( _Input.Position, worldViewProjection ); // Transform the Tangent frame into world space. output.Tangent = mul( float4( _Input.Tangent.xyz, 0 ), world ).xyz; output.Binormal = mul( float4( _Input.Binormal.xyz, 0 ), world ).xyz; output.Normal = mul( float4( _Input.Normal.xyz, 0 ), world ).xyz; // Pass through the texture coordinates. output.UV = _Input.UV; // Calculate surface Position in world space. Used for lighting. output.WorldPosition = mul( _Input.Position, world ).xyz; return output; } float4 PS( PixelShaderInput _Input ) : COLOR { _Input.Tangent = normalize( _Input.Tangent ); _Input.Binormal = normalize( _Input.Binormal ); _Input.Normal = normalize( _Input.Normal ); // Compute view vector float3 ToCamera = viewInverse[3].xyz - _Input.WorldPosition.xyz; float fCameraDistance = length( ToCamera ); ToCamera /= fCameraDistance; // Construct a transform from Tangent space into world space. float3x3 Tangent2World = float3x3( _Input.Binormal, _Input.Tangent, _Input.Normal ); // Read the diffuse & normal float4 DiffuseColor = tex2D( SamplerDiffuse, _Input.UV ); float3 Normal = 2 * tex2D( SamplerNormal, _Input.UV ).xyz - 1; Normal = normalize( mul( Normal, Tangent2World ) ); float4 SpecularColor = float4( 1, 1, 1, 1 ); // Apply lighting in world space float3 HalfVector = normalize( LightWorldDirection + ToCamera ); float4 Lighting = lit( dot( Normal, LightWorldDirection ), dot( Normal, HalfVector ), 20.0 ); float4 Result = AmbientColor * DiffuseColor + LightColor * (DiffuseColor * Lighting.y + SpecularColor * Lighting.z); return float4( Result.rgb, 1 ); }