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