#line 2 "C:\Documents\GDC2006\Demo 3 - Graphics and SceneDesigner\Scene Application\Data\MadLab2006\Win32\Shaders\Generated\\00000B8F-00000000-00000000-00180020-V.hlsl" //--------------------------------------------------------------------------- // Constant variables: //--------------------------------------------------------------------------- float4 g_AmbientLight : AmbientLight; float4 g_MaterialEmissive : MaterialEmissive; sampler Parallax : Parallax; float4 g_ParallaxOffset : ParallaxOffset; sampler Normal : Normal; sampler Base : Base; sampler Detail : Detail; float4 g_DirAmbient0 : Ambient; float4 g_DirDiffuse0 : Diffuse; float4 g_DirSpecular0 : Specular; float4 g_DirWorldPosition0 : WorldPosition; float4 g_DirWorldDirection0 : WorldDirection; float4 g_DirAmbient : Ambient; float4 g_DirDiffuse : Diffuse; float4 g_DirSpecular : Specular; float4 g_DirWorldPosition : WorldPosition; float4 g_DirWorldDirection : WorldDirection; //--------------------------------------------------------------------------- // Functions: //--------------------------------------------------------------------------- /* This fragment is responsible for normalizing a float3. */ void NormalizeFloat3(float3 VectorIn, out float3 VectorOut) { VectorOut = normalize(VectorIn); } //--------------------------------------------------------------------------- /* Separate a float4 into a float3 and a float. */ void SplitColorAndOpacity(float4 ColorAndOpacity, out float3 Color, out float Opacity) { Color.rgb = ColorAndOpacity.rgb; Opacity = ColorAndOpacity.a; } //--------------------------------------------------------------------------- /* This fragment is responsible for sampling a texture and returning its value as a RGB value. */ void TextureRGBSample(float2 TexCoord, sampler Sampler, out float3 ColorOut) { ColorOut.rgb = tex2D(Sampler, TexCoord).rgb; } //--------------------------------------------------------------------------- /* This fragment is responsible for calculating the UV offset to apply as a result of a parallax map. */ void CalculateParallaxOffset(float2 TexCoord, float2 Height, float OffsetScale, float3 TangentSpaceEyeVec, out float2 ParallaxOffsetUV) { // Calculate offset scaling constant bias. float2 Bias = float2(OffsetScale, OffsetScale) * -0.5; // Calculate offset float2 Offset = Height.rg * OffsetScale + Bias; // Get texcoord. ParallaxOffsetUV = TexCoord + Offset * TangentSpaceEyeVec.xy; } //--------------------------------------------------------------------------- /* This fragment is responsible for sampling a texture and returning its value as a RGB value and an A value. */ void TextureRGBASample(float2 TexCoord, sampler Sampler, out float4 ColorOut) { ColorOut = tex2D(Sampler, TexCoord); } //--------------------------------------------------------------------------- /* This fragment is responsible for scaling a float3 by a constant. */ void ScaleFloat3(float3 V1, float Scale, out float3 Output) { Output = Scale * V1; } //--------------------------------------------------------------------------- /* This fragment is responsible for sampling a normal map to generate the new world-space normal. The normal map type is an enumerated value that indicates the following: 0 - Standard (rgb = normal/binormal/tangent) 1 - DXN (rg = normal.xy need to calculate z) 2 - DXT5 (ag = normal.xy need to calculate z) */ void CalculateNormalFromColor(float4 NormalMap, float3 WorldNormalIn, float3 WorldBinormalIn, float3 WorldTangentIn, int NormalMapType, out float3 WorldNormalOut) { NormalMap = NormalMap * 2.0 - 1.0; // Do nothing extra for Standard // Handle compressed types: if (NormalMapType == 1) // DXN { NormalMap.rgb = float3(NormalMap.r, NormalMap.g, sqrt(1 - NormalMap.r * NormalMap.r - NormalMap.g * NormalMap.g)); } else if (NormalMapType == 2) // DXT5 { NormalMap.rg = NormalMap.ag; NormalMap.b = sqrt(1 - NormalMap.r*NormalMap.r - NormalMap.g * NormalMap.g); } float3x3 xForm = float3x3(WorldTangentIn, WorldBinormalIn, WorldNormalIn); xForm = transpose(xForm); WorldNormalOut = mul(xForm, NormalMap.rgb); WorldNormalOut = normalize(WorldNormalOut); } //--------------------------------------------------------------------------- /* This fragment is responsible for multiplying two float3's. */ void MultiplyFloat3(float3 V1, float3 V2, out float3 Output) { Output = V1 * V2; } //--------------------------------------------------------------------------- /* This fragment is responsible for multiplying two floats. */ void MultiplyFloat(float V1, float V2, out float Output) { Output = V1 * V2; } //--------------------------------------------------------------------------- /* This fragment is responsible for accumulating the effect of a light on the current pixel. LightType can be one of three values: 0 - Directional 1 - Point 2 - Spot Note that the LightType must be a compile-time variable, not a runtime constant/uniform variable on most Shader Model 2.0 cards. The compiler will optimize out any constants that aren't used. Attenuation is defined as (const, linear, quad, range). Range is not implemented at this time. SpotAttenuation is stored as (cos(theta/2), cos(phi/2), falloff) theta is the angle of the inner cone and phi is the angle of the outer cone in the traditional DX manner. Gamebryo only allows setting of phi, so cos(theta/2) will typically be cos(0) or 1. To disable spot effects entirely, set cos(theta/2) and cos(phi/2) to -1 or lower. */ void Light(float4 WorldPos, float3 WorldNrm, int LightType, bool SpecularEnable, float Shadow, float3 WorldViewVector, float4 LightPos, float3 LightAmbient, float3 LightDiffuse, float3 LightSpecular, float3 LightAttenuation, float3 LightSpotAttenuation, float3 LightDirection, float4 SpecularPower, float3 AmbientAccum, float3 DiffuseAccum, float3 SpecularAccum, out float3 AmbientAccumOut, out float3 DiffuseAccumOut, out float3 SpecularAccumOut) { // Get the world space light vector. float3 LightVector; float DistanceToLight; if (LightType == 0) { LightVector = -LightDirection; } else { LightVector = LightPos - WorldPos; DistanceToLight = length(LightVector); LightVector = LightVector / DistanceToLight; } // Take N dot L as intensity. float LightNDotL = dot(LightVector, WorldNrm); float LightIntensity = max(0, LightNDotL); float Attenuate = 1.0; if (LightType != 0) { // Attenuate Here Attenuate = LightAttenuation.x + LightAttenuation.y * DistanceToLight + LightAttenuation.z * DistanceToLight * DistanceToLight; Attenuate = max(1.0, Attenuate); Attenuate = 1.0 / Attenuate; if (LightType == 2) { // Get intensity as cosine of light vector and direction. float CosAlpha = dot(-LightVector, LightDirection); // Subtract out outer cone angle. CosAlpha = smoothstep(LightSpotAttenuation.y, LightSpotAttenuation.x, CosAlpha); // Power to falloff. CosAlpha = pow(CosAlpha, LightSpotAttenuation.z); // Multiply the spot attenuation into the overall attenuation. Attenuate *= CosAlpha; } LightIntensity = LightIntensity * Attenuate; } // Determine the interaction of diffuse color of light and material. // Scale by the attenuated intensity. DiffuseAccumOut = DiffuseAccum; DiffuseAccumOut.rgb += LightDiffuse.rgb * LightIntensity * Shadow; // Determine ambient contribution - not affected by shadow AmbientAccumOut = AmbientAccum; AmbientAccumOut.rgb += LightAmbient.rgb * Attenuate; SpecularAccumOut = SpecularAccum; if (SpecularEnable) { // Get the half vector. float3 LightHalfVector = LightVector + WorldViewVector; LightHalfVector = normalize(LightHalfVector); // Determine specular intensity. float LightNDotH = max(0, dot(WorldNrm, LightHalfVector)); float LightSpecIntensity = pow(LightNDotH, SpecularPower.x); //if (LightNDotL < 0.0) // LightSpecIntensity = 0.0; // Must use the code below rather than code above. // Using previous lines will cause the compiler to generate incorrect // output. float SpecularMultiplier = LightNDotL > 0.0 ? 1.0 : 0.0; // Attenuate Here LightSpecIntensity = LightSpecIntensity * Attenuate * SpecularMultiplier; // Determine the interaction of specular color of light and material. // Scale by the attenuated intensity. SpecularAccumOut.rgb += Shadow * LightSpecIntensity * LightSpecular; } } //--------------------------------------------------------------------------- /* This fragment is responsible for computing the coefficients for the following equations: Kdiffuse = MatEmissive + MatAmbient * Summation(0...N){LightAmbientContribution[N]} + MatDiffuse * Summation(0..N){LightDiffuseContribution[N]} Kspecular = MatSpecular * Summation(0..N){LightSpecularContribution[N]} */ void ComputeShadingCoefficients(float3 MatEmissive, float3 MatDiffuse, float3 MatAmbient, float3 MatSpecular, float3 LightSpecularAccum, float3 LightDiffuseAccum, float3 LightAmbientAccum, bool Saturate, out float3 Diffuse, out float3 Specular) { Diffuse = MatEmissive + MatAmbient * LightAmbientAccum + MatDiffuse * LightDiffuseAccum; Specular = MatSpecular * LightSpecularAccum; if (Saturate) { Diffuse = saturate(Diffuse); Specular = saturate(Specular); } } //--------------------------------------------------------------------------- /* This fragment is responsible for computing the final RGB color. */ void CompositeFinalRGBColor(float3 DiffuseColor, float3 SpecularColor, out float3 OutputColor) { OutputColor.rgb = DiffuseColor.rgb + SpecularColor.rgb; } //--------------------------------------------------------------------------- /* This fragment is responsible for computing the final RGB color. */ void CompositeFinalRGBAColor(float3 FinalColor, float FinalOpacity, out float4 OutputColor) { OutputColor.rgb = FinalColor.rgb; OutputColor.a = FinalOpacity; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Input: //--------------------------------------------------------------------------- struct Input { float4 PosProjected : POSITION0; float4 WorldPos : TEXCOORD0; float3 WorldNormal : TEXCOORD1; float3 WorldBinormal : TEXCOORD2; float3 WorldTangent : TEXCOORD3; float3 TangentSpaceView : TEXCOORD4; float4 VertexColors : COLOR0; float2 UVSet0 : TEXCOORD5; }; //--------------------------------------------------------------------------- // Output: //--------------------------------------------------------------------------- struct Output { float4 Color : COLOR0; }; //--------------------------------------------------------------------------- // Main(): //--------------------------------------------------------------------------- Output Main(Input In) { Output Out; // Function call #0 float3 VectorOut_CallOut0; NormalizeFloat3(In.WorldNormal, VectorOut_CallOut0); // Function call #1 float3 VectorOut_CallOut1; NormalizeFloat3(In.WorldTangent, VectorOut_CallOut1); // Function call #2 float3 Color_CallOut2; float Opacity_CallOut2; SplitColorAndOpacity(In.VertexColors, Color_CallOut2, Opacity_CallOut2); // Function call #3 float3 VectorOut_CallOut3; NormalizeFloat3(In.WorldBinormal, VectorOut_CallOut3); // Function call #4 float3 ColorOut_CallOut4; TextureRGBSample(In.UVSet0, Parallax, ColorOut_CallOut4); // Function call #5 float3 VectorOut_CallOut5; NormalizeFloat3(In.TangentSpaceView, VectorOut_CallOut5); // Function call #6 float2 ParallaxOffsetUV_CallOut6; CalculateParallaxOffset(In.UVSet0, ColorOut_CallOut4, g_ParallaxOffset, VectorOut_CallOut5, ParallaxOffsetUV_CallOut6); // Function call #7 float4 ColorOut_CallOut7; TextureRGBASample(ParallaxOffsetUV_CallOut6, Base, ColorOut_CallOut7); // Function call #8 float3 ColorOut_CallOut8; TextureRGBSample(ParallaxOffsetUV_CallOut6, Detail, ColorOut_CallOut8); // Function call #9 float4 ColorOut_CallOut9; TextureRGBASample(ParallaxOffsetUV_CallOut6, Normal, ColorOut_CallOut9); // Function call #10 float3 Color_CallOut10; float Opacity_CallOut10; SplitColorAndOpacity(ColorOut_CallOut7, Color_CallOut10, Opacity_CallOut10); // Function call #11 float3 Output_CallOut11; ScaleFloat3(ColorOut_CallOut8, float(2.0), Output_CallOut11); // Function call #12 float3 WorldNormalOut_CallOut12; CalculateNormalFromColor(ColorOut_CallOut9, VectorOut_CallOut0, VectorOut_CallOut3, VectorOut_CallOut1, int(0), WorldNormalOut_CallOut12); // Function call #13 float3 Output_CallOut13; MultiplyFloat3(Color_CallOut10, Output_CallOut11, Output_CallOut13); // Function call #14 float Output_CallOut14; MultiplyFloat(Opacity_CallOut2, Opacity_CallOut10, Output_CallOut14); // Function call #15 float3 AmbientAccumOut_CallOut15; float3 DiffuseAccumOut_CallOut15; float3 SpecularAccumOut_CallOut15; Light(In.WorldPos, WorldNormalOut_CallOut12, int(0), bool(false), float(1.0), float3(0.0, 0.0, 0.0), g_DirWorldPosition0, g_DirAmbient0, g_DirDiffuse0, g_DirSpecular0, float3(0.0, 1.0, 0.0), float3(-1.0, -1.0, 0.0), g_DirWorldDirection0, float4(1.0, 1.0, 1.0, 1.0), g_AmbientLight, float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), AmbientAccumOut_CallOut15, DiffuseAccumOut_CallOut15, SpecularAccumOut_CallOut15); // Function call #16 float3 AmbientAccumOut_CallOut16; float3 DiffuseAccumOut_CallOut16; float3 SpecularAccumOut_CallOut16; Light(In.WorldPos, WorldNormalOut_CallOut12, int(0), bool(false), float(1.0), float3(0.0, 0.0, 0.0), g_DirWorldPosition, g_DirAmbient, g_DirDiffuse, g_DirSpecular, float3(0.0, 1.0, 0.0), float3(-1.0, -1.0, 0.0), g_DirWorldDirection, float4(1.0, 1.0, 1.0, 1.0), AmbientAccumOut_CallOut15, DiffuseAccumOut_CallOut15, float3(0.0, 0.0, 0.0), AmbientAccumOut_CallOut16, DiffuseAccumOut_CallOut16, SpecularAccumOut_CallOut16); // Function call #17 float3 Diffuse_CallOut17; float3 Specular_CallOut17; ComputeShadingCoefficients(g_MaterialEmissive, Color_CallOut2, In.VertexColors, float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), DiffuseAccumOut_CallOut16, AmbientAccumOut_CallOut16, bool(true), Diffuse_CallOut17, Specular_CallOut17); // Function call #18 float3 Output_CallOut18; MultiplyFloat3(Diffuse_CallOut17, Output_CallOut13, Output_CallOut18); // Function call #19 float3 OutputColor_CallOut19; CompositeFinalRGBColor(Output_CallOut18, Specular_CallOut17, OutputColor_CallOut19); // Function call #20 CompositeFinalRGBAColor(OutputColor_CallOut19, Output_CallOut14, Out.Color); return Out; }