;________________________________________________________________________________________________ ; This shader will render a grass mesh, using 4 bones to bend the patch, making it follow the ; the ground. ; ; Written originaly for Mace ; By: Richard Lalancette ; Artech Studios Inc. ; April, 2003 ; ; 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 mov oD0, c[15].wwww ; Diffuse color = 0.125 or 32/256 mov oT0, v2 ; Texture Coordinates stage 0 mov r0, v0 ; Make a copy of our input vertex... ;________________________________________________________________________________________________ ; 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 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 ;________________________________________________________________________________________________ ; 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. ;________________________________________________________________________________________________ ; Transform the vertex position with the bones method /* */ 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 ;________________________________________________________________________________________________ ;If you want to try the grass without bone, comment out the bone transform up there ; and put his line in. ; mov r0, r2 ; Restore the Y coordinate, this will straighten the blades ;add r0.y, r0.y, v0.y add r0.y, r0.y, r4.y ; Optimised. ;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 ;________________________________________________________________________________________________ ; 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 */ ;m4x4 oPos, r11, c0 ; Book way to transform to screen space ; 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 add r0, r0, c[13] ; Now position the patch in the world.. ; This calculates the alpha, fade of the grass on distance sub r1, r0, c[16] dp3 r1, r1, r1 mul r1, r1, c[14].w sub oD0.w, c[14].z, r1.x ; 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 ;________________________________________________________________________________________________ ; Find the vertex index in the current blade ; example, if each blade has 9 vertex, this will return a number ; between 0 - 8 ;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