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

265 行
7.6 KiB

#ifndef UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED
#define UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED
// This function always return the absolute position in WS
float3 GetAbsolutePositionWS(float3 positionRWS)
{
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionRWS += _WorldSpaceCameraPos;
#endif
return positionRWS;
}
// This function return the camera relative position in WS
float3 GetCameraRelativePositionWS(float3 positionWS)
{
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS -= _WorldSpaceCameraPos;
#endif
return positionWS;
}
float4x4 GetWorldToViewMatrix()
{
return UNITY_MATRIX_V;
}
// Return absolute world position of current object
float3 GetObjectAbsolutePositionWS()
{
float4x4 modelMatrix = UNITY_MATRIX_M;
return GetAbsolutePositionWS(modelMatrix._m03_m13_m23); // Translation object to world
}
// Return the PreTranslated ObjectToWorld Matrix (i.e matrix with _WorldSpaceCameraPos apply to it if we use camera relative rendering)
float4x4 GetObjectToWorldMatrix()
{
return UNITY_MATRIX_M;
}
float4x4 GetWorldToObjectMatrix()
{
return UNITY_MATRIX_I_M;
}
// Transform to homogenous clip space
float4x4 GetViewToHClipMatrix()
{
return UNITY_MATRIX_P;
}
float4x4 GetWorldToHClipMatrix()
{
return UNITY_MATRIX_VP;
}
float GetOddNegativeScale()
{
return unity_WorldTransformParams.w;
}
float3 TransformWorldToView(float3 positionRWS)
{
return mul(GetWorldToViewMatrix(), float4(positionRWS, 1.0)).xyz;
}
float3 TransformObjectToWorld(float3 positionOS)
{
return mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)).xyz;
}
float3 TransformWorldToObject(float3 positionRWS)
{
return mul(GetWorldToObjectMatrix(), float4(positionRWS, 1.0)).xyz;
}
float3 TransformObjectToWorldDir(float3 dirOS)
{
// Normalize to support uniform scaling
return normalize(mul((float3x3)GetObjectToWorldMatrix(), dirOS));
}
float3 TransformWorldToViewDir(float3 dirWS)
{
return mul((float3x3)GetWorldToViewMatrix(), dirWS).xyz;
}
float3 TransformWorldToObjectDir(float3 dirWS)
{
// Normalize to support uniform scaling
return normalize(mul((float3x3)GetWorldToObjectMatrix(), dirWS));
}
// Transforms normal from object to world space
float3 TransformObjectToWorldNormal(float3 normalOS)
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return TransformObjectToWorldDir(normalOS);
#else
// Normal need to be multiply by inverse transpose
return normalize(mul(normalOS, (float3x3)GetWorldToObjectMatrix()));
#endif
}
// Tranforms position from world space to homogenous space
float4 TransformWorldToHClip(float3 positionRWS)
{
return mul(GetWorldToHClipMatrix(), float4(positionRWS, 1.0));
}
// Tranforms vector from world space to homogenous space
float3 TransformWorldToHClipDir(float3 directionWS)
{
return mul((float3x3)GetWorldToHClipMatrix(), directionWS);
}
// Tranforms position from view space to homogenous space
float4 TransformWViewToHClip(float3 positionVS)
{
return mul(GetViewToHClipMatrix(), float4(positionVS, 1.0));
}
// Tranforms vector from world space to homogenous space
float3 TransformViewToHClipDir(float3 directionVS)
{
return mul((float3x3)GetViewToHClipMatrix(), directionVS);
}
float3 GetPrimaryCameraPosition()
{
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
return float3(0, 0, 0);
#else
return _WorldSpaceCameraPos;
#endif
}
// Could be e.g. the position of a primary camera or a shadow-casting light.
float3 GetCurrentViewPosition()
{
#if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS)
return GetPrimaryCameraPosition();
#else
// This is a generic solution.
// However, using '_WorldSpaceCameraPos' is better for cache locality,
// and in case we enable camera-relative rendering, we can statically set the position is 0.
return UNITY_MATRIX_I_V._14_24_34;
#endif
}
// Returns the forward (central) direction of the current view in the world space.
float3 GetViewForwardDir()
{
float4x4 viewMat = GetWorldToViewMatrix();
return -viewMat[2].xyz;
}
// Returns 'true' if the current view performs a perspective projection.
bool IsPerspectiveProjection()
{
#if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS)
return (unity_OrthoParams.w == 0);
#else
// This is a generic solution.
// However, using 'unity_OrthoParams' is better for cache locality.
// TODO: set 'unity_OrthoParams' during the shadow pass.
return UNITY_MATRIX_P[3][3] == 0;
#endif
}
// Computes the world space view direction (pointing towards the viewer).
float3 GetWorldSpaceViewDir(float3 positionRWS)
{
if (IsPerspectiveProjection())
{
// Perspective
return GetCurrentViewPosition() - positionRWS;
}
else
{
// Orthographic
return -GetViewForwardDir();
}
}
float3 GetWorldSpaceNormalizeViewDir(float3 positionRWS)
{
return normalize(GetWorldSpaceViewDir(positionRWS));
}
float3x3 CreateWorldToTangent(float3 normal, float3 tangent, float flipSign)
{
// For odd-negative scale transforms we need to flip the sign
float sgn = flipSign * GetOddNegativeScale();
float3 bitangent = cross(normal, tangent) * sgn;
return float3x3(tangent, bitangent, normal);
}
float3 TransformTangentToWorld(float3 dirTS, float3x3 worldToTangent)
{
// Use transpose transformation to go from tangent to world as the matrix is orthogonal
return mul(dirTS, worldToTangent);
}
float3 TransformWorldToTangent(float3 dirWS, float3x3 worldToTangent)
{
return mul(worldToTangent, dirWS);
}
float3 TransformTangentToObject(float3 dirTS, float3x3 worldToTangent)
{
// Use transpose transformation to go from tangent to world as the matrix is orthogonal
float3 normalWS = mul(dirTS, worldToTangent);
return mul((float3x3)GetWorldToObjectMatrix(), normalWS);
}
float3 TransformObjectToTangent(float3 dirOS, float3x3 worldToTangent)
{
return mul(worldToTangent, TransformObjectToWorldDir(dirOS));
}
// UNITY_MATRIX_V defines a right-handed view space with the Z axis pointing towards the viewer.
// This function reverses the direction of the Z axis (so that it points forward),
// making the view space coordinate system left-handed.
void GetLeftHandedViewSpaceMatrices(out float4x4 viewMatrix, out float4x4 projMatrix)
{
viewMatrix = UNITY_MATRIX_V;
viewMatrix._31_32_33_34 = -viewMatrix._31_32_33_34;
projMatrix = UNITY_MATRIX_P;
projMatrix._13_23_33_43 = -projMatrix._13_23_33_43;
}
// This method should be used for rendering any full screen quad that uses an auto-scaling Render Targets (see RTHandle/HDCamera)
// It will account for the fact that the textures it samples are not necesarry using the full space of the render texture but only a partial viewport.
float2 GetNormalizedFullScreenTriangleTexCoord(uint vertexID)
{
return GetFullScreenTriangleTexCoord(vertexID) * _ScreenToTargetScale.xy;
}
// The size of the render target can be larger than the size of the viewport.
// This function returns the fraction of the render target covered by the viewport:
// ViewportScale = ViewportResolution / RenderTargetResolution.
// Do not assume that their size is the same, or that sampling outside of the viewport returns 0.
float2 GetViewportScaleCurrentFrame()
{
return _ScreenToTargetScale.xy;
}
float2 GetViewportScalePreviousFrame()
{
return _ScreenToTargetScale.zw;
}
float4 SampleSkyTexture(float3 texCoord)
{
return SAMPLE_TEXTURECUBE(_SkyTexture, s_trilinear_clamp_sampler, texCoord);
}
float4 SampleSkyTexture(float3 texCoord, float lod)
{
return SAMPLE_TEXTURECUBE_LOD(_SkyTexture, s_trilinear_clamp_sampler, texCoord, lod);
}
#endif // UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED