//==================================================== // DNSREG Shader // Supports Diffuse, Normal, Specular, Reflection, Emissive & Grain (i.e. detail) //==================================================== // // #o3d VertexShaderEntryPoint VS // #o3d PixelShaderEntryPoint PS // #o3d MatrixLoadOrder RowMajor float4x4 WorldIT : WORLDINVERSETRANSPOSE; float4x4 Local2Proj : WORLDVIEWPROJECTION; float4x4 Local2World : WORLD; float4x4 Camera2World : VIEWINVERSE; #include "../Data/Shaders/ShaderInterfaces/DirectionalLight.shader" #include "../Data/Shaders/ShaderInterfaces/AmbientLight.shader" #include "DNSREG_LightingEquation.shader" float LightStrength; float EmissiveFactor; sampler2D TextureEmissiveSampler; float DiffuseFactor; sampler2D TextureColorSampler; float BumpFactor; sampler2D TextureNormalSampler; float SpecularFactor; float SpecularPower; sampler2D TextureSpecularSampler; float ReflectionFactor; sampler2D TextureReflectionSampler; samplerCUBE TextureEnvironmentSampler; float DetailFactor; float DetailScale; sampler2D TextureDetailSampler; //-------------- // vertex shader //-------------- struct VSInput { float4 Position : POSITION; float4 Normal : NORMAL; float4 Tangent : TANGENT; float4 Binormal : BINORMAL; float2 UV0 : TEXCOORD0; }; struct PSInput { float4 __Position : POSITION; float2 UV0 : TEXCOORD0; float3 Normal : TEXCOORD1; float3 Tangent : TEXCOORD2; float3 Binormal : TEXCOORD3; float3 ToLight : TEXCOORD4; float3 ToCamera : TEXCOORD5; }; PSInput VS( VSInput _Input ) { PSInput Output; Output.__Position = mul( _Input.Position, Local2Proj ); float3 WorldPosition = mul( _Input.Position, Local2World ).xyz; Output.ToCamera = Camera2World[3].xyz - WorldPosition; Output.ToLight = LightWorldDirection; Output.UV0 = _Input.UV0; Output.Normal = mul( _Input.Normal, WorldIT ).xyz; Output.Tangent = mul( _Input.Tangent, WorldIT ).xyz; Output.Binormal = mul( _Input.Binormal, WorldIT ).xyz; return Output; } //-------------- // pixel shader //-------------- float4 PS( PSInput _Input ) : COLOR { // Retrieve texture values float3 EmissiveColor = EmissiveFactor * tex2D( TextureEmissiveSampler, _Input.UV0 ).xyz; float3 ColorColor = DiffuseFactor * tex2D( TextureColorSampler, _Input.UV0 ).xyz; float3 SpecularColor = SpecularFactor * tex2D( TextureSpecularSampler, _Input.UV0 ).xyz; float3 ReflectionColor = ReflectionFactor * tex2D( TextureReflectionSampler, _Input.UV0 ).xyz; float3 DetailColor = DetailFactor * (tex2D( TextureDetailSampler, _Input.UV0 * DetailScale ).xyz - 0.5); float3 Normal = 2 * tex2D( TextureNormalSampler, _Input.UV0 ) - 1; Normal *= float3( BumpFactor, BumpFactor, 1 ); // Add detail ColorColor += DetailColor; // Transform normal into WORLD space _Input.Binormal = normalize( _Input.Binormal ); _Input.Tangent = normalize( _Input.Tangent ); _Input.Normal = normalize( _Input.Normal ); float3x3 Tangent2World = { _Input.Binormal, _Input.Tangent, _Input.Normal }; Normal = mul( Normal, Tangent2World ); Normal = normalize( Normal ); // Compute camera & lights vectors float3 ToLight = normalize( _Input.ToLight ); float3 ToCamera = normalize( _Input.ToCamera ); float3 Reflected = reflect( ToCamera, Normal ); // Fetch lighting in reflected direction float3 SampleDir = float3( -Reflected.x, -Reflected.z, Reflected.y ); float3 ReflectedEnvColor = texCUBE( TextureEnvironmentSampler, SampleDir ); // Compute specular factor float fSpecularDot = 0.3 + 0.7 * saturate( dot( -Reflected, ToLight ) ); float fSpecularFactor = pow( fSpecularDot, SpecularPower ); ////// COMBINE ////// float3 Color = ComputeLighting( AmbientColor, LightColor, ToLight, Normal, LightStrength, EmissiveColor, ColorColor, fSpecularFactor, SpecularColor, ReflectionColor, ReflectedEnvColor ); return float4( Color, 1 ); }