浏览代码

Implement efficient depth linearization for oblique view frustums

/Branch_Batching2
Evgenii Golubev 8 年前
当前提交
b764b1b3
共有 5 个文件被更改,包括 49 次插入20 次删除
  1. 27
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  3. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  4. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
  5. 20
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl

27
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


public Matrix4x4 viewProjectionMatrix;
public Matrix4x4 invViewProjectionMatrix;
public Matrix4x4 invProjectionMatrix;
public Vector4 invProjectionParam;
}
public class GBufferManager

public void PushGlobalParams(HDCamera hdCamera, ScriptableRenderContext renderContext, SubsurfaceScatteringParameters sssParameters)
{
var cmd = new CommandBuffer {name = "Push Global Parameters"};
cmd.SetGlobalVector("_ScreenSize", hdCamera.screenSize);
cmd.SetGlobalMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
cmd.SetGlobalMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
cmd.SetGlobalMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
cmd.SetGlobalVector("_InvProjParam", hdCamera.invProjectionParam);
// TODO: cmd.SetGlobalInt() does not exist, so we are forced to use Shader.SetGlobalInt() instead.
if (m_SkyManager.IsSkyValid())
{
m_SkyManager.SetGlobalSkyTexture();

// Broadcast SSS parameters to all shaders.
Shader.SetGlobalInt("_TransmissionFlags", sssParameters.transmissionFlags);
Shader.SetGlobalFloatArray("_ThicknessRemaps", sssParameters.thicknessRemaps);
Shader.SetGlobalVectorArray("_HalfRcpVariancesAndLerpWeights", sssParameters.halfRcpVariancesAndLerpWeights);
cmd.SetGlobalFloatArray("_ThicknessRemaps", sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray("_HalfRcpVariancesAndLerpWeights", sssParameters.halfRcpVariancesAndLerpWeights);
Shader.EnableKeyword("_SUBSURFACE_SCATTERING");
cmd.EnableShaderKeyword("_SUBSURFACE_SCATTERING");
Shader.DisableKeyword("_SUBSURFACE_SCATTERING");
cmd.DisableShaderKeyword("_SUBSURFACE_SCATTERING");
var cmd = new CommandBuffer {name = "Push Global Parameters"};
cmd.SetGlobalVector("_ScreenSize", hdCamera.screenSize);
cmd.SetGlobalMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
cmd.SetGlobalMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

var cmd = new CommandBuffer() { name = "Subsurface Scattering Pass" };
// Perform the vertical SSS filtering pass.
m_FilterSubsurfaceScattering.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
m_FilterSubsurfaceScattering.SetVectorArray("_FilterKernels", sssParameters.filterKernels);
m_FilterSubsurfaceScattering.SetVectorArray("_HalfRcpWeightedVariances", sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT);

// Perform the horizontal SSS filtering pass, and combine diffuse and specular lighting.
m_FilterAndCombineSubsurfaceScattering.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
m_FilterAndCombineSubsurfaceScattering.SetVectorArray("_FilterKernels", sssParameters.filterKernels);
m_FilterAndCombineSubsurfaceScattering.SetVectorArray("_HalfRcpWeightedVariances", sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalTexture("_IrradianceSource", m_CameraFilteringBufferRT);

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


float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
float4x4 _InvProjMatrix;
TEXTURE2D_FLOAT(_CameraDepthTexture);
TEXTURE2D(_GBufferTexture2);

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


// ----------------------------------------------------------------------------
// TODO: move this to constant buffer by Pass
float4x4 _InvViewProjMatrix;
float4 _ScreenSize;
float4 _ScreenSize;
float4x4 _InvViewProjMatrix;
float4x4 _InvProjMatrix;
float4 _InvProjParam;
float4x4 GetWorldToViewMatrix()
{

15
Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs


var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
var gpuVP = gpuProj * camera.worldToCameraMatrix;
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
Vector4 invProjectionParam = new Vector4(gpuProj.m20 / (gpuProj.m00 * gpuProj.m23),
gpuProj.m21 / (gpuProj.m11 * gpuProj.m23),
-1.0f / gpuProj.m23,
(-gpuProj.m22
+ gpuProj.m20 * gpuProj.m02 / gpuProj.m00
+ gpuProj.m21 * gpuProj.m12 / gpuProj.m11) / gpuProj.m23);
hdCamera.invProjectionParam = invProjectionParam;
return hdCamera;
}

material.SetVector("_ScreenSize", hdCamera.screenSize);
material.SetMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
material.SetVector("_ScreenSize", hdCamera.screenSize);
material.SetMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
material.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
material.SetVector("_InvProjParam", hdCamera.invProjectionParam);
}
// TEMP: These functions should be implemented C++ side, for now do it in C#

20
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


// World position reconstruction / transformation
// ----------------------------------------------------------------------------
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane)
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane).
// Does not correctly handle oblique view frustums.
// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane)
// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane).
// Does not correctly handle oblique view frustums.
// Z buffer to linear depth
// Z buffer to linear depth.
// Does not correctly handle oblique view frustums.
}
// Z buffer to linear depth.
// Correctly handles oblique view frustums.
// positionNDC.xy are in [-1, 1] and positionNDC.z is in [0, 1].
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
float LinearEyeDepth(float3 positionNDC, float4 invProjParam)
{
float z = 1.0 / dot(float4(positionNDC, 1), invProjParam);
// The view space uses a right-handed coordinate system.
return -z;
}
struct PositionInputs

正在加载...
取消
保存