SubD11_SmoothPS.hlsl 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
  2. // CHECK: sample
  3. // CHECK: dot3
  4. // CHECK: dot3
  5. // CHECK: dot3
  6. // CHECK: Rsqrt
  7. // CHECK: sample
  8. // CHECK: sample
  9. // CHECK: Log
  10. // CHECK: Exp
  11. // CHECK: Rsqrt
  12. // CHECK: dot3
  13. // CHECK: Saturate
  14. // CHECK: storeOutput
  15. //--------------------------------------------------------------------------------------
  16. // File: SubD11.hlsl
  17. //
  18. // This file contains functions to convert from a Catmull-Clark subdivision
  19. // representation to a bicubic patch representation.
  20. //
  21. // Copyright (c) Microsoft Corporation. All rights reserved.
  22. //--------------------------------------------------------------------------------------
  23. //--------------------------------------------------------------------------------------
  24. // A sample extraordinary SubD quad is represented by the following diagram:
  25. //
  26. // 15 Valences:
  27. // / \ Vertex 0: 5
  28. // / 14 Vertex 1: 4
  29. // 17---------16 / \ Vertex 2: 5
  30. // | \ | / \ Vertex 3: 3
  31. // | \ | / 13
  32. // | \ |/ / Prefixes:
  33. // | 3------2------12 Vertex 0: 9
  34. // | | | | Vertex 1: 12
  35. // | | | | Vertex 2: 16
  36. // 4----0------1------11 Vertex 3: 18
  37. // / /| | |
  38. // / / | | |
  39. // 5 / 8------9------10
  40. // \ / /
  41. // 6 /
  42. // \ /
  43. // 7
  44. //
  45. // Where the quad bounded by vertices 0,1,2,3 represents the actual subd surface of interest
  46. // The 1-ring neighborhood of the quad is represented by vertices 4 through 17. The counter-
  47. // clockwise winding of this 1-ring neighborhood is important, especially when it comes to compute
  48. // the corner vertices of the bicubic patch that we will use to approximate the subd quad (0,1,2,3).
  49. //
  50. // The resulting bicubic patch fits within the subd quad (0,1,2,3) and has the following control
  51. // point layout:
  52. //
  53. // 12--13--14--15
  54. // 8---9--10--11
  55. // 4---5---6---7
  56. // 0---1---2---3
  57. //
  58. // The inner 4 control points of the bicubic patch are a combination of only the vertices (0,1,2,3)
  59. // of the subd quad. However, the corner control points for the bicubic patch (0,3,15,12) are actually
  60. // a much more complex weighting of the subd patch and the 1-ring neighborhood. In the example above
  61. // the bicubic control point 0 is actually a weighted combination of subd points 0,1,2,3 and 1-ring
  62. // neighborhood points 17, 4, 5, 6, 7, 8, and 9. We can see that the 1-ring neighbor hood is simply
  63. // walked from the prefix value from the previous corner (corner 3 in this case) to the prefix
  64. // prefix value for the current corner. We add one more vertex on either side of the prefix values
  65. // and we have all the data necessary to calculate the value for the corner points.
  66. //
  67. // The edge control points of the bicubic patch (1,2,13,14,4,8,7,11) are also combinations of their
  68. // neighbors, but fortunately each one is only a combination of 6 values and no walk is required.
  69. //--------------------------------------------------------------------------------------
  70. #define MOD4(x) ((x)&3)
  71. #ifndef MAX_POINTS
  72. #define MAX_POINTS 32
  73. #endif
  74. #define MAX_BONE_MATRICES 80
  75. //--------------------------------------------------------------------------------------
  76. // Textures
  77. //--------------------------------------------------------------------------------------
  78. Texture2D g_txHeight : register( t0 ); // Height and Bump texture
  79. Texture2D g_txDiffuse : register( t1 ); // Diffuse texture
  80. Texture2D g_txSpecular : register( t2 ); // Specular texture
  81. //--------------------------------------------------------------------------------------
  82. // Samplers
  83. //--------------------------------------------------------------------------------------
  84. SamplerState g_samLinear : register( s0 );
  85. SamplerState g_samPoint : register( s0 );
  86. //--------------------------------------------------------------------------------------
  87. // Constant Buffers
  88. //--------------------------------------------------------------------------------------
  89. cbuffer cbTangentStencilConstants : register( b0 )
  90. {
  91. float g_TanM[1024]; // Tangent patch stencils precomputed by the application
  92. float g_fCi[16]; // Valence coefficients precomputed by the application
  93. };
  94. cbuffer cbPerMesh : register( b1 )
  95. {
  96. matrix g_mConstBoneWorld[MAX_BONE_MATRICES];
  97. };
  98. cbuffer cbPerFrame : register( b2 )
  99. {
  100. matrix g_mViewProjection;
  101. float3 g_vCameraPosWorld;
  102. float g_fTessellationFactor;
  103. float g_fDisplacementHeight;
  104. float3 g_vSolidColor;
  105. };
  106. cbuffer cbPerSubset : register( b3 )
  107. {
  108. int g_iPatchStartIndex;
  109. }
  110. //--------------------------------------------------------------------------------------
  111. Buffer<uint4> g_ValencePrefixBuffer : register( t0 );
  112. //--------------------------------------------------------------------------------------
  113. struct VS_CONTROL_POINT_OUTPUT
  114. {
  115. float3 vPosition : WORLDPOS;
  116. float2 vUV : TEXCOORD0;
  117. float3 vTangent : TANGENT;
  118. };
  119. struct BEZIER_CONTROL_POINT
  120. {
  121. float3 vPosition : BEZIERPOS;
  122. };
  123. struct PS_INPUT
  124. {
  125. float3 vWorldPos : POSITION;
  126. float3 vNormal : NORMAL;
  127. float2 vUV : TEXCOORD;
  128. float3 vTangent : TANGENT;
  129. float3 vBiTangent : BITANGENT;
  130. };
  131. //--------------------------------------------------------------------------------------
  132. // Smooth shading pixel shader section
  133. //--------------------------------------------------------------------------------------
  134. float3 safe_normalize( float3 vInput )
  135. {
  136. float len2 = dot( vInput, vInput );
  137. if( len2 > 0 )
  138. {
  139. return vInput * rsqrt( len2 );
  140. }
  141. return vInput;
  142. }
  143. static const float g_fSpecularExponent = 32.0f;
  144. static const float g_fSpecularIntensity = 0.6f;
  145. static const float g_fNormalMapIntensity = 1.5f;
  146. float2 ComputeDirectionalLight( float3 vWorldPos, float3 vWorldNormal, float3 vDirLightDir )
  147. {
  148. // Result.x is diffuse illumination, Result.y is specular illumination
  149. float2 Result = float2( 0, 0 );
  150. Result.x = pow( saturate( dot( vWorldNormal, -vDirLightDir ) ), 2 );
  151. float3 vPointToCamera = normalize( g_vCameraPosWorld - vWorldPos );
  152. float3 vHalfAngle = normalize( vPointToCamera - vDirLightDir );
  153. Result.y = pow( saturate( dot( vHalfAngle, vWorldNormal ) ), g_fSpecularExponent );
  154. return Result;
  155. }
  156. float3 ColorGamma( float3 Input )
  157. {
  158. return pow( Input, 2.2f );
  159. }
  160. float4 main( PS_INPUT Input ) : SV_TARGET
  161. {
  162. float4 vNormalMapSampleRaw = g_txHeight.Sample( g_samLinear, Input.vUV );
  163. float3 vNormalMapSampleBiased = ( vNormalMapSampleRaw.xyz * 2 ) - 1;
  164. vNormalMapSampleBiased.xy *= g_fNormalMapIntensity;
  165. float3 vNormalMapSample = normalize( vNormalMapSampleBiased );
  166. float3 vNormal = safe_normalize( Input.vNormal ) * vNormalMapSample.z;
  167. vNormal += safe_normalize( Input.vTangent ) * vNormalMapSample.x;
  168. vNormal += safe_normalize( Input.vBiTangent ) * vNormalMapSample.y;
  169. //float3 vColor = float3( 1, 1, 1 );
  170. float3 vColor = g_txDiffuse.Sample( g_samLinear, Input.vUV ).rgb;
  171. float vSpecular = g_txSpecular.Sample( g_samLinear, Input.vUV ).r * g_fSpecularIntensity;
  172. const float3 DirLightDirections[4] =
  173. {
  174. // key light
  175. normalize( float3( -63.345150, -58.043934, 27.785097 ) ),
  176. // fill light
  177. normalize( float3( 23.652107, -17.391443, 54.972504 ) ),
  178. // back light 1
  179. normalize( float3( 20.470509, -22.939510, -33.929531 ) ),
  180. // back light 2
  181. normalize( float3( -31.003685, 24.242104, -41.352859 ) ),
  182. };
  183. const float3 DirLightColors[4] =
  184. {
  185. // key light
  186. ColorGamma( float3( 1.0f, 0.964f, 0.706f ) * 1.0f ),
  187. // fill light
  188. ColorGamma( float3( 0.446f, 0.641f, 1.0f ) * 1.0f ),
  189. // back light 1
  190. ColorGamma( float3( 1.0f, 0.862f, 0.419f ) * 1.0f ),
  191. // back light 2
  192. ColorGamma( float3( 0.405f, 0.630f, 1.0f ) * 1.0f ),
  193. };
  194. float3 fLightColor = 0;
  195. for( int i = 0; i < 4; ++i )
  196. {
  197. float2 LightDiffuseSpecular = ComputeDirectionalLight( Input.vWorldPos, vNormal, DirLightDirections[i] );
  198. fLightColor += DirLightColors[i] * vColor * LightDiffuseSpecular.x;
  199. fLightColor += DirLightColors[i] * LightDiffuseSpecular.y * vSpecular;
  200. }
  201. return float4( fLightColor, 1 );
  202. }