浏览代码

Implement 3 texturing modes for SSS

/Branch_Batching2
Evgenii Golubev 8 年前
当前提交
d75bcfa1
共有 6 个文件被更改,包括 151 次插入76 次删除
  1. 95
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  2. 20
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  3. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader
  4. 46
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  5. 49
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  6. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs

95
Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs


public readonly GUIContent sssProfileLerpWeight = new GUIContent("Filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssProfileTransmission = new GUIContent("Enable transmission", "Toggles simulation of light passing through thin objects. Depends on the thickness of the material.");
public readonly GUIContent sssProfileThicknessRemap = new GUIContent("Thickness remap", "Remaps the thickness parameter from [0, 1] to the desired range.");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing mode", "Specifies when the diffuse texture should be applied.");
public readonly GUIContent[] sssTexturingModeOptions = new GUIContent[3] { new GUIContent("Pre-scatter", "Before the blurring pass. Effectively results in the diffuse texture getting blurred together with the lighting."), new GUIContent("Post-scatter", "After the blurring pass. Effectively preserves the sharpness of the diffuse texture."), new GUIContent("Pre- and post-scatter", "Both before and after the blurring pass.") };
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);

SerializedProperty m_RenderingUseDepthPrepass = null;
// Subsurface Scattering Settings
SerializedProperty m_TexturingMode = null;
SerializedProperty m_Profiles = null;
SerializedProperty m_NumProfiles = null;

m_RenderingUseDepthPrepass = FindProperty(x => x.renderingSettings.useDepthPrepass);
// Subsurface Scattering Settings
m_TexturingMode = FindProperty(x => x.sssSettings.texturingMode);
m_Profiles = FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}

EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_NumProfiles, styles.sssNumProfiles);
EditorGUILayout.PropertyField(m_Profiles);
m_TexturingMode.intValue = EditorGUILayout.Popup(styles.sssTexturingMode, m_TexturingMode.intValue, styles.sssTexturingModeOptions, (GUILayoutOption[])null);
if (m_Profiles.isExpanded)
for (int i = 0, n = Math.Min(m_Profiles.arraySize, SubsurfaceScatteringSettings.maxNumProfiles); i < n; i++)
EditorGUI.indentLevel++;
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.sssProfiles[i]);
for (int i = 0, n = Math.Min(m_Profiles.arraySize, SubsurfaceScatteringSettings.maxNumProfiles); i < n; i++)
if (profile.isExpanded)
SerializedProperty profile = m_Profiles.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(profile, styles.sssProfiles[i]);
EditorGUI.indentLevel++;
if (profile.isExpanded)
{
EditorGUI.indentLevel++;
SerializedProperty profileStdDev1 = profile.FindPropertyRelative("stdDev1");
SerializedProperty profileStdDev2 = profile.FindPropertyRelative("stdDev2");
SerializedProperty profileLerpWeight = profile.FindPropertyRelative("lerpWeight");
SerializedProperty profileTransmission = profile.FindPropertyRelative("enableTransmission");
SerializedProperty profileThicknessRemap = profile.FindPropertyRelative("thicknessRemap");
SerializedProperty profileStdDev1 = profile.FindPropertyRelative("stdDev1");
SerializedProperty profileStdDev2 = profile.FindPropertyRelative("stdDev2");
SerializedProperty profileLerpWeight = profile.FindPropertyRelative("lerpWeight");
SerializedProperty profileTransmission = profile.FindPropertyRelative("enableTransmission");
SerializedProperty profileThicknessRemap = profile.FindPropertyRelative("thicknessRemap");
EditorGUILayout.PropertyField(profileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(profileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(profileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(profileTransmission, styles.sssProfileTransmission);
EditorGUILayout.PropertyField(profileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(profileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(profileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(profileTransmission, styles.sssProfileTransmission);
Vector2 thicknessRemap = profileThicknessRemap.vector2Value;
EditorGUILayout.LabelField("Min thickness: ", thicknessRemap.x.ToString());
EditorGUILayout.LabelField("Max thickness: ", thicknessRemap.y.ToString());
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
profileThicknessRemap.vector2Value = thicknessRemap;
Vector2 thicknessRemap = profileThicknessRemap.vector2Value;
EditorGUILayout.LabelField("Min thickness: ", thicknessRemap.x.ToString());
EditorGUILayout.LabelField("Max thickness: ", thicknessRemap.y.ToString());
EditorGUILayout.MinMaxSlider(styles.sssProfileThicknessRemap, ref thicknessRemap.x, ref thicknessRemap.y, 0, 10);
profileThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssProfilePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssProfilePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField(styles.sssProfilePreview2, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImages[i], m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImages[i], m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssTransmittancePreview0, styles.centeredMiniBoldLabel);
EditorGUILayout.LabelField(styles.sssTransmittancePreview1, EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.Space();
// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", profileThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImages[i], m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", profileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", profileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", profileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", profileThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImages[i], m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;

20
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


m_CameraFilteringBufferRT = new RenderTargetIdentifier(m_CameraFilteringBuffer);
m_FilterSubsurfaceScattering = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineSubsurfaceScattering");
m_FilterSubsurfaceScattering.DisableKeyword("FILTER_HORIZONTAL");
m_FilterSubsurfaceScattering.DisableKeyword("FILTER_HORIZONTAL_AND_COMBINE");
m_FilterSubsurfaceScattering.EnableKeyword("FILTER_HORIZONTAL");
m_FilterSubsurfaceScattering.EnableKeyword("FILTER_HORIZONTAL_AND_COMBINE");
m_FilterAndCombineSubsurfaceScattering.SetFloat("_DstBlend", (float)BlendMode.One);
InitializeDebugMaterials();

Shader.SetGlobalInt("_TransmissionFlags", sssParameters.transmissionFlags);
cmd.SetGlobalFloatArray("_ThicknessRemaps", sssParameters.thicknessRemaps);
cmd.SetGlobalVectorArray("_HalfRcpVariancesAndLerpWeights", sssParameters.halfRcpVariancesAndLerpWeights);
switch (sssParameters.texturingMode)
{
case SubsurfaceScatteringSettings.TexturingMode.PreScatter:
cmd.EnableShaderKeyword("SSS_PRE_SCATTER_TEXTURING");
cmd.DisableShaderKeyword("SSS_POST_SCATTER_TEXTURING");
break;
case SubsurfaceScatteringSettings.TexturingMode.PostScatter:
cmd.DisableShaderKeyword("SSS_PRE_SCATTER_TEXTURING");
cmd.EnableShaderKeyword("SSS_POST_SCATTER_TEXTURING");
break;
case SubsurfaceScatteringSettings.TexturingMode.PreAndPostScatter:
cmd.DisableShaderKeyword("SSS_PRE_SCATTER_TEXTURING");
cmd.DisableShaderKeyword("SSS_POST_SCATTER_TEXTURING");
break;
}
if (globalDebugSettings.renderingDebugSettings.enableSSS)
{

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader


// Split lighting is utilized during the SSS pass.
#pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
// #ifdef OUTPUT_SPLIT_LIGHTING
#pragma shader_feature _ SSS_PRE_SCATTER_TEXTURING SSS_POST_SCATTER_TEXTURING
// #endif
#pragma multi_compile _ LIGHTING_DEBUG
//-------------------------------------------------------------------------------------

46
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


#endif
}
void ConfigureTexturingForSSS(inout BSDFData bsdfData)
{
#ifdef SSS_PRE_SCATTER_TEXTURING
bsdfData.diffuseColor = bsdfData.diffuseColor;
#elif SSS_POST_SCATTER_TEXTURING
bsdfData.diffuseColor = float3(1, 1, 1);
#else // combine pre-scatter and post-scatter texturing
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
#endif
}
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians.
// Computes results for each color channel separately.
// Ref: Real-Time Realistic Skin Translucency (2010), equation 9 (modified).

bsdfData.fresnel0 = surfaceData.specularColor;
}
#ifdef OUTPUT_SPLIT_LIGHTING
ConfigureTexturingForSSS(bsdfData);
#endif
return bsdfData;
}

#endif
}
void DecodeFromGBuffer(
float4 DecodeGBuffer0(GBufferType0 encodedGBuffer0)
{
float4 decodedGBuffer0;
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
decodedGBuffer0.x = UnpackUIntToFloat(encodedGBuffer0.x, 8, 0);
decodedGBuffer0.y = UnpackUIntToFloat(encodedGBuffer0.x, 8, 8);
decodedGBuffer0.z = UnpackUIntToFloat(encodedGBuffer0.y, 8, 0);
decodedGBuffer0.w = UnpackUIntToFloat(encodedGBuffer0.y, 8, 8);
decodedGBuffer0.xyz = Gamma20ToLinear(encodedGBuffer0.xyz);
#else
decodedGBuffer0 = encodedGBuffer0;
#endif
return decodedGBuffer0;
}
void DecodeFromGBuffer(
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
GBufferType0 inGBufferU0,
GBufferType1 inGBufferU1,

#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
float4 inGBuffer0, inGBuffer1, inGBuffer2, inGBuffer3;
inGBuffer0.x = UnpackUIntToFloat(inGBufferU0.x, 8, 0);
inGBuffer0.y = UnpackUIntToFloat(inGBufferU0.x, 8, 8);
inGBuffer0.z = UnpackUIntToFloat(inGBufferU0.y, 8, 0);
inGBuffer0.w = UnpackUIntToFloat(inGBufferU0.y, 8, 8);
inGBuffer0.xyz = Gamma20ToLinear(inGBuffer0.xyz);
inGBuffer0 = DecodeGBuffer0(inGBufferU0);
inGBuffer2.x = UnpackUIntToFloat(inGBufferU1.x, 8, 0);
inGBuffer2.y = UnpackUIntToFloat(inGBufferU1.x, 8, 8);
inGBuffer2.z = UnpackUIntToFloat(inGBufferU1.y, 8, 0);

bakeDiffuseLighting = inGBuffer3.rgb;
#ifdef OUTPUT_SPLIT_LIGHTING
ConfigureTexturingForSSS(bsdfData);
#endif
ApplyDebugToBSDFData(bsdfData);
}

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


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
// #pragma enable_d3d11_debug_symbols
#pragma multi_compile _ FILTER_HORIZONTAL
#pragma shader_feature _ SSS_PRE_SCATTER_TEXTURING SSS_POST_SCATTER_TEXTURING
#pragma multi_compile _ FILTER_HORIZONTAL_AND_COMBINE
//-------------------------------------------------------------------------------------
// Include

#include "HDRenderPipeline/ShaderConfig.cs.hlsl"
#define UNITY_MATERIAL_LIT // Need to be defined before including Material.hlsl
#include "HDRenderPipeline/Material/Material.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs

#define N_SAMPLES 7
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
float4 _HalfRcpWeightedVariances[N_PROFILES]; // RGB for chromatic, A for achromatic
#ifndef SSS_PRE_SCATTER_TEXTURING
TEXTURE2D(_GBufferTexture0); // RGB = baseColor, A = spec. occlusion
#endif
TEXTURE2D(_GBufferTexture2);
TEXTURE2D(_IrradianceSource);
TEXTURE2D(_GBufferTexture2); // R = SSS radius, G = SSS thickness, A = SSS profile
TEXTURE2D(_IrradianceSource); // RGB = irradiance on the back side of the object
//-------------------------------------------------------------------------------------
// Implementation

float3 centerPosVS = ComputeViewSpacePosition(posInput.positionSS, rawDepth, _InvProjMatrix);
// Compute the dimensions of the surface fragment viewed as a quad facing the camera.
float fragWidth = ddx(centerPosVS.x);
float fragheight = ddy(centerPosVS.y);
float fragWidth = ddx_fine(centerPosVS.x);
float fragheight = ddy_fine(centerPosVS.y);
#ifdef FILTER_HORIZONTAL
#ifdef FILTER_HORIZONTAL_AND_COMBINE
float stepSize = stepSizeX;
float2 unitDirection = float2(1, 0);
#else

#else
float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;
#endif
// Accumulate filtered irradiance (already weighted by (albedo / Pi)).
float3 totalIrradiance = sampleIrradiance * sampleWeight;
// Accumulate filtered irradiance.
float3 totalIrradiance = sampleWeight * sampleIrradiance;
// Make sure bilateral filtering does not cause energy loss.
// TODO: ask Morten if there is a better way to do this.

sampleWeight = _FilterKernels[profileID][i].rgb;
rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, samplePosition).r;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;
// Apply bilateral weighting.
// Ref #1: Skin Rendering by Pseudo–Separable Cross Bilateral Filtering.

sampleWeight *= exp(-zDistance * zDistance * halfRcpVariance);
totalIrradiance += sampleIrradiance * sampleWeight;
totalIrradiance += sampleWeight * sampleIrradiance;
#ifdef SSS_PRE_SCATTER_TEXTURING
float3 diffuseContrib = float3(1, 1, 1);
#elif SSS_POST_SCATTER_TEXTURING
float3 diffuseColor = DecodeGBuffer0(LOAD_TEXTURE2D(_GBufferTexture0, posInput.unPositionSS)).rgb;
float3 diffuseContrib = diffuseColor;
#else // combine pre-scatter and post-scatter texturing
float3 diffuseColor = DecodeGBuffer0(LOAD_TEXTURE2D(_GBufferTexture0, posInput.unPositionSS)).rgb;
float3 diffuseContrib = sqrt(diffuseColor);
#endif
#ifdef FILTER_HORIZONTAL_AND_COMBINE
return float4(diffuseContrib * totalIrradiance / totalWeight, 1.0);
#else
#endif
}
ENDHLSL
}

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs


[Serializable]
public class SubsurfaceScatteringSettings
{
public enum TexturingMode : int { PreScatter = 0, PostScatter = 1, PreAndPostScatter = 2, MaxValue = 2 };
public TexturingMode texturingMode;
public int transmissionFlags;
public SubsurfaceScatteringProfile[] profiles;
public float[] thicknessRemaps;

public SubsurfaceScatteringSettings()
{
numProfiles = 1;
profiles = new SubsurfaceScatteringProfile[numProfiles];
numProfiles = 1;
texturingMode = 0;
profiles = new SubsurfaceScatteringProfile[numProfiles];
for (int i = 0; i < numProfiles; i++)
{

Array.Resize(ref profiles, maxNumProfiles);
}
numProfiles = profiles.Length;
transmissionFlags = 0;
numProfiles = profiles.Length;
texturingMode = (TexturingMode)Math.Max(0, Math.Min((int)texturingMode, (int)TexturingMode.MaxValue));
if (thicknessRemaps == null)
{

filterKernels = new Vector4[maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
}
transmissionFlags = 0;
Color c = new Color();
for (int i = 0; i < numProfiles; i++)

正在加载...
取消
保存