// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2008 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27517 // http://www.emergent.net // Gooch.fxl - Implements a modified version of Gooch shading using // warm and cool tonal interpolation as well as a black outline generated // using the extruded-backface method. One point light is used for the shading // as well as the object's material color. Specular highlights are not // generated. float4x4 WorldViewProj < string VarType = "Predefined"; string DefinedMapping = "WORLDVIEWPROJECTION"; >; float4x4 World < string VarType = "Predefined"; string DefinedMapping = "WORLD"; >; float4x4 ViewProj < string VarType = "Predefined"; string DefinedMapping = "VIEWPROJECTION"; >; static const int MAX_BONES = 30; float4x3 SkinBone[MAX_BONES] < string VarType = "Predefined"; string DefinedMapping = "SKINBONEMATRIX3"; >; float4 EdgeColor < string VarType = "Attribute"; string Description = "The color for the edges generated by the extruded " "backface method."; bool Hidden = false; bool Color = true; > = {0.0f, 0.0f, 0.0f, 1.0f}; float ExtrusionScale < string VarType = "Attribute"; string Description = "The scale of the extrusion which controls the " "line thickness."; bool Hidden = false; > = 0.1f; float3 LightPosition < string VarType = "Object"; string ObjectProperty = "Position"; string Object = "PointLight"; string Space = "World"; int ObjectIndex = 0; >; float3 WarmTone < string VarType = "Attribute"; string Description = "The warm tone for the Gooch shading model."; bool Hidden = false; bool Color = true; > = {0.8f, 0.8f, 0.0f}; float3 CoolTone < string VarType = "Attribute"; string Description = "The cool tone for the Gooch shading model."; bool Hidden = false; bool Color = true; > = {0.0f, 0.0f, 0.8f}; float3 MaterialDiffuse < string VarType = "Predefined"; string DefinedMapping = "MaterialDiffuse"; >; // Calculate the skinned position. We push the world position back out so that // we can pass it to the pixel shader for per-pixel lighting. float4 CalculateSkinnedPosition(float4 inPos, float4 inBlendWeights, float4 inBlendIndices, out float4 WorldPos) { int4 indices = inBlendIndices; // Calculate normalized fourth bone weight float weight4 = 1.0f - inBlendWeights[0] - inBlendWeights[1] - inBlendWeights[2]; // Calculate bone transform float4x3 SkinBoneTransform; SkinBoneTransform = inBlendWeights[0] * SkinBone[indices[0]]; SkinBoneTransform += inBlendWeights[1] * SkinBone[indices[1]]; SkinBoneTransform += inBlendWeights[2] * SkinBone[indices[2]]; SkinBoneTransform += weight4 * SkinBone[indices[3]]; WorldPos = float4(mul(inPos, SkinBoneTransform), 1.0); float4 ProjectedPos = mul(WorldPos, ViewProj); return ProjectedPos; } struct ColorPassOutput { float4 Pos : POSITION; float3 WorldPos : TEXCOORD0; float3 Nrm : TEXCOORD1; }; ColorPassOutput ColorPassVS(in float4 inPos : POSITION, in float3 inNrm : NORMAL) { ColorPassOutput Out; Out.WorldPos = mul(inPos, World); Out.Pos = mul(inPos, WorldViewProj); Out.Nrm = inNrm; return Out; } ColorPassOutput ColorPassVSSkinned(in float4 inPos : POSITION, in float4 inWeights : BLENDWEIGHT, in float4 inIndices : BLENDINDICES, in float3 inNrm : NORMAL) { ColorPassOutput Out; Out.Pos = CalculateSkinnedPosition(inPos, inWeights, inIndices, Out.WorldPos); Out.Nrm = inNrm; return Out; } float4 ColorPassPS(in float3 inPos : TEXCOORD0, in float3 inNrm : TEXCOORD1) : COLOR0 { float3 LightVec = LightPosition - inPos; LightVec = normalize(LightVec); float NDotL = dot(inNrm, LightVec); // Get the ShadedColor via the Gooch shading model. // ((1 + NDotL) / 2) * Cool + (1 - ((1 + NDotL) / 2)) * Warm // Once we have this color, we modulate by the material color. float4 ShadedColor = float4(0.0f, 0.0f, 0.0f, 1.0f); float LerpValue = (1 + NDotL) * 0.5f; ShadedColor += float4(CoolTone * LerpValue, 0.0f); ShadedColor += float4(WarmTone * (1 - LerpValue), 0.0f); ShadedColor.rgb *= MaterialDiffuse; return ShadedColor; } struct EdgePassOutput { float4 Pos : POSITION; }; EdgePassOutput EdgePassVS(in float4 inPos : POSITION, in float3 inNrm : NORMAL) { EdgePassOutput Out; // Extrude the position a small amount before we transform into clip space. float4 ExtrudedPos = inPos + float4((ExtrusionScale * inNrm), 0.0f); Out.Pos = mul(ExtrudedPos, WorldViewProj); return Out; } EdgePassOutput EdgePassVSSkinned(in float4 inPos : POSITION, in float3 inNrm : NORMAL, in float4 inWeights : BLENDWEIGHT, in float4 inIndices : BLENDINDICES) { EdgePassOutput Out; float4 WorldPos; // Extrude the position a small amount before we transform into clip space. float4 ExtrudedPos = inPos + float4((ExtrusionScale * inNrm), 0.0f); Out.Pos = CalculateSkinnedPosition(ExtrudedPos, inWeights, inIndices, WorldPos); return Out; } // Output the color for the edge pass. The edges simply need to be the color // specified by the shader. float4 EdgePassPS() : COLOR0 { return EdgeColor; } technique Gooch < string description = "Implements a modified version of Gooch shading " "using warm and cool tonal interpolation as well as an outline " "generated using the extruded-backface method. The object's diffuse " "material color is used in the shading as well as a single point " "light."; bool UsesNiRenderState = true; bool UsesNiLightState = false; int implementation = 0; > { pass ColorPass { VertexShader = compile vs_1_1 ColorPassVS(); PixelShader = compile ps_2_0 ColorPassPS(); // Set the CullMode to CW so we draw the CCW wrapped front-facing tris. CullMode = CW; } pass EdgePass { VertexShader = compile vs_1_1 EdgePassVS(); PixelShader = compile ps_2_0 EdgePassPS(); // Set the CullMode to CCW so we draw the CW wrapped back-facing tris. CullMode = CCW; } } technique GoochSkinned < string description = "Implements a modified version of Gooch shading " "using warm and cool tonal interpolation as well as an outline " "generated using the extruded-backface method. The object's diffuse " "material color is used in the shading as well as a single point " "light. This technique supports skinning."; bool UsesNiRenderState = true; bool UsesNiLightState = false; int implementation = 0; int BonesPerPartition = MAX_BONES; > { pass ColorPass { VertexShader = compile vs_1_1 ColorPassVSSkinned(); PixelShader = compile ps_2_0 ColorPassPS(); // Set the CullMode to CW so we draw the CCW wrapped front-facing tris. CullMode = CW; } pass EdgePass { VertexShader = compile vs_1_1 EdgePassVSSkinned(); PixelShader = compile ps_2_0 EdgePassPS(); // Set the CullMode to CCW so we draw the CW wrapped back-facing tris. CullMode = CCW; } }