浏览代码

Remove the bilateral scale and store RGB (1 / (2 * WeightedVariance))

/main
Evgenii Golubev 8 年前
当前提交
00ba8344
共有 3 个文件被更改,包括 29 次插入34 次删除
  1. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs
  2. 9
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  3. 48
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs

6
Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs


if (debugParameters.ShouldUseForwardRenderingOnly()) return;
// Load the kernel data.
Vector4[] kernelData = new Vector4[SubsurfaceScatteringParameters.maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
Vector4[] kernelData = new Vector4[SubsurfaceScatteringParameters.maxNumProfiles * SubsurfaceScatteringProfile.numVectors];
for (int i = 0, n = SubsurfaceScatteringProfile.numSamples; i < n; i++)
for (int i = 0, n = SubsurfaceScatteringProfile.numVectors; i < n; i++)
var cmd = new CommandBuffer() { name = "Combine Subsurface Scattering" };
var cmd = new CommandBuffer() { name = "Subsurface Scattering Pass" };
// Perform the vertical SSS filtering pass.
m_FilterSubsurfaceScattering.SetMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);

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


{
Properties
{
_FilterRadius("", Float) = 20
_BilateralScale("", Float) = 0.1
[HideInInspector] _DstBlend("", Float) = 1 // Can be set to 1 for blending with specular
}

#define N_PROFILES 8
#define N_SAMPLES 7
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _FilterKernels[N_PROFILES][N_SAMPLES + 1]; // RGB = weights, A = radial distance
float4x4 _InvProjMatrix;
TEXTURE2D(_CameraDepthTexture);

#endif
float2 scaledDirection = radiusScale * stepSize * unitDirection;
float inv2MaxVariance = _FilterKernels[profileID][0].a;
// Load (1 / (2 * WeightedVariance)) for bilateral weighting.
float3 halfRcpVariance = _FilterKernels[profileID][N_SAMPLES].rgb;
// Take the first (central) sample.
float2 samplePosition = posInput.unPositionSS;

// Ref #2: Separable SSS, Supplementary Materials, Section E.
float sampleDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float zDistance = radiusScale * sampleDepth - (radiusScale * centerPosVS.z);
sampleWeight *= exp(-zDistance * zDistance * inv2MaxVariance);
sampleWeight *= exp(-zDistance * zDistance * halfRcpVariance);
filteredIrradiance += sampleIrradiance * sampleWeight;
}

48
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs


public class SubsurfaceScatteringProfile
{
public const int numSamples = 7; // Must be an odd number
public const int numVectors = 8; // numSamples + 1 for (1 / (2 * WeightedVariance))
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
Color m_StdDev1;

void ComputeKernel()
{
if (m_FilterKernel == null || m_FilterKernel.Length != numSamples)
if (m_FilterKernel == null || m_FilterKernel.Length != numVectors)
m_FilterKernel = new Vector4[numSamples];
m_FilterKernel = new Vector4[numVectors];
}
// Our goal is to blur the image using a filter which is represented

val.y = GaussianCombination(pos, m_StdDev1.g, m_StdDev2.g, m_LerpWeight);
val.z = GaussianCombination(pos, m_StdDev1.b, m_StdDev2.b, m_LerpWeight);
m_FilterKernel[i].x = val.x / (pdf * numSamples);
m_FilterKernel[i].y = val.y / (pdf * numSamples);
m_FilterKernel[i].z = val.z / (pdf * numSamples);
// We do not divide by 'numSamples' since we will renormalize, anyway.
m_FilterKernel[i].x = val.x * (1 / pdf);
m_FilterKernel[i].y = val.y * (1 / pdf);
m_FilterKernel[i].z = val.z * (1 / pdf);
m_FilterKernel[i].w = pos;
weightSum.x += m_FilterKernel[i].x;

// Renormalize the weights to conserve energy.
for (uint i = 0; i < numSamples; i++)
{
m_FilterKernel[i].x *= 1.0f / weightSum.x;
m_FilterKernel[i].y *= 1.0f / weightSum.y;
m_FilterKernel[i].z *= 1.0f / weightSum.z;
m_FilterKernel[i].x *= 1 / weightSum.x;
m_FilterKernel[i].y *= 1 / weightSum.y;
m_FilterKernel[i].z *= 1 / weightSum.z;
// Store (1 / (2 * variance)) instead of the distance to the 1st sample (which is implicitly 0).
float weightedStdDev = Mathf.Lerp(maxStdDev1, maxStdDev2, m_LerpWeight);
m_FilterKernel[0].w = 1.0f / (2.0f * weightedStdDev * weightedStdDev);
Vector3 weightedStdDev;
weightedStdDev.x = Mathf.Lerp(m_StdDev1.r, m_StdDev2.r, m_LerpWeight);
weightedStdDev.y = Mathf.Lerp(m_StdDev1.g, m_StdDev2.g, m_LerpWeight);
weightedStdDev.z = Mathf.Lerp(m_StdDev1.b, m_StdDev2.b, m_LerpWeight);
m_KernelNeedsUpdate = false;
// Store (1 / (2 * WeightedVariance)) per color channel.
m_FilterKernel[numSamples].x = 0.5f / (weightedStdDev.x * weightedStdDev.x);
m_FilterKernel[numSamples].y = 0.5f / (weightedStdDev.y * weightedStdDev.y);
m_FilterKernel[numSamples].z = 0.5f / (weightedStdDev.z * weightedStdDev.z);
}
}

int m_NumProfiles;
[SerializeField]
SubsurfaceScatteringProfile[] m_Profiles;
[SerializeField]
float m_BilateralScale;
m_NumProfiles = 1;
m_Profiles = new SubsurfaceScatteringProfile[m_NumProfiles];
m_BilateralScale = 0.1f;
m_NumProfiles = 1;
m_Profiles = new SubsurfaceScatteringProfile[m_NumProfiles];
for (int i = 0; i < m_NumProfiles; i++)
{

public SubsurfaceScatteringProfile[] profiles { set { m_Profiles = value; OnValidate(); } get { return m_Profiles; } }
public float bilateralScale { set { m_BilateralScale = value; OnValidate(); } get { return m_BilateralScale; } }
public SubsurfaceScatteringProfile[] profiles { set { m_Profiles = value; OnValidate(); } get { return m_Profiles; } }
public void SetDirtyFlag()
{

m_Profiles[i].lerpWeight = Mathf.Clamp01(m_Profiles[i].lerpWeight);
}
m_BilateralScale = Mathf.Clamp01(m_BilateralScale);
}
}

public readonly GUIContent sssProfileStdDev1 = new GUIContent("SSS profile standard deviation #1", "Determines the shape of the 1st Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileStdDev2 = new GUIContent("SSS profile standard deviation #2", "Determines the shape of the 2nd Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileLerpWeight = new GUIContent("SSS profile filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssBilateralScale = new GUIContent("SSS bilateral filtering scale", "Larger values make the filter more tolerant to depth differences.");
private SerializedProperty m_BilateralScale;
// --- Public Methods ---

EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_Profiles, true);
EditorGUILayout.PropertyField(m_BilateralScale, styles.sssBilateralScale);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();

void OnEnable()
{
m_Profiles = serializedObject.FindProperty("m_Profiles");
m_BilateralScale = serializedObject.FindProperty("m_BilateralScale");
m_Profiles = serializedObject.FindProperty("m_Profiles");
}
}
}
正在加载...
取消
保存