SubD11_SmoothPS.hlsl 8.4 KB

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