// $Revision$ $Author$ $DateTime$ //------------------------------------------------------------------------------------------------ // // ***************** FIRAXIS GAME ENGINE ******************** // // FILE: VSTerrain_Base_11.vsh // // AUTHOR: Bart Muzzin - 19/03/2004 // // PURPOSE: This is base file for all terrain vertex shaders. It basically does everything, // but several constants must be defined before this file is included by a terrain shader. // //------------------------------------------------------------------------------------------------ // Copyright (c) 2004 Firaxis Games, Inc. All rights reserved. //------------------------------------------------------------------------------------------------ // We are assuming the following: // // Constant Registers: // // Name Reg Size // --------------- ----- ---- // mtxProj c0 4 // mtxWorldView c4 4 // f3FogValues c8 1 // f4FogColor c9 1 // f4LightDir c10 1 // f3LightColor c11 1 // f4AmbientColor c12 1 // f3FogCenter c13 1 // f4C14 c14 1 = { 1.0f, 0.0f, 2.0f, 0.5f } (constant) ( universial one and zero ) // f4LandscapeParams c18 1 // .xy = Texture offset, .z = Texture scaling, .w = Landscape Z scaling modifier // f4LandscapeValues c19 1 // .x = # units per vert [4 = 256/64], .y = [max height (256)], .z = XY scaling, .w = Z scaling // f4C20 c20 1 = { 255, 1/255, 252, 1/252 } (constant) ( 255/252 and their reciprocals ) // Defines: // ALPHA_REG = v4 | v5 depending on the pass, starting with v4 for pass 0. // COLOR_REG = dcl_color1 | dcl_color2 depending on the pass, starting with dcl_color1. // TEXTURE_1 = This shader uses texture #1 // TEXTURE_2 = This shader uses texture #2 // TEXTURE_3 = This shader uses texture #3 // TEXTURE_4 = This shader uses texture #4 // Note: TEXTURE_X should be defined sequentially (ie don't define TEXTURE_2 and not TEXTURE_1, etc.) dcl_position v0 dcl_normal v1 COLOR_REG ALPHA_REG // See files that include this file for what this actually is. (ie VSTerrain_2BP1_11.vsh). // The following instructions multiply the input position by the world matrix mul r3.xy, v0.xy, c19.z // 1 // r3.xy = (pos.xy * 255) * xy_scaling mov r3.y, -r3.y // 1 // r3.y = -(pos.y * 255) * xy_scaling (negate y) mul r3.z, v0.z, c19.w // 1 // r3.z = (pos.z * 255) * z_scaling mul r3.z, r3.z, c18.w // 1 // Scale the world Z position by the landscape scaling factor mov r3.w, c14.x // 1 // w = 1. m4x4 r1, r3, c0 // 4 // This translates the final world position into screen space mov oPos, r1 // 1 (11) // Move the final position into the output register // Now compute lighting information mul r6, v1, c20.y // 1 // r6 = (norm.xy / 255 ) add r0, r6, -c14.w // 1 // norm = (norm.xy - 0.5) mul r0, r0, c14.z // 1 // norm = (norm.xy - 0.5) * 2.0 dp3 r11, -c10, r0 // 1 // (Light Vector) dot (Normal) (L.N) mul r11, r11, c11 // 1 // Modulate diffuse by its color add r11, r11, c12 // 1 // Add the ambient color to this value. max r11, c14.y, r11 // 1 // Clamp the minimum value to 0 min oD0.rgb, c14.x, r11 // 1 (18) // Clamp the maximum value to 1 // Write the texture registers by multiplying the input texture coordinates by the base scaling. // Note: this is kind of a fudge... I divide by 252 because I know that the terrain cell x/y values are [ 0..63 ]. // This is multiplied by 4, and then normalized. If we normalized by 255 we would get numbers in the range // [0 .. ~0.988]. We want numbers in the range [0 .. 1] (and thus we normalize by 252 instead of 255). mul r4, v0, c20.w // 1 // position.xy / 252.0f mul r0.xy, r4, c18.z // 1 // r0.xy = basescaling * position.xy / 252.0f mul r0.xy, r0.xy, c19.x // 1 // multiply the texture coordinates by the number of verts per range. add r0.xy, r0.xy, c18.xy // 1 (21) // Add the texture offset // Fogging calculations mul r6.w, r1.z, c8.x // 1 // sqrt( (WP - FC) dot (WP - FC) ) / (Far plane distance) = Fogging, [0..1] add r2, r6.w, -c8.y // 1 // ( Fogging - MinFogValue ) mul r2, r2, c8.z // 1 // ( Fogging - MinFogValue ) / ( 1 - MinFogValue ) sge r3, r6.w, c8.y // 1 // If (Fogging >= MinFogValue ) { r3 = 1 } else { r3 = 0 } mul r3, r3.x, r2.x // 1 (26) // Set the alpha of the primitive to be the fogging value // We don't use fogging directly, it is done in a seperate pass - however, we need to reduce the levels of things that will be fogged, // because the terrain is going to be added in an additive method. add r3, c14.x, -r3 // 1 // Take the complement of the fog value mul r11, r3, ALPHA_REG // 1 // Turn down the alpha by the amount of fog at this pixel mul r11, r11, c20.y // 1 // Divide by 255 (UBYTE4 is not normalized between 0..1). // Move the alpha values into their correct registers. mov oD1, c14.y // 1 // zero out the register, in case we don't write the whole thing mov oD1.b, r3 // 1 // atotal -> oD1.b #ifdef TEXTURE_1 mov oD0.a, r11.r // 1 // ax -> oD0.a mov oT0.xy, r0.xy // 1 // texture coords -> oT0 #endif #ifdef TEXTURE_2 mov oD1.a, r11.g // 1 // ay -> oD1.a mov oT1.xy, r0.xy // 1 // texture coords -> oT1 #endif #ifdef TEXTURE_3 mov oD1.g, r11.b // 1 // az -> oD1.g mov oT2.xy, r0.xy // 1 // texture coords -> oT2 #endif #ifdef TEXTURE_4 mov oD1.r, r11.a // 1 // aw -> oD1.r mov oT3.xy, r0.xy // 1 // texture coords -> oT3 #endif // Total instructions = 31 for 1 texture, 33 for 2 textures, 35 for 3 textures, 37 for 4 textures.