暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

SpaceTransforms.hlsl 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. #ifndef UNITY_SPACE_TRANSFORMS_INCLUDED
  2. #define UNITY_SPACE_TRANSFORMS_INCLUDED
  3. #if SHADER_API_MOBILE || SHADER_API_GLES3 || SHADER_API_SWITCH || defined(UNITY_UNIFIED_SHADER_PRECISION_MODEL)
  4. #pragma warning (disable : 3205) // conversion of larger type to smaller
  5. #endif
  6. // Caution: For HDRP, adding a function in this file requires adding the appropriate #define in PickingSpaceTransforms.hlsl
  7. // Return the PreTranslated ObjectToWorld Matrix (i.e matrix with _WorldSpaceCameraPos apply to it if we use camera relative rendering)
  8. float4x4 GetObjectToWorldMatrix()
  9. {
  10. return UNITY_MATRIX_M;
  11. }
  12. float4x4 GetWorldToObjectMatrix()
  13. {
  14. return UNITY_MATRIX_I_M;
  15. }
  16. float4x4 GetPrevObjectToWorldMatrix()
  17. {
  18. return UNITY_PREV_MATRIX_M;
  19. }
  20. float4x4 GetPrevWorldToObjectMatrix()
  21. {
  22. return UNITY_PREV_MATRIX_I_M;
  23. }
  24. float4x4 GetWorldToViewMatrix()
  25. {
  26. return UNITY_MATRIX_V;
  27. }
  28. float4x4 GetViewToWorldMatrix()
  29. {
  30. return UNITY_MATRIX_I_V;
  31. }
  32. // Transform to homogenous clip space
  33. float4x4 GetWorldToHClipMatrix()
  34. {
  35. return UNITY_MATRIX_VP;
  36. }
  37. // Transform to homogenous clip space
  38. float4x4 GetViewToHClipMatrix()
  39. {
  40. return UNITY_MATRIX_P;
  41. }
  42. // This function always return the absolute position in WS
  43. float3 GetAbsolutePositionWS(float3 positionRWS)
  44. {
  45. #if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
  46. positionRWS += _WorldSpaceCameraPos.xyz;
  47. #endif
  48. return positionRWS;
  49. }
  50. // This function return the camera relative position in WS
  51. float3 GetCameraRelativePositionWS(float3 positionWS)
  52. {
  53. #if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
  54. positionWS -= _WorldSpaceCameraPos.xyz;
  55. #endif
  56. return positionWS;
  57. }
  58. real GetOddNegativeScale()
  59. {
  60. // FIXME: We should be able to just return unity_WorldTransformParams.w, but it is not
  61. // properly set at the moment, when doing ray-tracing; once this has been fixed in cpp,
  62. // we can revert back to the former implementation.
  63. return unity_WorldTransformParams.w >= 0.0 ? 1.0 : -1.0;
  64. }
  65. float3 TransformObjectToWorld(float3 positionOS)
  66. {
  67. #if defined(SHADER_STAGE_RAY_TRACING)
  68. return mul(ObjectToWorld3x4(), float4(positionOS, 1.0)).xyz;
  69. #else
  70. return mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)).xyz;
  71. #endif
  72. }
  73. float3 TransformWorldToObject(float3 positionWS)
  74. {
  75. #if defined(SHADER_STAGE_RAY_TRACING)
  76. return mul(WorldToObject3x4(), float4(positionWS, 1.0)).xyz;
  77. #else
  78. return mul(GetWorldToObjectMatrix(), float4(positionWS, 1.0)).xyz;
  79. #endif
  80. }
  81. float3 TransformWorldToView(float3 positionWS)
  82. {
  83. return mul(GetWorldToViewMatrix(), float4(positionWS, 1.0)).xyz;
  84. }
  85. float3 TransformViewToWorld(float3 positionVS)
  86. {
  87. return mul(GetViewToWorldMatrix(), float4(positionVS, 1.0)).xyz;
  88. }
  89. // Transforms position from object space to homogenous space
  90. float4 TransformObjectToHClip(float3 positionOS)
  91. {
  92. // More efficient than computing M*VP matrix product
  93. return mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)));
  94. }
  95. // Transforms position from world space to homogenous space
  96. float4 TransformWorldToHClip(float3 positionWS)
  97. {
  98. return mul(GetWorldToHClipMatrix(), float4(positionWS, 1.0));
  99. }
  100. // Transforms position from view space to homogenous space
  101. float4 TransformWViewToHClip(float3 positionVS)
  102. {
  103. return mul(GetViewToHClipMatrix(), float4(positionVS, 1.0));
  104. }
  105. // Normalize to support uniform scaling
  106. float3 TransformObjectToWorldDir(float3 dirOS, bool doNormalize = true)
  107. {
  108. #ifndef SHADER_STAGE_RAY_TRACING
  109. float3 dirWS = mul((float3x3)GetObjectToWorldMatrix(), dirOS);
  110. #else
  111. float3 dirWS = mul((float3x3)ObjectToWorld3x4(), dirOS);
  112. #endif
  113. if (doNormalize)
  114. return SafeNormalize(dirWS);
  115. return dirWS;
  116. }
  117. // Normalize to support uniform scaling
  118. float3 TransformWorldToObjectDir(float3 dirWS, bool doNormalize = true)
  119. {
  120. #ifndef SHADER_STAGE_RAY_TRACING
  121. float3 dirOS = mul((float3x3)GetWorldToObjectMatrix(), dirWS);
  122. #else
  123. float3 dirOS = mul((float3x3)WorldToObject3x4(), dirWS);
  124. #endif
  125. if (doNormalize)
  126. return normalize(dirOS);
  127. return dirOS;
  128. }
  129. // Transforms vector from world space to view space
  130. real3 TransformWorldToViewDir(real3 dirWS, bool doNormalize = false)
  131. {
  132. float3 dirVS = mul((real3x3)GetWorldToViewMatrix(), dirWS).xyz;
  133. if (doNormalize)
  134. return normalize(dirVS);
  135. return dirVS;
  136. }
  137. // Transforms vector from view space to world space
  138. real3 TransformViewToWorldDir(real3 dirVS, bool doNormalize = false)
  139. {
  140. float3 dirWS = mul((real3x3)GetViewToWorldMatrix(), dirVS).xyz;
  141. if (doNormalize)
  142. return normalize(dirWS);
  143. return dirWS;
  144. }
  145. // Transforms normal from world space to view space
  146. real3 TransformWorldToViewNormal(real3 normalWS, bool doNormalize = false)
  147. {
  148. // assuming view matrix is uniformly scaled, we can use direction transform
  149. return TransformWorldToViewDir(normalWS, doNormalize);
  150. }
  151. // Transforms normal from view space to world space
  152. real3 TransformViewToWorldNormal(real3 normalVS, bool doNormalize = false)
  153. {
  154. // assuming view matrix is uniformly scaled, we can use direction transform
  155. return TransformViewToWorldDir(normalVS, doNormalize);
  156. }
  157. // Transforms vector from world space to homogenous space
  158. real3 TransformWorldToHClipDir(real3 directionWS, bool doNormalize = false)
  159. {
  160. float3 dirHCS = mul((real3x3)GetWorldToHClipMatrix(), directionWS).xyz;
  161. if (doNormalize)
  162. return normalize(dirHCS);
  163. return dirHCS;
  164. }
  165. // Transforms normal from object to world space
  166. float3 TransformObjectToWorldNormal(float3 normalOS, bool doNormalize = true)
  167. {
  168. #ifdef UNITY_ASSUME_UNIFORM_SCALING
  169. return TransformObjectToWorldDir(normalOS, doNormalize);
  170. #else
  171. // Normal need to be multiply by inverse transpose
  172. float3 normalWS = mul(normalOS, (float3x3)GetWorldToObjectMatrix());
  173. if (doNormalize)
  174. return SafeNormalize(normalWS);
  175. return normalWS;
  176. #endif
  177. }
  178. // Transforms normal from world to object space
  179. float3 TransformWorldToObjectNormal(float3 normalWS, bool doNormalize = true)
  180. {
  181. #ifdef UNITY_ASSUME_UNIFORM_SCALING
  182. return TransformWorldToObjectDir(normalWS, doNormalize);
  183. #else
  184. // Normal need to be multiply by inverse transpose
  185. float3 normalOS = mul(normalWS, (float3x3)GetObjectToWorldMatrix());
  186. if (doNormalize)
  187. return SafeNormalize(normalOS);
  188. return normalOS;
  189. #endif
  190. }
  191. real3x3 CreateTangentToWorld(real3 normal, real3 tangent, real flipSign)
  192. {
  193. // For odd-negative scale transforms we need to flip the sign
  194. real sgn = flipSign * GetOddNegativeScale();
  195. real3 bitangent = cross(normal, tangent) * sgn;
  196. return real3x3(tangent, bitangent, normal);
  197. }
  198. // this function is intended to work on Normals (handles non-uniform scale)
  199. // tangentToWorld is the matrix representing the transformation of a normal from tangent to world space
  200. real3 TransformTangentToWorld(float3 normalTS, real3x3 tangentToWorld, bool doNormalize = false)
  201. {
  202. // Note matrix is in row major convention with left multiplication as it is build on the fly
  203. real3 result = mul(normalTS, tangentToWorld);
  204. if (doNormalize)
  205. return SafeNormalize(result);
  206. return result;
  207. }
  208. // this function is intended to work on Normals (handles non-uniform scale)
  209. // This function does the exact inverse of TransformTangentToWorld() and is
  210. // also decribed within comments in mikktspace.h and it follows implicitly
  211. // from the scalar triple product (google it).
  212. // tangentToWorld is the matrix representing the transformation of a normal from tangent to world space
  213. real3 TransformWorldToTangent(real3 normalWS, real3x3 tangentToWorld, bool doNormalize = true)
  214. {
  215. // Note matrix is in row major convention with left multiplication as it is build on the fly
  216. float3 row0 = tangentToWorld[0];
  217. float3 row1 = tangentToWorld[1];
  218. float3 row2 = tangentToWorld[2];
  219. // these are the columns of the inverse matrix but scaled by the determinant
  220. float3 col0 = cross(row1, row2);
  221. float3 col1 = cross(row2, row0);
  222. float3 col2 = cross(row0, row1);
  223. float determinant = dot(row0, col0);
  224. // inverse transposed but scaled by determinant
  225. // Will remove transpose part by using matrix as the first arg in the mul() below
  226. // this makes it the exact inverse of what TransformTangentToWorld() does.
  227. real3x3 matTBN_I_T = real3x3(col0, col1, col2);
  228. real3 result = mul(matTBN_I_T, normalWS);
  229. if (doNormalize)
  230. {
  231. float sgn = determinant < 0.0 ? (-1.0) : 1.0;
  232. return SafeNormalize(sgn * result);
  233. }
  234. else
  235. return result / determinant;
  236. }
  237. // this function is intended to work on Vectors/Directions
  238. // tangentToWorld is the matrix representing the transformation of a normal from tangent to world space
  239. real3 TransformWorldToTangentDir(real3 dirWS, real3x3 tangentToWorld, bool doNormalize = false)
  240. {
  241. // Note matrix is in row major convention with left multiplication as it is build on the fly
  242. real3 result = mul(tangentToWorld, dirWS);
  243. if (doNormalize)
  244. return SafeNormalize(result);
  245. return result;
  246. }
  247. // this function is intended to work on Vectors/Directions
  248. // This function does the exact inverse of TransformWorldToTangentDir()
  249. // tangentToWorld is the matrix representing the transformation of a normal from tangent to world space
  250. real3 TransformTangentToWorldDir(real3 dirWS, real3x3 tangentToWorld, bool doNormalize = false)
  251. {
  252. // Note matrix is in row major convention with left multiplication as it is build on the fly
  253. float3 row0 = tangentToWorld[0];
  254. float3 row1 = tangentToWorld[1];
  255. float3 row2 = tangentToWorld[2];
  256. // these are the columns of the inverse matrix but scaled by the determinant
  257. float3 col0 = cross(row1, row2);
  258. float3 col1 = cross(row2, row0);
  259. float3 col2 = cross(row0, row1);
  260. float determinant = dot(row0, col0);
  261. // inverse transposed but scaled by determinant
  262. // Will remove transpose part by using matrix as the second arg in the mul() below
  263. // this makes it the exact inverse of what TransformWorldToTangentDir() does.
  264. real3x3 matTBN_I_T = real3x3(col0, col1, col2);
  265. real3 result = mul(dirWS, matTBN_I_T);
  266. if (doNormalize)
  267. {
  268. float sgn = determinant < 0.0 ? (-1.0) : 1.0;
  269. return SafeNormalize(sgn * result);
  270. }
  271. else
  272. return result / determinant;
  273. }
  274. // tangentToWorld is the matrix representing the transformation of a normal from tangent to world space
  275. real3 TransformTangentToObject(real3 dirTS, real3x3 tangentToWorld)
  276. {
  277. // Note matrix is in row major convention with left multiplication as it is build on the fly
  278. real3 normalWS = TransformTangentToWorld(dirTS, tangentToWorld);
  279. return TransformWorldToObjectNormal(normalWS);
  280. }
  281. // tangentToWorld is the matrix representing the transformation of a normal from tangent to world space
  282. real3 TransformObjectToTangent(real3 dirOS, real3x3 tangentToWorld)
  283. {
  284. // Note matrix is in row major convention with left multiplication as it is build on the fly
  285. // don't normalize, as normalWS will be normalized after TransformWorldToTangent
  286. float3 normalWS = TransformObjectToWorldNormal(dirOS, false);
  287. // transform from world to tangent
  288. return TransformWorldToTangent(normalWS, tangentToWorld);
  289. }
  290. #if SHADER_API_MOBILE || SHADER_API_GLES3 || SHADER_API_SWITCH
  291. #pragma warning (enable : 3205) // conversion of larger type to smaller
  292. #endif
  293. #endif