#include "VertexShader.h" ;------------------------------------------------------------------------------ ; Vertex shader for zsprite ;------------------------------------------------------------------------------ #define C_VIEWPROJ c10 #define C_OT2 c14 #define C_OT3 c15 #define C_CAMERA c17 #define C_RADIUS c18 #define C_ZMAX c19 #define C_WORLD c20 #define C_BILLBOARD_X c24 #define C_BILLBOARD_Y c25 ;------------------------------------------------------------------------------ ;custom inputs ;c[10,13] - view*proj matrix ;c14 - Stage 2 texture coords (ZScale, 0, ZBias) ;c15 - Stage 3 texture coords (0, 0, 1) ;c17 - Camera position ;c18 - World radius of sprite (default: 50.0) ;c19 - D3DZ_MAX ;c[20,23] - world matrix ;------------------------------------------------------------------------------ ;Step 1: Transform the vertex by the World * View * Projection matrix m4x4 r0,vPos,C_PROJECTION_MATRIX ; Add in the appropriate billboard vectors ; Store a copy of the transformed position in R4 ; (These are already transformed into projection space) mad r0, vScale.x, C_BILLBOARD_X, r0 mad r4, vScale.y, C_BILLBOARD_Y, r0 mov OPOS,r4 FIXUP_OPOS ;Step 2: Set up initial texture coords from constants & vertex stream mov oT0, vTexCoords mov oT1, vTexCoords ;For stages 2 and 3, we just copy the constants over mov oT2, C_OT2 mov oT3, C_OT3 ;Propagate the color mov oD0, C_MATERIAL_COLOR ;Step 3: Calculate stage 2 texture coords ;We need to calculate the Scale factor for T2, because the lookup from the ;depth texture will get transformed to [0, 1]. The second coordinate is used ;to scale those depth values out to the appropriate values in our depth ;buffer. We calculate this by taking the world coordinates of the center of ;the explosion (c7) and the world coordinates of the near edge of the ;explosion (c8), and transforming them by our view and projection transforms ;(c10-13). We then project the resultant vectors back into w=1 before ;calculating the distance between them. Finally, we take that value and ;multiply by D3DZ_MAX for the appropriate depth buffer format, so that we ;end up with values in the appropriate range ;Transform and project vertex (already done above in r4) ;then project to w=1 rcp r2,r4.w mul r0,r4,r2 ; Hack near edge by pushing the vertex position towards the camera by a ; distance equal to the sprite's world radius ; This will give us a little distortion, but that's ok for the moment ; transform vpos to world space m4x4 r9, vPos, C_WORLD ; this is identity unless the emitter is flagged as relative ; Find camera vector and normalize ; Subtract camera position from vertex position in world space sub r5,r9,C_CAMERA ; normalize dp3 r8, r5, r5 rsq r6, r8.w mul r5, r5, r6 ; Push towards camera mad r5, r5, C_RADIUS, r9 ; Transform and project near edge of explosion (c8) m4x4 r1,r5,C_VIEWPROJ ; Project to w=1 rcp r2,r1.w mul r1,r1,r2 ; Subtract vectors and calculate length into r1 sub r0,r0,r1 dp3 r2,r0,r0 rsq r3,r2.w rcp r1,r3.w ; Multiply length by D3DZ_MAX for scale ; Negate or not depending on whether we want ; to push forward or back (this should coordinate ; with the texture), and whether our ; reference point will be the original vertex ; or the near vertex mul oT2.x,r1,C_ZMAX ; The pixel shader debugger seems to bound this ; to 0.0-1.0, so try giving it a value in that range ;mov oT2.x,r1 ; Still not working (values are ~60) ; Try dividing by ZMAX? ;rcp r2, C_ZMAX ;mul oT2.x,r1,r2 ; Calculate transformed Z - this is the Zbias component of ; oT2, which represents the depth of the near edge of the ; explosion, in the depth buffer format. We take the transformed ; vertex from above, project into w=1, and scale by D3DZ_MAX rcp r1,r4.w mul r1,r1,r4.z ;TMP - zero the zbias mov oT2.z, C_ZERO.z ; mul oT2.z,r1,C_ZMAX