//---------------------------------------------------------------------------------- // Uniform Variables //---------------------------------------------------------------------------------- float4x4 coreWorldViewProj; float4x4 coreWorld; float4x4 coreWorldInverseTranspose; float4x4 coreViewInverse; float4x4 coreLight0; float4x4 coreLight1; float coreShininess; texture coreDiffuseTexture; texture coreDiffuseTexture1; float4 coreMaterialDiffuse; float4 coreMaterialSpecular; float fireWaveRadius; float fireRichtor; float3 firePlayerPosition; float boulderWaveRadius; float boulderRichtor; float3 boulderPlayerPosition; float4 boulderLookVector; bool boulderIsMoving; float4 boulderEnergyValue; float fireFrequency = 10.0f; // Between 1-300 --> Never 0!!! float fireAmplitude = 0.2f; // 0.01 < amplituted < 0.10 --> very sensitive float fireRedShift = 0.7f; // Increase red components of color float waveForm = 2.0f; float boulderAmplitude = 0.05f; // float boudlerRedShift = 0.3f; // Increase red components of color float waveFormScaler = 0.5f;; // Scale the height of the flame float4x4 playerWorldViewProj; Texture colorMap; sampler colorMapSampler = sampler_state { texture = ; AddressU = mirror; AddressV = mirror; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; }; sampler coreTextureSampler = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; sampler coreTextureSampler1 = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; AddressW = CLAMP; MIPFILTER = LINEAR; MINFILTER = LINEAR; MAGFILTER = LINEAR; }; struct coreVertexInput { float3 position : POSITION; float3 normal : NORMAL; float3 binormal : BINORMAL; float3 tangent : TANGENT; float4 texCoordDiffuse : TEXCOORD0; float4 color : COLOR0; }; struct coreVertexOutput { float4 hPosition : POSITION; float4 texCoordDiffuse : TEXCOORD0; float3 norm : TEXCOORD1; float3 Position3D : TEXCOORD2; float3 eyePos : TEXCOORD3; float4 color : COLOR0; }; struct GeneralVertexInput { float4 position : POSITION; //float3 position : POSITION; float2 texCoords : TEXCOORD0; //float4 texCoordDiffuse : TEXCOORD0; float3 normal : NORMAL; float3 binormal : BINORMAL; float3 tangent : TANGENT; float4 color : COLOR0; }; struct GeneralVertexToPixel { float4 position : POSITION; //float4 hPosition : POSITION; float2 texCoords : TEXCOORD0; // float4 texCoordDiffuse : TEXCOORD0; float4 color : COLOR0; float3 norm : TEXCOORD1; float3 texCoords2 : TEXCOORD2; float3 eyePos : TEXCOORD3; }; //---------------------------------------------------------------------------------- // Fire Shader AOE // The two distance equations take into account 3D distance which is why it moves up the mountain last // To switch to a 2D wave, just use distance formula on x and z values // We want to raise vertex based on reciprocal distance // cos func() rotates between -1 && 1 based on distance to wave front and the frequency // mult times distance to wave front taking abs value or result to clamp to upward movement only // sqrt to create the parabaloid wave form // amplituded to muffle the height to which the flame can rise // take inverse so that as waveDistance goes to 0, waveForm gets larger //---------------------------------------------------------------------------------- GeneralVertexToPixel FireVertexShader(GeneralVertexInput IN) { // Distance between Player and Vertex float groundZeroDistance = abs( distance( IN.position, firePlayerPosition) ); // Distance between vertex and wave crest float waveDistance = abs( (groundZeroDistance - fireWaveRadius) ); // Create the waveForm float waveForm = 1.0f/ (fireAmplitude + sqrt( abs( waveDistance * cos( waveDistance / fireFrequency) ))); // New vertex height based on wave form; IN.position.y = IN.position.y + fireRichtor * waveForm - 2.5f; // Now burn it down based on time //IN.position.y -= fireWaveRadius/500 * IN.position.y; // Pack it up GeneralVertexToPixel Output = (GeneralVertexToPixel)0; Output.position = mul(IN.position, coreWorldViewProj); Output.texCoords = IN.texCoords; // Pass red to fragment shader based on height Output.color.r = waveForm * fireRedShift; // Pass to fragShader return Output; } float4 FirePixelShader(GeneralVertexToPixel IN) : Color { float4 Output = (float4)0; clip(IN.color.r - 0.1f); Output = tex1D(coreTextureSampler, IN.color.r); return Output; } technique FireWave { pass Pass0 { VertexShader = compile vs_2_0 FireVertexShader(); PixelShader = compile ps_2_0 FirePixelShader(); FillMode = Solid; } } //--------------------------------------------------------------------------------- //Water Shader //--------------------------------------------------------------------------------- GeneralVertexToPixel WaterVertexShader( GeneralVertexInput IN) { if( IN.position.y > 0.0f ) { // Distance between vertex and wave crest float waveDistance = abs( length(IN.position - boulderWaveRadius) ); // See Fire Shader Notes for explanation float waveForm = 1.0f / (1.0f + boulderAmplitude + cos(waveDistance * 3.14159265f / 60 )); // We only want protrusions, not indentions into the object float adjustment = boulderRichtor / waveForm * waveFormScaler; if(adjustment > 1.0f) { // New vertex height IN.position = IN.position + (adjustment * boulderLookVector); } } // Pack it up GeneralVertexToPixel Output = (GeneralVertexToPixel)0; Output.position = mul(IN.position, coreWorldViewProj); Output.texCoords = IN.texCoords; // Pass red to fragment shader based on height Output.color.r = waveForm * boudlerRedShift; // Pass to fragShader return Output; } float4 WaterPixelShader(GeneralVertexToPixel IN) : Color { float4 Output = (float4)0; clip(IN.color.r - 0.1f); Output = tex1D(coreTextureSampler, IN.color.r); return Output; } technique WaterWave { pass Pass0 { VertexShader = compile vs_2_0 WaterVertexShader(); PixelShader = compile ps_2_0 WaterPixelShader(); FillMode = Solid; } } //---------------------------------------------------------------------------------------------------------------- // Fire Boulder Shader //---------------------------------------------------------------------------------------------------------------- GeneralVertexToPixel BoulderVertexShader(GeneralVertexInput IN) { float waveForm = 2.0f; if( true ) { // Distance between vertex and wave crest float waveDistance = abs( length(IN.position - boulderWaveRadius) ); // Height Offsetting variable // Create sharp wave... log() for rounded?? // As distance between flame and vert grows, waveForm shinks // Ensure that wave burns upward // Cos creates a circular algorithm from linear distance // See Fire Shader Notes for explanation waveForm = boulderAmplitude + sqrt(waveDistance * abs( cos( waveDistance ) ) ); // We only want protrusions, not indentions into the object float adjustment = boulderRichtor / waveForm * waveFormScaler; if(adjustment > 1.0f) { // New vertex height IN.position = IN.position + (adjustment * boulderLookVector); } } // Pack it up GeneralVertexToPixel Output = (GeneralVertexToPixel)0; Output.position = mul(IN.position, coreWorldViewProj); Output.texCoords = IN.texCoords; // Pass red to fragment shader based on height Output.color.r = waveForm * boudlerRedShift; // Pass to fragShader return Output; } float4 BoulderPixelShader(GeneralVertexToPixel IN) : Color { float4 Output = (float4)0; clip(IN.color.r - 0.1f); Output = tex1D(coreTextureSampler, IN.color.r); return Output; } technique FireBoulder { pass Pass0 { VertexShader = compile vs_2_0 BoulderVertexShader(); PixelShader = compile ps_2_0 BoulderPixelShader(); // Alpha blending AlphaBlendEnable = true; SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; FillMode = Solid; } } //------------------------------------------------------------ // Normal Boulder Shader //------------------------------------------------------------ GeneralVertexToPixel NormalBoulderTransform(GeneralVertexInput IN) { GeneralVertexToPixel Output = (GeneralVertexToPixel)0; Output.position = mul(IN.position, coreWorldViewProj); Output.texCoords = IN.texCoords; return Output; } float4 NormalBoulderPixelShader( GeneralVertexToPixel IN) : Color { float4 Output = (float4)0; Output = tex2D(coreTextureSampler, IN.texCoords); Output.rgb += boulderEnergyValue; return Output; } technique NormalBoulder { pass P0 { vertexShader = compile vs_2_0 NormalBoulderTransform(); pixelShader = compile ps_2_0 NormalBoulderPixelShader(); // Alpha blending AlphaBlendEnable = true; SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; FillMode = Solid; } } //--------------------------------------------------------------------------------------- // Character Shader //--------------------------------------------------------------------------------------- GeneralVertexToPixel CharacterVertexShader(GeneralVertexInput IN) { // Pack it up GeneralVertexToPixel Output = (GeneralVertexToPixel)0; Output.position = mul(IN.position, coreWorldViewProj); Output.texCoords = IN.texCoords; // Pass to fragShader return Output; } float4 CharacterPixelShader(GeneralVertexToPixel PSIn): Color { float4 Output = (float4)0; Output = tex2D(coreTextureSampler, PSIn.texCoords); return Output; } technique CharacterShader { pass Pass0 { VertexShader = compile vs_2_0 CharacterVertexShader(); PixelShader = compile ps_2_0 CharacterPixelShader(); FillMode = Solid; } } //-------------------------------------------------------------------------------------------------- // Core Light Shader //-------------------------------------------------------------------------------------------------- coreVertexOutput CoreVS_TransformAndTexture(coreVertexInput IN) { coreVertexOutput Output = (coreVertexOutput)0; Output.hPosition = mul(float4(IN.position.xyz , 1.0) , coreWorldViewProj); Output.texCoordDiffuse = IN.texCoordDiffuse; //calculate our vectors N, E, L, and H float3 coreWorldEyePos = coreViewInverse[3].xyz; float3 coreWorldVertPos = mul(IN.position, coreWorld).xyz; float4 N = mul(IN.normal, coreWorldInverseTranspose); //normal vector Output.norm = N; Output.Position3D = coreWorldVertPos; Output.eyePos = coreWorldEyePos; //coreLight = L; //halfvec = H; return Output; } float4 CorePS_Textured(coreVertexOutput IN) : Color { //calculate the diffuse and specular contributions float3 E = normalize(IN.eyePos - IN.Position3D); //eye vector float3 H0 = normalize(E + -float3(coreLight0[0][0], coreLight0[0][1], coreLight0[0][2])); //half angle vector float diff0 = max(0, dot(normalize(IN.norm), normalize(-float3(coreLight0[0][0], coreLight0[0][1], coreLight0[0][2])))); float spec0 = pow(max(0, dot(normalize(IN.norm), H0)), coreShininess); if( diff0 <= .0 ) { spec0 = 0; } float3 H1 = normalize(E + -float3(coreLight1[0][0], coreLight1[0][1], coreLight1[0][2])); //half angle vector float diff1 = max(0, dot(normalize(IN.norm), normalize(-float3(coreLight1[0][0], coreLight1[0][1], coreLight1[0][2])))); float spec1 = pow(max(0, dot(normalize(IN.norm), H1)), coreShininess ); if( diff1 <= .0 ) { spec1 = 0; } //output diffuse float4 ambColor = coreMaterialDiffuse * float4(coreLight0[1][0], coreLight0[1][1], coreLight0[1][2], 0) + coreMaterialDiffuse * float4(coreLight1[1][0], coreLight1[1][1], coreLight1[1][2], 0); float4 diffColor = coreMaterialDiffuse * diff0 * float4(coreLight0[2][0], coreLight0[2][1], coreLight0[2][2], 0) + coreMaterialDiffuse * diff1 * float4(coreLight1[2][0], coreLight1[2][1], coreLight1[2][2], 0); //output specular float4 specColor = coreMaterialSpecular * float4(coreLight0[3][0], coreLight0[3][1], coreLight0[3][2], 0) * spec0 + coreMaterialSpecular * float4(coreLight1[3][0], coreLight1[3][1], coreLight1[3][2], 0) * spec1; float4 coreDiffuseTexture = tex2D(coreTextureSampler, IN.texCoordDiffuse); float4 diffAmbColor = (diffColor * coreDiffuseTexture) + ambColor * coreDiffuseTexture; return ((diffAmbColor) + specColor); } technique coreTextured { pass p0 { VertexShader = compile vs_2_0 CoreVS_TransformAndTexture(); PixelShader = compile ps_2_0 CorePS_Textured(); } }