/*________________________________________________________________________________________________ This shader will render a grass mesh, using 4 bones to bend the patch, making it follow the the ground. Special thanks to Dave E. for his assistance. Written originaly for Mace By: Richard Lalancette Artech Studios Inc. April, 2003. Last modified September, 2004. r0 will contain the temporary vertex position during the shader processing. r1, r2 will be used as a temporary registers */ vs.1.1 // version instruction //________________________________________________________________________________________________ // COLOR TINTING // This is to tint the color in the vertex based on a palette. //__________ // Version 0 // Old way to color the vertex... mov oD0, c[15].wwww // Diffuse color = 0.125 or 32/256 //__________ // Version 1 //mul r2.x, v0.x, c[14].x //mul r2.x, v0.z, r2.x //mov a0.x, r2.x //mov r3, c[a0.x+31] //mul oD0, r3, c[15].w //__________ // Version 2 // add r2.x, v0.x, c[13].x // add the vertex position and the patch position // mul r2.x, r2.x, c[14].x // multiplied by 10, divided by terrain width // mov a0.x, r2.x // mov r3, c[a0.x+31] // mul oD0, r3, c[15].w //________________________________________________________________________________________________ // MISC. PROCESSING... mov oT0, v2 // Texture Coordinates stage 0 mov r0, v0 // Make a copy of our input vertex... //________________________________________________________________________________________________ // HEIGHT SCALING // Scale the patch using the height in each corner and the weight from the bones. mul r1, r0.yyyy, v1.zyxw mul r3.y, r1.x, c[30].z mad r3.y, r1.y, c[30].w, r3.y mad r3.y, r1.z, c[30].y, r3.y mad r0.y, r1.w, c[30].x, r3.y //________________________________________________________________________________________________ // FLATENING in preparation to bending... // Start by removing the Y from the input vertex before doing the transform // Later, we will be adding the Y back to move the grass straight up. //mov r2, v0 // Copy our input vertex... mov r2, r0 // Copy our input vertex... mov r4, r0 // Copy our input vertex... mov r2.y, c[4].y // ...and remove the Y by putting 0 in it. //________________________________________________________________________________________________ // BENDING // Transform the vertex position with the bones method // If you want grass without bones, comment out the bone transform // and put this line in : mov r0, r2 dp4 r1.x, r2, c[42] dp4 r1.y, r2, c[43] dp4 r1.z, r2, c[44] dp4 r1.w, r2, c[45] mul r0, r1, v1.z dp4 r1.x, r2, c[46] dp4 r1.y, r2, c[47] dp4 r1.z, r2, c[48] dp4 r1.w, r2, c[49] mad r0, r1, v1.y, r0 dp4 r1.x, r2, c[50] dp4 r1.y, r2, c[51] dp4 r1.z, r2, c[52] dp4 r1.w, r2, c[53] mad r0, r1, v1.x, r0 dp4 r1.x, r2, c[54] dp4 r1.y, r2, c[55] dp4 r1.z, r2, c[56] dp4 r1.w, r2, c[57] mad r0, r1, v1.w, r0 //________________________________________________________________________________________________ // WIND/WAVING // add bit of movement to simulate wind... // This multiply the sin by the 2d vector indicating the wave direction in each vertex. // Trying to find a way so higher the vertex is, the more important the wave is... //__________ // Version 1 //mad r0.xz, v3.xy, c[4].xx, r0.xz //__________ // Version 2 //mul r1.xz, v3.xy, c[4].xx //mad r0.xz, r1.xz, c[30], r0.xz //__________ // Version 3 // By Dave E. //sub r0.w, c0.z, v3.x //mul r0.xyz, c%d.xyz, r0.www // totalwind = wind * 1-spec //mad r0.xyz, c%d.xyz, v3.xxx, r0.xyz // totalwind += wind2 * spec //mad r4.xyz, v2.www, r0.xyz, r4.xyz // pos += totalwind * alpha sub r5.w, c17.x, v3.y mul r5.xyz, c21.xyz, r5.www // totalwind = wind * 1-spec mad r5.xyz, c22.xyz, v3.yyy, r5.xyz // totalwind += wind2 * spec mad r0.xyz, v3.xxx, r5.xyz, r0.xyz // pos += totalwind * alpha //________________________________________________________________________________________________ // Restore the Y coordinate, this will straighten the blades back up // add r0.y, r0.y, v0.y add r0.y, r0.y, r4.y //________________________________________________________________________________________________ // POSITIONING IN WORLD // Now add the patch position to the vertex...brings the vertex in world space... add r0, r0, c[13] //________________________________________________________________________________________________ // DISTANCE FADING // This calculates the alpha, fade of the grass on distance // From Ernest's code. sub r1, r0, c[16] dp3 r1, r1, r1 mul r1, r1, c[14].w sub oD0.w, c[14].z, r1.x //________________________________________________________________________________________________ // TERRAIN LIGHTMAP LIGHTING // Generating uv's for the lightmap stage. mul r1, r0.xyz, c[15].yyy sub r1.z, -c[15].z, r1.z mov oT1.xy, r1.xz // Texture Coordinates stage 1, Lightmap /////////////////////////////////////////////////////////////// // APPLY DEPTH-FOG // Input: c19.y = Fog start Y // c19.z = 1.0f / (fogEndY - fogStartY) // r0 = Vertex position // c2 = Current View Z vector // c17 = 1,1,1 // c18 = 0,0,0 // // Output: r11.x = 1 if completely fogged, 0 if not fogged /////////////////////////////////////////////////////////////// dp4 r11.x, r0, c[2] // Get the current depth of this vertex sub r1.x, r11.x, c19.y // r1.x = (vertex.y - fogStart) mul r11.x, r1.x, c19.z // r2.x = (vertex.y - fogStart) / (fogEnd - fogStart) max r11.x, r11.x, c18.x // Clamp fog at 0. We have to do this here, as a negative value might wipe out other types of fog /////////////////////////////////////////////////////////////// // APPLY HEIGHT-FOG // Input: c20.y = Fog start Y // c20.z = 1.0f / (fogEndY - fogStartY) // r0 = Vertex position // c17 = 1,1,1 // c18 = 0,0,0 // // Output: r2.x = 1 if completely fogged, 0 if not fogged /////////////////////////////////////////////////////////////// sub r1.x, r0.y, c20.y // r1.x = (vertex.y - fogStart) mul r2.x, r1.x, c20.z // r2.x = (vertex.y - fogStart) / (fogEnd - fogStart) max r2.x, r2.x, c18.x // Clamp fog at 0. We have to do this here, as a negative value might wipe out other types of fog /////////////////////////////////////////////////////////////// // COMBINE FOGS // This is done by simply adding the various types of fogs // Input: r2.x = Height fog. 1 if completely fogged, 0 if not fogged // r11.x = Depth fog. 1 if completely fogged, 0 if not fogged // c17 = 1,1,1 // c18 = 0,0,0 // // Output: oFog.x = 1 if completely fogged, 0 if not fogged /////////////////////////////////////////////////////////////// add r2.x, r2.x, r11.x // Add the fogs max r2.x, r2.x, c18.x // Clamp fog at 0 min r2.x, r2.x, c17.x // Clamp fog at 1 //mul r2.x, r2.x, c11.x sub oFog.x, c17.x, r2.x // Fog = 1 - r2 (so 0 is completely fogged, 1 is not fogged) //________________________________________________________________________________________________ // WORLDVIEWPROJ XFORM dp4 oPos.x, r0, c[0] ; Matrix multiply row 0 dp4 oPos.y, r0, c[1] ; Matrix multiply row 1 dp4 oPos.z, r0, c[2] ; Matrix multiply row 2 dp4 oPos.w, r0, c[3] ; Matrix multiply row 3 // END OF SHADER INSTRUCTIONS //************************************************************************************************ //________________________________________________________________________________________________ // The rest below is reference code used or that could be used in the futur. //________________________________________________________________________________________________ // Find the vertex index in the current blade // example, if each blade has 9 vertex, this will return a number // between 0 - 8 // c[14].xy was used for something else, will need to be remapped. //mov r5.x, v5.x ; Get the index it's from 0 to Number of Vert in the mesh //mov r2.xy, c[14].xy ; Get the factor which should be something like 1.0f/9.0f, if 9 vertex per blade //mul r3.x, r5.x, r2.x ; divide //frc r4.xy,r3.x ; Find the fractionnal part //mul r4.x,r4.x,r2.y ; convert fraction back to a number between 0 - 8 //mov a0.x,r4.x ; use the result as an index to find the height //mov r4, c[a0.x + 15] ; 15 is where the heights are stored for each vertex of a blade //add r0.y, r0.y, r4.y //________________________________________________________________________________________________ // mov r1.w, c0.z ; T is in c0.z // mul r1.w, r1.w, v0.x ; sigma // expp r2.y, r1.w ; fractional time is in r2 // sub r1.w, r1.w, r2.y ; a unit pseudo-random number is in r1.w //________________________________________________________________________________________________ // Wave the grass adapted from the book: Direct3d ShaderX, Vertex and pixel shaders, page 334. // // pos + sumOverI(wavedirI * texcoordy * sin( xdirI * (xpos+time)) + ydirI * (ypos+time))) // THIS IS NOT COMPLETED YET. /* mul r3, c24, r0.x ; use vertex pos x as inputs to sinusoidal warp mad r3, c25, r0.yv, r3 ; use vertex pos y as inputs to sinusoidal warp mov r1, c18.x ; get current time mad r3, r1, c26, r3 ; add scaled time to move bumps according to speed frc r3.xy, r3 ; take frac of all 4 components frc r1.xy, r3.zwzw ; mov r3.zw, r1.xyxy ; mul r3, r3, c20.x ; multiply by fixup factor (due to inaccuracy of taylor series) sub r3, r3, c17.y ; subtract 0.5 mul r1, r3, c27.w ; *=2pi coords range from(-pi to pi) mul r2, r1, r1 ; (wave vec)^2 mul r3, r2, r1 ; (wave vec)^3 mul r5, r3, r2 ; (wave vec)^5 mul r7, r5, r2 ; (wave vec)^7 mul r9, r7, r2 ; (wave vec)^9 mad r3, r3, c19.x, r1 ;(wave vec) - ((wave vec)^3)/3! mad r3, r5, c19.y, r3 ; + ((wave vec)^5)/5! mad r3, r7, c19.z, r3 ; - ((wave vec)^7)/7! mad r3, r9, c19.w, r3 ; - ((wave vec)^9)/9! dp4 r3.x, r3, c21 dp4 r3.y, r3, c22 dp4 r3.zw, r3, c23 sub r4, c17.z, v2.y mul r4, r4, r4 mul r3, r3, r4 ; attenuate sinusoidal warping by (1-tex0.y)^2 mov r2.w, v0 add r2.xyz, r3, v0 ; add sinusoidal warping to grass position ;mov r0.w, v0 ;add r0.xyz, r3, r0 ; add sinusoidal warping to grass position // COLORING here, not sure i want this part yet //dp4 r10.x, r8, c28 ; scale and add sine waves together //mad oD0, c29.xzxz, -r10.x, c29.y ; scale and bias color values (green is scaled more than red and blue) //mov oT0, v7 */ //________________________________________________________________________________________________ // scale the patch using the height in each corner and the weight from the bones. // Old method // mul r1.y, r0.y, v1.z // mul r3.y, r1.y, c[30].z // mul r1.y, r0.y, v1.y // mad r3.y, r1.y, c[30].w, r3.y // mul r1.y, r0.y, v1.x // mad r3.y, r1.y, c[30].y, r3.y // mul r1.y, r0.y, v1.w // mad r3.y, r1.y, c[30].x, r3.y // mov r0.y, r3.y