hlsl.azsl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. //==============================================================================
  2. //
  3. // Filename: MizuchiBase_Common_Utility.fx
  4. //
  5. // Author: Silicon Studio Co., Ltd.
  6. // Technology Business Division - Research Group
  7. //
  8. // Description: MizuchiBase Common Utility code
  9. //
  10. //==============================================================================
  11. // Copyright (C) 2013 Silicon Studio Corporation. All rights reserved.
  12. //==============================================================================
  13. void SinCos(float rads, out float s, out float c)
  14. {
  15. sincos(rads, s, c);
  16. }
  17. float Atan2(float y, float x)
  18. {
  19. return atan2(y, x);
  20. }
  21. float3x3 m4x4To3x3( float4x4 m4 )
  22. {
  23. return ( float3x3 )( m4 );
  24. }
  25. //------------------------------------------------------------------------------
  26. float2 MaterialCalcUV(float2 texCoord, float2 scale, float2 rotate, float2 offset)
  27. {
  28. // float2( S0 * U + R0 * V + T0 ,
  29. // R1 * U + S1 * V + T1 );
  30. return float2(scale.x * texCoord.x + rotate.x * texCoord.y + offset.x,
  31. rotate.y * texCoord.x + scale.y * texCoord.y + offset.y);
  32. }
  33. float2 MATERIAL_CALC_UV_2(float2 texcoordArray[TEXCOORD_ARRAY_COUNT], float4 uvTransforms[2], uint uvSlot)
  34. {
  35. float2 texCoord = texcoordArray[min(UV_SLOT_COUNT, uvSlot)];
  36. float2 scale = float2(uvTransforms[0].x, uvTransforms[0].w);
  37. float2 rotate = float2(uvTransforms[0].z, uvTransforms[0].y);
  38. float2 offset = uvTransforms[1].xy;
  39. return MaterialCalcUV(texCoord, scale, rotate, offset);
  40. }
  41. //------------------------------------------------------------------------------
  42. //
  43. // Convert RGB to YCbCr space
  44. //
  45. //------------------------------------------------------------------------------
  46. void ConvertRGBToYCbCr( float3 rgbColor,
  47. out float3 YCbCrColor )
  48. {
  49. float Y = dot(rgbColor,float3(0.299,0.587,0.114));
  50. float Cb = dot(rgbColor,float3(-0.168,-0.331,0.5)) + 0.5;
  51. float Cr = dot(rgbColor,float3(0.5,-0.418,-0.0081)) + 0.5;
  52. YCbCrColor.r = Y;
  53. YCbCrColor.g = Cb;
  54. YCbCrColor.b = Cr;
  55. } // End of ConvertRGBToYCbCr
  56. //------------------------------------------------------------------------------
  57. //
  58. // Convert YCbCr to RGB space
  59. //
  60. //------------------------------------------------------------------------------
  61. void ConvertYCbCrToRGB( float3 YCbCrColor,
  62. out float3 rgbColor )
  63. {
  64. float Y = YCbCrColor.r;
  65. float Cb = YCbCrColor.g;
  66. float Cr = YCbCrColor.b;
  67. rgbColor.r = Y + 1.402 * (Cr-0.5);
  68. rgbColor.g = Y - 0.344 * (Cb-0.5) - 0.714 * (Cr-0.5);
  69. rgbColor.b = Y + 1.772 * (Cb-0.5);
  70. } // End of ConvertYCbCrToRGB
  71. //------------------------------------------------------------------------------
  72. //
  73. // Conver Linear Z to Normalized Z
  74. //
  75. //------------------------------------------------------------------------------
  76. float ConvertToNormalizedDepth( float linearZ )
  77. {
  78. PerSubView subView = GET_UNIFORM( PerViewCB, u_subViews )[GET_UNIFORM(PerDrawCB, u_drawView).x];
  79. float normZ = mad(linearZ,subView.projRatio.x,subView.projRatio.y)
  80. / mad(linearZ,subView.projRatio.z,subView.projRatio.w);
  81. return normZ;
  82. } // End of ConvertToNormalizedDepth
  83. //------------------------------------------------------------------------------
  84. //
  85. // Conver ZBuffer z to Linear Z
  86. //
  87. //------------------------------------------------------------------------------
  88. float ConvertToLinearDepth( float zBufferDepth )
  89. {
  90. PerSubView subView = GET_UNIFORM( PerViewCB, u_subViews )[GET_UNIFORM(PerDrawCB, u_drawView).x];
  91. float linearDepth = mad(zBufferDepth,subView.projRatio.w,-subView.projRatio.y)
  92. / mad(-zBufferDepth,subView.projRatio.z,subView.projRatio.x);
  93. return linearDepth;
  94. } // End of ConvertToLinearDepth
  95. //------------------------------------------------------------------------------
  96. //
  97. // Conver ZBuffer z to Linear Z
  98. //
  99. //------------------------------------------------------------------------------
  100. float ConvertToLinearDepth( float zBufferDepth, float4 projRatio )
  101. {
  102. float linearDepth = mad( zBufferDepth, projRatio.w,-projRatio.y)
  103. / mad(-zBufferDepth, projRatio.z, projRatio.x);
  104. return linearDepth;
  105. } // End of ConvertToLinearDepth
  106. //------------------------------------------------------------------------------
  107. //
  108. // Convert 2D coordinate to 3D view space position
  109. //
  110. // - screenPos is -1 to 1 range ( left to right,
  111. // bottomto top )
  112. //
  113. //------------------------------------------------------------------------------
  114. float3 ConvertToViewSpacePos( float2 screenPos, float linearZ )
  115. {
  116. // Revert viewport jittering
  117. PerSubView subView = GET_UNIFORM( PerViewCB, u_subViews )[GET_UNIFORM(PerDrawCB, u_drawView).x];
  118. //float2 jitterOffset = subView.zPlane.z > 0.0 ? 2.0 * subView.viewportSizeJitterOffset.zw / subView.viewportSizeJitterOffset.xy : float2(0.0, 0.0);
  119. float select = subView.zPlane.z > 0.0 ? 1.0 : 0.0;
  120. float2 jitterOffset = (2.0f * subView.viewportSizeJitterOffset.zw / subView.viewportSizeJitterOffset.xy) * select;
  121. // Map to left to right and top to bottom range
  122. float2 screenPosAtNearPlane;
  123. screenPosAtNearPlane.xy = lerp(subView.frustum.xw,subView.frustum.yz,mad(screenPos.xy-jitterOffset,0.5,0.5));
  124. // u_CubeMapFetchScaler contains scaler for RHS
  125. float3 viewSpacePos;
  126. float xyScale = subView.zPlane.z > 0.0 ? linearZ / subView.zPlane.x : -1.0;
  127. viewSpacePos.xy = screenPosAtNearPlane * subView.cubeMapFetchScaler.x * xyScale;
  128. viewSpacePos.z = linearZ;
  129. return viewSpacePos;
  130. } // End of ConvertToViewSpacePos
  131. //------------------------------------------------------------------------------
  132. //
  133. // Convert 2D coordinate to 3D view space position
  134. //
  135. // - screenPos is -1 to 1 range ( left to right,
  136. // bottomto top )
  137. //
  138. //------------------------------------------------------------------------------
  139. float3 ConvertToViewSpacePosWithoutJitterOffset( float2 screenPos, float linearZ )
  140. {
  141. // Map to left to right and top to bottom range
  142. PerSubView subView = GET_UNIFORM( PerViewCB, u_subViews )[GET_UNIFORM(PerDrawCB, u_drawView).x];
  143. float2 screenPosAtNearPlane;
  144. screenPosAtNearPlane.xy = lerp(subView.frustum.xw,subView.frustum.yz,mad(screenPos.xy,0.5,0.5));
  145. // u_CubeMapFetchScaler contains scaler for RHS
  146. float3 viewSpacePos;
  147. float xyScale = subView.zPlane.z > 0.0 ? linearZ / subView.zPlane.x : -1.0;
  148. viewSpacePos.xy = screenPosAtNearPlane * subView.cubeMapFetchScaler.x * xyScale;
  149. viewSpacePos.z = linearZ;
  150. return viewSpacePos;
  151. } // End of ConvertToViewSpacePos
  152. //------------------------------------------------------------------------------
  153. //
  154. // Calc specular AO
  155. //
  156. //------------------------------------------------------------------------------
  157. float CalcSpecularAO(float ao, float dotNV, float roughness)
  158. {
  159. float val = pow(max(dotNV + ao, 0.0), roughness) - 1.0 + ao;
  160. return SATURATE(val);
  161. }
  162. //------------------------------------------------------------------------------
  163. // Remap the clothnessLevel in [0,7] to a uniform float value in [0.0,1.0]
  164. //------------------------------------------------------------------------------
  165. float ClothnessRatio(int clothnessLevel)
  166. {
  167. return float(clothnessLevel) / 7.0;
  168. }
  169. //------------------------------------------------------------------------------
  170. // Remap shininess by clothness
  171. // To make sure that the material looks "fully cloth" with clothnessRatio = 1.0,
  172. // we fix the roughness to 0.5 if clothnessRatio is 1.0.
  173. // - finalRoughness = roughness^2 = (1 - shinness)^2 = (1-0.2929)^2 = 0.49999041
  174. //------------------------------------------------------------------------------
  175. float GetRemappedShininess(float shininess, float clothnessRatio)
  176. {
  177. return lerp(shininess, 0.2929f, clothnessRatio);
  178. }
  179. //------------------------------------------------------------------------------
  180. // Remap metallic by clothness
  181. //------------------------------------------------------------------------------
  182. float GetRemappedMetallic(float metallic, float clothnessRatio)
  183. {
  184. return lerp(metallic, metallic * 0.5 + 0.5, clothnessRatio);
  185. }
  186. float2 OctWrap(float2 v)
  187. {
  188. return (1.0 - abs(v.yx)) * float2(
  189. v.x >= 0.0 ? 1.0 : -1.0,
  190. v.y >= 0.0 ? 1.0 : -1.0);
  191. }
  192. //------------------------------------------------------------------------------
  193. // Pack Normal
  194. //------------------------------------------------------------------------------
  195. float2 PackNormal(float3 normal)
  196. {
  197. // Octahedron normal vector encoding
  198. // https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/
  199. float3 n = normal / (abs(normal.x) + abs(normal.y) + abs(normal.z));
  200. n.xy = n.z >= 0.0 ? n.xy : OctWrap(n.xy);
  201. return n.xy * 0.5 + 0.5;
  202. } // End of PackNormal
  203. //------------------------------------------------------------------------------
  204. // Unpack Normal
  205. //------------------------------------------------------------------------------
  206. float3 UnpackNormal(float2 packedNormal)
  207. {
  208. // Octahedron normal vector encoding
  209. // https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/
  210. float2 encN = packedNormal.xy * 2.0 - 1.0;
  211. float3 n;
  212. n.z = 1.0 - abs(encN.x) - abs(encN.y);
  213. n.xy = n.z >= 0.0 ? encN.xy : OctWrap(encN.xy);
  214. return normalize(n);
  215. } // End of UnpackNormal
  216. //------------------------------------------------------------------------------
  217. // Compute Jittering Offset
  218. // In SDK2, placed on Common_Jittering.fx
  219. //------------------------------------------------------------------------------
  220. float2 ComputeJitterOffset(const float4 vHgPos, const float3 WPrevPos, const float4x4 previousViewProjectionMatrix, const float4 viewportSizeJitterOffset)
  221. {
  222. float4 vHgPrevPos = MUL_VEC_MAT(float4(WPrevPos, 1.0f), previousViewProjectionMatrix);
  223. // w除算してクリップ座標系へ
  224. // Convert to clip coordinates (by dividing by w)
  225. float2 vClipPos = vHgPos.xy / vHgPos.w;
  226. float2 vClipPrevPos = vHgPrevPos.xy / vHgPrevPos.w;
  227. // スクリーン上でのベロシティ(画面端から端まで動くと1.0)
  228. // Velocity on screen (1.0 means: move from one screen side to the other)
  229. float2 vVelocity = vClipPos - vClipPrevPos;
  230. float2 vVelocityInPixels = vVelocity * viewportSizeJitterOffset.xy * 0.5f;
  231. // ピクセル単位での移動量
  232. // Velocity Length, in Pixels
  233. float fVelocityLengthInPixels = length(vVelocityInPixels);
  234. // Remap move range [0.1px ~ full stop] to [0.0 ~ 1.0] - 0.1 is an arbitrary value, but seems ok
  235. // 0.1ピクセルくらいから静止までの動きを0.0~1.0にマッピングしてクランプ - この値は適当に調整する(おそらくこの程度の値で問題ない)
  236. const float fThreshold = 0.1;
  237. float fJitterScale = SATURATE(1.0 - fVelocityLengthInPixels / fThreshold);
  238. // fJitterScale がジッタリングすべき最大ピクセルサイズを示す - fJitterScale が 1.0 の時に1ピクセル分ジッタリングさせるように出力座標にオフセット
  239. // fJitterScale is the biggest distance jitter should cover (in pixels) - if fJitterScale==1.0, we offset output coordinates in order to have a jittering of 1px
  240. float2 vJitterInPixels = viewportSizeJitterOffset.zw * fJitterScale * 20;
  241. // ピクセル単位からクリップ座標系のオフセット量へ
  242. // Convert from pixel unit to clip coordinates
  243. float2 vClipJitterOffset = float2(2, 2) * vJitterInPixels / viewportSizeJitterOffset.xy;
  244. // クリップ座標系のオフセット量から射影空間上のオフセット量へ
  245. // Convert from offset clip coordinates to projective space
  246. float2 vHgJitterOffset = vClipJitterOffset * vHgPos.w;
  247. // 出力頂点座標
  248. // output vertex coordinates
  249. return vHgJitterOffset;
  250. }