Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
5.5 KiB

  1. vs.1.1
  2. # DYNAMIC: "DOWATERFOG" "0..1"
  3. #include "macros.vsh"
  4. $cQuarter = "c91.x";
  5. ;------------------------------------------------------------------------------
  6. ; Constants specified by the app
  7. ; c0 = (0, 1, 2, 0.5)
  8. ; c1 = (1/2.2, 0, 0, 0)
  9. ; 2 = camera position *in world space*
  10. ; c4-c7 = modelViewProj matrix (transpose)
  11. ; c8-c11 = ViewProj matrix (transpose)
  12. ; c12-c15 = model->world matrix (transpose)
  13. ; c16 = [fogStart, fogEnd, fogRange, undefined]
  14. ; c17-c20 = model->view matrix (transpose)
  15. ;
  16. ; The ParticleSphere lighting equation is:
  17. ; A + [N dot ||L - P||] * C * r / |L - P|^2
  18. ;
  19. ; where:
  20. ; A = ambient light color
  21. ; N = particle normal (stored in the texture)
  22. ; L = directional light position
  23. ; P = point on surface
  24. ; C = directional light color
  25. ; r = directional light intensity
  26. ;
  27. ; This shader just does the |L - P| part and the pixel shader does the rest.
  28. ;
  29. ; Vertex components
  30. ; $vPos = Position
  31. ; $vSpecular = Directional light color
  32. ; $vColor = Ambient color (and alpha)
  33. ; $vTexCoord0 = Texture coordinates for normal map
  34. ; $vTexCoord0.z = Index into the light list for light info
  35. ;------------------------------------------------------------------------------
  36. ; Constant registers
  37. ;------------------------------------------------------------------------------
  38. ;------------------------------------------------------------------------------
  39. ; Vertex blending
  40. ;------------------------------------------------------------------------------
  41. &AllocateRegister( \$projPos );
  42. ; Transform position from object to projection space
  43. dp4 $projPos.x, $vPos, $cModelViewProj0
  44. dp4 $projPos.y, $vPos, $cModelViewProj1
  45. dp4 $projPos.z, $vPos, $cModelViewProj2
  46. dp4 $projPos.w, $vPos, $cModelViewProj3
  47. mov oPos, $projPos
  48. ;------------------------------------------------------------------------------
  49. ; Fog
  50. ;------------------------------------------------------------------------------
  51. alloc $worldPos
  52. if( $DOWATERFOG == 1 )
  53. {
  54. ; Get the worldpos z component only since that's all we need for height fog
  55. dp4 $worldPos.z, $vPos, $cModel2
  56. }
  57. &CalcFog( $worldPos, $projPos );
  58. free $worldPos
  59. &FreeRegister( \$projPos );
  60. ;------------------------------------------------------------------------------
  61. ; Setup to index our directional light.
  62. ;------------------------------------------------------------------------------
  63. mov a0.x, $vTexCoord0.z
  64. ;------------------------------------------------------------------------------
  65. ; Copy texcoords for the normal map texture
  66. ;------------------------------------------------------------------------------
  67. mov oT0, $vTexCoord0
  68. mov oT2.xyz, $vColor
  69. ; FIXME : the rest of this needs to use AllocateRegister
  70. ;------------------------------------------------------------------------------
  71. ; Generate a tangent space and rotate L.
  72. ; This can be thought of as rotating the normal map to face the viewer.
  73. ;
  74. ; This is useful when a particle is way off to the side of the screen.
  75. ; You should be looking at the half-sphere with a normal pointing from the
  76. ; particle to the viewer. Instead, you're looking at the half-sphere with
  77. ; a normal along Z. This tangent space builder code fixes the problem.
  78. ;
  79. ; Note that since the model and view matrices are identity, the coordinate
  80. ; system has X=right, Y=up, and Z=behind you (negative Z goes into the screen).
  81. ;------------------------------------------------------------------------------
  82. ; r5 (forward) = normalized P
  83. dp3 r1, $vPos, $vPos
  84. rsq r5, r1
  85. mul r5, r5, $vPos
  86. mov r5.z, -r5.z ; This basis wants Z positive going into the screen
  87. ; so flip it here.
  88. ; r1 (up) = r5 x c24
  89. mul r1, r5.xzyw, $SHADER_SPECIFIC_CONST_0; (This effectively does a cross product with [1,0,0,0]
  90. ; You wind up with [0, r5.z, -r5.y, 1]
  91. dp3 r2, r1, r1
  92. rsq r2, r2
  93. mul r1, r1, r2
  94. ; r2 (right) = r1 x r5
  95. mul r2, r1.yzxw, r5.zxyw
  96. mad r2, -r1.zxyw, r5.yzxw, r2
  97. sub r3, c[45 + a0.x], $vPos ; r3 = L - P
  98. ; transposed matrix mul
  99. mul r0, r2, r3.xxxx ; x * right
  100. mad r0, r1, r3.yyyy, r0 ; + y * up
  101. mad r0, r5, r3.zzzz, r0 ; + z * forward
  102. ;------------------------------------------------------------------------------
  103. ; Put ||L - P|| into t1
  104. ;------------------------------------------------------------------------------
  105. dp3 r2, r0, r0 ; r2 = Length(L - P)^2
  106. rsq r3, r2 ; r3 = 1 / Length(L - P)
  107. mul r8, r0, r3 ; r8 = Normalize(L - P)
  108. mul r9, r8, $cQuarter ; r9 = Normalize(L - P) * 0.25
  109. add oT1, r9, c0.w ; oT1 = Normalize(L - P) * 0.25 + 0.5
  110. ;------------------------------------------------------------------------------
  111. ; Setup the diffuse light color (C * r / ||L - P||^2)
  112. ;------------------------------------------------------------------------------
  113. mul r8, c[46 + a0.x], $vSpecular ; r8 = C * r
  114. rcp r7, r2 ; r7 = 1 / Length(L - P)^2
  115. ; rescale the color if necessary
  116. mul r8, r8, r7 ; r8 = C * r / Length(L - P)^2
  117. ; We're doing both parts of an if statement here, with each part scaled by 0 or 1.
  118. mul r9, r7, c[46 + a0.x] ; r9 = r / Length(L - P)^2
  119. ; If the light intensity scales the color > 1
  120. sge r10, r9.xxxx, $cOne ; r10.x = 1 if the color's max component > 1
  121. rcp r6, r9.xxxx
  122. mul r6, r6, r10.xxxx ; r6 = 1 / max_component or [0,0,0,0] if max_component < 1
  123. mul r2, r8, r6 ; rescaled color (all zeros if no component was > 1)
  124. ; else
  125. slt r11, r9.xxxx, $cOne ; r11.x = 1 if the color's max component < 1
  126. mad oD0.xyz, r8, r11, r2 ; if it was rescaled, then r8*r11 = 0
  127. ; if not, then r8*r11 = the original color
  128. mov oD0.a, $vColor.a ; Pass in vertex alpha so the pixel shader can use it.