// SPDX-License-Identifier: (Not available for this version, you are only allowed to use this software if you have express permission from the copyright holder and agreed to the latest NiloToonURP EULA) // Copyright (c) 2021 Kuroneko ShaderLab Limited // For more information, visit -> https://github.com/ColinLeung-NiloCat/UnityURPToonLitShaderExample // #pragma once is a safe guard best practice in almost every .hlsl, // doing this can make sure your .hlsl's user can include this .hlsl anywhere anytime without producing any multi include conflict #pragma once // here TS = Tangent space, not TargetSpace float3 ConvertNormalTSToNormalTargetSpace(float3 normalTS, float3 tangentTargetSpace, float3 bitangentTargetSpace, float3 normalTargetSpace) { // TBN matrix, usually when you need to convert tangent space normal to other space(target space), you will need a TBN matrix of that target space float3x3 TBNMatrixTargetSpace = float3x3(tangentTargetSpace, bitangentTargetSpace, normalTargetSpace); // Usually 99% of the time you will see hlsl's mul() in this order // resultVector = mul(matrix, vector); // However doing the multiplication of the matrix and the vector in a different order; the matrix is transposed. // mul(matrix, vector) == mul(vector, transpose(matrix)) // mul(transpose(matrix), vector) == mul(vector, matrix) // for more information about it you can read: https://forum.unity.com/threads/mul-function-and-matrices.445266/#post-2880535 // 1.TBNMatrixTargetSpace is a rotation only 3x3 matrix // 2.The inverse of a rotation only matrix is its transpose, which is also a rotation only matrix // (https://en.wikipedia.org/wiki/Rotation_matrix) // 3.mul(A,B) is the transpose of mul(B,A) float3 resultNormalTargetSpace = mul(normalTS, TBNMatrixTargetSpace); // so this line means transform from Tangent space back to "Target space", it only works for "rotation-only" matrix return resultNormalTargetSpace; }