浏览代码

Fix tangent space SSS integration

/RenderPassXR_Sandbox
Evgenii Golubev 8 年前
当前提交
8be8c50b
共有 4 个文件被更改,包括 37 次插入23 次删除
  1. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  3. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariablesFunctions.hlsl
  4. 31
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


if (sssSettings.useDisneySSS)
{
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT); // Cannot set a RT on a material
// Temp >>>
Matrix4x4 viewMatrix = hdCamera.camera.worldToCameraMatrix;
viewMatrix.SetRow(2, -viewMatrix.GetRow(2)); // Make Z axis point forwards in the view space (left-handed CS)
Matrix4x4 projMatrix = GL.GetGPUProjectionMatrix(hdCamera.camera.projectionMatrix, false);
projMatrix.SetColumn(2, -projMatrix.GetColumn(2)); // Undo the view-space transformation
m_FilterAndCombineSubsurfaceScattering.SetMatrix("_ViewMatrix", viewMatrix);
m_FilterAndCombineSubsurfaceScattering.SetMatrix("_ProjMatrix", projMatrix);
// <<< Temp
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_WorldScales", sssParameters.worldScales);
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_FilterKernelsNearField", sssParameters.filterKernelsNearField);
m_FilterAndCombineSubsurfaceScattering.SetFloatArray("_FilterKernelsFarField", sssParameters.filterKernelsFarField);

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


/* 'vec' is given relative to the tangent frame. */ \
float3 relPosVS = vec.x * tangentX + vec.y * tangentY; \
float3 positionVS = centerPosVS + relPosVS; \
float4 positionCS = mul(_ProjMatrix, float4(positionVS, 1)); \
float2 positionSS = positionCS.xy * (rcp(positionCS.w) * 0.5) + 0.5; \
float4 positionCS = mul(projMatrix, float4(positionVS, 1)); \
float2 positionSS = ComputeScreenSpacePosition(positionCS); \
\
position = positionSS * _ScreenSize.xy; \
irradiance = LOAD_TEXTURE2D(_IrradianceSource, position).rgb; \

const bool useTangentPlane = SSS_USE_TANGENT_PLANE != 0;
float4x4 viewMatrix, projMatrix;
GetLeftHandedViewSpaceMatrices(viewMatrix, projMatrix);
float3 normalVS = mul((float3x3)_ViewMatrix, bsdfData.normalWS);
float3 normalVS = mul((float3x3)viewMatrix, bsdfData.normalWS);
float3 tangentX = GetLocalFrame(normalVS)[0] * unitsPerMm;
float3 tangentY = GetLocalFrame(normalVS)[1] * unitsPerMm;

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariablesFunctions.hlsl


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;
}
#endif // UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED

31
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


posInput.positionWS = positionWS;
}
float4 ComputeClipSpacePosition(float2 positionSS, float depthRaw)
{
#if UNITY_UV_STARTS_AT_TOP
positionSS.y = 1.0 - positionSS.y;
#endif
return float4(positionSS * 2.0 - 1.0, depthRaw, 1.0);
}
float2 ComputeScreenSpacePosition(float4 positionCS)
{
float2 positionSS = positionCS.xy * (rcp(positionCS.w) * 0.5) + 0.5;
#if UNITY_UV_STARTS_AT_TOP
positionSS.y = 1.0 - positionSS.y;
#endif
return positionSS;
}
// From deferred or compute shader
// depth must be the depth from the raw depth buffer. This allow to handle all kind of depth automatically with the inverse view projection matrix.
// For information. In Unity Depth is always in range 0..1 (even on OpenGL) but can be reversed.

{
posInput.depthRaw = depthRaw;
float2 screenSpacePos;
screenSpacePos = posInput.positionSS;
#if UNITY_UV_STARTS_AT_TOP
screenSpacePos.y = 1.0 - screenSpacePos.y;
#endif
float4 positionCS = float4(screenSpacePos * 2.0 - 1.0, depthRaw, 1.0);
float4 positionCS = ComputeClipSpacePosition(posInput.positionSS, depthRaw);
float4 hpositionWS = mul(invViewProjMatrix, positionCS);
posInput.positionWS = hpositionWS.xyz / hpositionWS.w;

// of Direct3D is at the top left corner of the screen, with the Y axis pointing downwards.
float3 ComputeViewSpacePosition(float2 positionSS, float depthRaw, float4x4 invProjMatrix)
{
float2 screenSpacePos;
screenSpacePos = positionSS;
#if UNITY_UV_STARTS_AT_TOP
screenSpacePos.y = 1.0 - screenSpacePos.y;
#endif
float4 positionCS = float4(screenSpacePos * 2.0 - 1.0, depthRaw, 1.0);
float4 positionCS = ComputeClipSpacePosition(positionSS, depthRaw);
float4 positionVS = mul(invProjMatrix, positionCS);
// The view space uses a right-handed coordinate system.
positionVS.z = -positionVS.z;

正在加载...
取消
保存