浏览代码

Merge pull request #205 from EvgeniiG/master

Refactor SSS
/fptl_cleanup
GitHub 8 年前
当前提交
77b44a0b
共有 15 个文件被更改,包括 174 次插入363 次删除
  1. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
  2. 137
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset
  3. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  4. 48
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  5. 23
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  6. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  7. 39
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  8. 198
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
  9. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs
  10. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs
  11. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/FragInputs.hlsl
  12. 5
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  13. 2
      ProjectSettings/ProjectVersion.txt
  14. 35
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset
  15. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset.meta

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


// Subsurface Scattering Settings
public readonly GUIContent[] sssProfiles = new GUIContent[SubsurfaceScatteringSettings.maxNumProfiles] { new GUIContent("Profile #0"), new GUIContent("Profile #1"), new GUIContent("Profile #2"), new GUIContent("Profile #3"), new GUIContent("Profile #4"), new GUIContent("Profile #5"), new GUIContent("Profile #6"), new GUIContent("Profile #7") };
public readonly GUIContent sssNumProfiles = new GUIContent("Number of profiles");
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.") };
// Tile pass Settings
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop Settings");

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");
m_Profiles = FindProperty(x => x.sssSettings.profiles);
m_NumProfiles = m_Profiles.FindPropertyRelative("Array.size");
}
SerializedProperty FindProperty<TValue>(Expression<Func<HDRenderPipeline, TValue>> expr)

EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_NumProfiles, styles.sssNumProfiles);
m_TexturingMode.intValue = EditorGUILayout.Popup(styles.sssTexturingMode, m_TexturingMode.intValue, styles.sssTexturingModeOptions, (GUILayoutOption[])null);
for (int i = 0, n = Math.Min(m_Profiles.arraySize, SubsurfaceScatteringSettings.maxNumProfiles); i < n; i++)
{

137
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.asset


useForwardRenderingOnly: 0
useDepthPrepass: 0
sssSettings:
numProfiles: 1
numProfiles: 0
profiles:
- {fileID: 11400000, guid: 09521380d86baee43bf09b32473ea5f3, type: 2}
thicknessRemaps:
- 0
- 1
- 0
- 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
halfRcpVariancesAndLerpWeights:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553, w: 0.5}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888, w: 0.5}
- {x: 5.5555553, y: 5.5555553, z: 5.5555553, w: 0.5}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888, w: 0.5}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
halfRcpWeightedVariances:
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
filterKernels:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.7609476}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.49358216}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.4935822}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.7609475}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.7609476}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.49358216}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.4935822}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.7609475}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
- {x: 0, y: 0, z: 0, w: 0}
profiles: []
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096

19
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


}
// Broadcast SSS parameters to all shaders.
Shader.SetGlobalInt("_TransmissionFlags", sssParameters.transmissionFlags);
Shader.SetGlobalInt("_TransmissionFlags", sssParameters.transmissionFlags);
Shader.SetGlobalInt("_TexturingModeFlags", sssParameters.texturingModeFlags);
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)
{

48
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


emissiveIntensity = FindProperty(kEmissiveIntensity, props);
}
protected void ShaderSSSInputGUI()
protected void ShaderSSSInputGUI(Material material)
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
// Attempt to load the profile from the SSS Settings.
HDRenderPipelineInstance hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipelineInstance;
if (profileID >= 0 && profileID < hdPipeline.sssSettings.profiles.Length)
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length &&
hdPipeline.sssSettings.profiles[profileID] != null)
// Refresh the ID of the profile.
hdPipeline.sssSettings.OnValidate();
}
}
subsurfaceProfile = EditorGUILayout.ObjectField(Styles.subsurfaceProfileText, subsurfaceProfile, typeof(SubsurfaceScatteringProfile), false) as SubsurfaceScatteringProfile;
bool validProfile = false;
// Set the profile ID.
if (subsurfaceProfile != null)
{
// Load the profile from the GUI field.
int profileID = subsurfaceProfile.settingsIndex;
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length)
{
validProfile = true;
material.SetInt("_SubsurfaceProfile", profileID);
subsurfaceProfile = SubsurfaceScatteringProfile.defaultProfile;
subsurfaceProfile = null;
Debug.LogError("The SSS Profile assigned to the material has an invalid index. First, add the Profile to the SSS Settings, and then reassign it to the material.");
// Refresh the ID of the profile.
hdPipeline.sssSettings.OnValidate();
// Extract the profile ID.
subsurfaceProfile = EditorGUILayout.ObjectField(Styles.subsurfaceProfileText, subsurfaceProfile, subsurfaceProfile.GetType(), false, null) as SubsurfaceScatteringProfile;
subsurfaceProfileID.floatValue = subsurfaceProfile.settingsIndex;
if (!validProfile)
{
// Disable SSS for this object.
material.SetInt("_SubsurfaceProfile", SubsurfaceScatteringSettings.neutralProfileID);
}
m_MaterialEditor.ShaderProperty(subsurfaceRadius, Styles.subsurfaceRadiusText);
m_MaterialEditor.TexturePropertySingleLine(Styles.subsurfaceRadiusMapText, subsurfaceRadiusMap);

m_MaterialEditor.TexturePropertySingleLine(Styles.anisotropyMapText, anisotropyMap);
}
protected override void MaterialPropertiesGUI()
protected override void MaterialPropertiesGUI(Material material)
{
bool useEmissiveMask = (EmissiveColorMode)emissiveColorMode.floatValue == EmissiveColorMode.UseEmissiveMask;

}
else if ((MaterialIDType)materialID.floatValue == MaterialIDType.SubsurfaceScattering)
{
ShaderSSSInputGUI();
ShaderSSSInputGUI(material);
}
EditorGUILayout.Space();

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


// SSS parameters
#define SSS_N_PROFILES 8
#define SSS_UNIT_CONVERSION (1.0 / 300.0) // From meters to 1/3 centimeters
uint _TransmissionFlags; // One bit per profile; 1 = enabled
uint _TransmissionFlags; // 1 bit/profile; 0 = inf. thick, 1 = supports transmission
uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
float _ThicknessRemaps[SSS_N_PROFILES][2]; // Remap: 0 = start, 1 = end - start
float4 _HalfRcpVariancesAndLerpWeights[SSS_N_PROFILES][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight

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
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, bsdfData.subsurfaceProfile);
// It's either post-scatter, or pre- and post-scatter texturing.
bsdfData.diffuseColor = performPostScatterTexturing ? float3(1, 1, 1)
: sqrt(bsdfData.diffuseColor);
}
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians.

bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * surfaceData.subsurfaceRadius;
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * surfaceData.thickness);
bsdfData.enableTransmission = (1 << bsdfData.subsurfaceProfile) & _TransmissionFlags;
bsdfData.enableTransmission = IsBitSet(_TransmissionFlags, bsdfData.subsurfaceProfile);
if (bsdfData.enableTransmission)
{
bsdfData.transmittance = ComputeTransmittance(_HalfRcpVariancesAndLerpWeights[bsdfData.subsurfaceProfile][0].xyz,

}
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_N_PROFILES));
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_N_PROFILES - 1));
}
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT)
{

{
bsdfData.diffuseColor = baseColor;
bsdfData.fresnel0 = 0.028; // TODO take from subsurfaceProfile
bsdfData.subsurfaceProfile = SSS_N_PROFILES * inGBuffer2.a;
bsdfData.subsurfaceProfile = (SSS_N_PROFILES - 1) * inGBuffer2.a;
bsdfData.enableTransmission = (1 << bsdfData.subsurfaceProfile) & _TransmissionFlags;
bsdfData.enableTransmission = IsBitSet(_TransmissionFlags, bsdfData.subsurfaceProfile);
if (bsdfData.enableTransmission)
{
bsdfData.transmittance = ComputeTransmittance(_HalfRcpVariancesAndLerpWeights[bsdfData.subsurfaceProfile][0].xyz,

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0
_AnisotropyMap("AnisotropyMap", 2D) = "white" {}
_SubsurfaceProfile("Subsurface Profile", Float) = 0
_SubsurfaceProfile("Subsurface Profile", Int) = 0
_SubsurfaceRadius("Subsurface Radius", Range(0.004, 1.0)) = 1.0
_SubsurfaceRadiusMap("Subsurface Radius Map", 2D) = "white" {}
_Thickness("Thickness", Range(0.004, 1.0)) = 1.0

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


#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#define UNITY_MATERIAL_LIT // Need to be defined before including Material.hlsl
#define UNITY_MATERIAL_LIT // Needs to be defined before including Material.hlsl
#include "../../../Material/Material.hlsl"
//-------------------------------------------------------------------------------------

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); // R = SSS radius, G = SSS thickness, A = SSS profile
TEXTURE2D(_IrradianceSource); // RGB = irradiance on the back side of the object
TEXTURE2D(_IrradianceSource); // RGB = irradiance on the back side of the object
DECLARE_GBUFFER_TEXTURE(_GBufferTexture); // Contains the albedo and SSS parameters
//-------------------------------------------------------------------------------------
// Implementation

{
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, uint2(0, 0));
float2 gBufferData = LOAD_TEXTURE2D(_GBufferTexture2, posInput.unPositionSS).ra;
int profileID = N_PROFILES * gBufferData.y;
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule).
float distScale = (1.0 / 300.0) * gBufferData.x;
float invDistScale = rcp(distScale);
float3 unused;
BSDFData bsdfData;
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
DECODE_FROM_GBUFFER(gbuffer, bsdfData, unused);
int profileID = bsdfData.subsurfaceProfile;
float distScale = bsdfData.subsurfaceRadius;
float invDistScale = rcp(distScale);
// Reconstruct the view-space position.
float rawDepth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).r;

totalWeight += sampleWeight;
}
#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
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, profileID);
#ifdef FILTER_HORIZONTAL_AND_COMBINE
// It's either post-scatter, or pre- and post-scatter texturing.
float3 diffuseContrib = performPostScatterTexturing ? bsdfData.diffuseColor
: sqrt(bsdfData.diffuseColor);
return float4(diffuseContrib * totalIrradiance / totalWeight, 1.0);
#else
return float4(totalIrradiance / totalWeight, 1.0);

198
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs


[Serializable]
public class SubsurfaceScatteringProfile : ScriptableObject
{
public enum TexturingMode : int { PreAndPostScatter = 0, PostScatter = 1 };
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev1;
[SerializeField, ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev2;
[ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev1;
[ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
public Color stdDev2;
public float lerpWeight;
public TexturingMode texturingMode;
public bool enableTransmission;
public Vector2 thicknessRemap;
[HideInInspector]
public int settingsIndex;
public float lerpWeight;
Vector4[] m_FilterKernel;
public bool enableTransmission;
Vector3[] m_HalfRcpVariances;
public Vector2 thicknessRemap;
[SerializeField] [HideInInspector]
public int settingsIndex;
[SerializeField] [HideInInspector]
Vector4[] m_FilterKernel;
[SerializeField] [HideInInspector]
Vector3[] m_HalfRcpVariances;
[SerializeField] [HideInInspector]
Vector4 m_HalfRcpWeightedVariances;
private static SubsurfaceScatteringProfile s_DefaultProfile = null; // Singleton
Vector4 m_HalfRcpWeightedVariances;
public static SubsurfaceScatteringProfile defaultProfile
{
get
{
if (s_DefaultProfile == null)
{
#if UNITY_EDITOR
s_DefaultProfile = CreateInstance<SubsurfaceScatteringProfile>();
AssetDatabase.CreateAsset(s_DefaultProfile, "Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset");
AssetDatabase.SaveAssets();
#else
throw new UnassignedReferenceException("SubsurfaceScatteringProfile.defaultProfile can not be null.");
#endif
}
return s_DefaultProfile;
}
}
texturingMode = TexturingMode.PreAndPostScatter;
settingsIndex = 0;
settingsIndex = SubsurfaceScatteringSettings.neutralProfileID; // Updated by SubsurfaceScatteringSettings.OnValidate() once assigned
UpdateKernelAndVarianceData();
}

[Serializable]
public class SubsurfaceScatteringSettings
{
public enum TexturingMode : int { PreScatter = 0, PostScatter = 1, PreAndPostScatter = 2, MaxValue = 2 };
public const int maxNumProfiles = 8;
public const int maxNumProfiles = 8;
public const int neutralProfileID = 7;
public TexturingMode texturingMode;
public int transmissionFlags;
public float[] thicknessRemaps;
public Vector4[] halfRcpVariancesAndLerpWeights;
public Vector4[] halfRcpWeightedVariances;
public Vector4[] filterKernels;
// Below is the cache filled during OnValidate().
[NonSerialized] public int texturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter
[NonSerialized] public int transmissionFlags; // 1 bit/profile; 0 = inf. thick, 1 = supports transmission
[NonSerialized] public float[] thicknessRemaps;
[NonSerialized] public Vector4[] halfRcpVariancesAndLerpWeights;
[NonSerialized] public Vector4[] halfRcpWeightedVariances;
[NonSerialized] public Vector4[] filterKernels;
// --- Public Methods ---

texturingMode = TexturingMode.PreScatter;
profiles = null;
profiles = new SubsurfaceScatteringProfile[numProfiles];
profiles[0] = null;
texturingModeFlags = 0;
transmissionFlags = 0;
thicknessRemaps = null;
halfRcpVariancesAndLerpWeights = null;
halfRcpWeightedVariances = null;

public void OnValidate()
{
if (profiles == null)
{
// It will be called during the initialization of the HDRenderPipeline.
CreateProfiles();
}
numProfiles = Math.Max(1, Math.Min(profiles.Length, maxNumProfiles));
// Reserve one slot for the neutral profile.
numProfiles = Math.Min(profiles.Length, maxNumProfiles - 1);
if (profiles.Length != numProfiles)
{

for (int i = 0; i < numProfiles; i++)
{
if (profiles[i] == null)
if (profiles[i] != null)
// No invalid/empty assets allowed!
profiles[i] = SubsurfaceScatteringProfile.defaultProfile;
// Assign the profile IDs.
profiles[i].settingsIndex = i;
// Assign profile IDs.
profiles[i].settingsIndex = i;
texturingMode = (TexturingMode)Math.Max(0, Math.Min((int)texturingMode, (int)TexturingMode.MaxValue));
if (thicknessRemaps == null || thicknessRemaps.Length != (maxNumProfiles * 2))
{

filterKernels = new Vector4[maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
}
transmissionFlags = 0;
transmissionFlags |= (profiles[i].enableTransmission ? 1 : 0) << i;
// Skip unassigned profiles.
if (profiles[i] == null) continue;
c.r = Mathf.Clamp(profiles[i].stdDev1.r, 0.05f, 2.0f);
c.g = Mathf.Clamp(profiles[i].stdDev1.g, 0.05f, 2.0f);

profiles[i].UpdateKernelAndVarianceData();
}
texturingModeFlags = 0;
transmissionFlags = 0;
// Skip unassigned profiles.
if (profiles[i] == null) continue;
texturingModeFlags |= ((int)profiles[i].texturingMode) << i;
transmissionFlags |= (profiles[i].enableTransmission ? 1 : 0) << i;
thicknessRemaps[2 * i] = profiles[i].thicknessRemap.x;
thicknessRemaps[2 * i + 1] = profiles[i].thicknessRemap.y - profiles[i].thicknessRemap.x;
halfRcpVariancesAndLerpWeights[2 * i] = profiles[i].halfRcpVariances[0];

filterKernels[n * i + j] = profiles[i].filterKernel[j];
}
}
}
// --- Private Methods ---
// Fill the neutral profile.
{
int i = neutralProfileID;
// Limitation of Unity - cannot create assets in the constructor.
public void CreateProfiles()
{
profiles = new SubsurfaceScatteringProfile[numProfiles];
halfRcpWeightedVariances[i] = Vector4.one;
for (int i = 0; i < numProfiles; i++)
{
profiles[i] = SubsurfaceScatteringProfile.defaultProfile;
for (int j = 0, n = SubsurfaceScatteringProfile.numSamples; j < n; j++)
{
filterKernels[n * i + j] = Vector4.one;
filterKernels[n * i + j].w = 0.0f;
}
}
}
}

public class SubsurfaceScatteringProfileEditor : Editor {
private class Styles
{
public readonly GUIContent sssProfilePreview0 = new GUIContent("Profile preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as radius increases to 1.");
public readonly GUIContent sssProfilePreview2 = new GUIContent("Note that the intensity of the region in the center may be clamped.");
public readonly GUIContent sssTransmittancePreview0 = new GUIContent("Transmittance preview");
public readonly GUIContent sssTransmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object as thickness increases to 1.");
public readonly GUIContent sssProfileStdDev1 = new GUIContent("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("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("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 sssProfilePreview0 = new GUIContent("Profile preview");
public readonly GUIContent sssProfilePreview1 = new GUIContent("Shows the fraction of light scattered from the source as radius increases to 1.");
public readonly GUIContent sssProfilePreview2 = new GUIContent("Note that the intensity of the region in the center may be clamped.");
public readonly GUIContent sssTransmittancePreview0 = new GUIContent("Transmittance preview");
public readonly GUIContent sssTransmittancePreview1 = new GUIContent("Shows the fraction of light passing through the object as thickness increases to 1.");
public readonly GUIContent sssProfileStdDev1 = new GUIContent("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("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("Filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssTexturingMode = new GUIContent("Texturing mode", "Specifies when the diffuse texture should be applied.");
public readonly GUIContent[] sssTexturingModeOptions = new GUIContent[2] { new GUIContent("Pre- and post-scatter", "Texturing is performed during both the lighting and the SSS passes. Slightly blurs the diffuse texture. Choose this mode if your diffuse texture contains little to no SSS lighting."),
new GUIContent("Post-scatter", "Texturing is performed only during the SSS pass. Effectively preserves the sharpness of the diffuse texture. Choose this mode if your diffuse texture already contains SSS lighting (e.g. a photo of skin).") };
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 GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);
public readonly GUIStyle centeredMiniBoldLabel = new GUIStyle(GUI.skin.label);
public Styles()
{

private static Styles s_Styles = null;
private RenderTexture m_ProfileImage, m_TransmittanceImage;
private RenderTexture m_ProfileImage, m_TransmittanceImage;
private SerializedProperty m_ProfileStdDev1, m_ProfileStdDev2,
m_ProfileLerpWeight, m_ProfileTransmission,
m_ProfileThicknessRemap;
private SerializedProperty m_StdDev1, m_StdDev2, m_LerpWeight,
m_TexturingMode, m_Transmission, m_ThicknessRemap;
m_ProfileStdDev1 = serializedObject.FindProperty("stdDev1");
m_ProfileStdDev2 = serializedObject.FindProperty("stdDev2");
m_ProfileLerpWeight = serializedObject.FindProperty("lerpWeight");
m_ProfileTransmission = serializedObject.FindProperty("enableTransmission");
m_ProfileThicknessRemap = serializedObject.FindProperty("thicknessRemap");
m_StdDev1 = serializedObject.FindProperty("stdDev1");
m_StdDev2 = serializedObject.FindProperty("stdDev2");
m_LerpWeight = serializedObject.FindProperty("lerpWeight");
m_TexturingMode = serializedObject.FindProperty("texturingMode");
m_Transmission = serializedObject.FindProperty("enableTransmission");
m_ThicknessRemap = serializedObject.FindProperty("thicknessRemap");
m_ProfileMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawGaussianProfile");
m_TransmittanceMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/DrawTransmittanceGraph");

EditorGUI.BeginChangeCheck();
{
EditorGUILayout.PropertyField(m_ProfileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(m_ProfileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(m_ProfileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(m_ProfileTransmission, styles.sssProfileTransmission);
EditorGUILayout.PropertyField(m_StdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(m_StdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(m_LerpWeight, styles.sssProfileLerpWeight);
m_TexturingMode.intValue = EditorGUILayout.Popup(styles.sssTexturingMode, m_TexturingMode.intValue, styles.sssTexturingModeOptions);
EditorGUILayout.PropertyField(m_Transmission, styles.sssProfileTransmission);
Vector2 thicknessRemap = m_ProfileThicknessRemap.vector2Value;
Vector2 thicknessRemap = m_ThicknessRemap.vector2Value;
m_ProfileThicknessRemap.vector2Value = thicknessRemap;
m_ThicknessRemap.vector2Value = thicknessRemap;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.sssProfilePreview0, styles.centeredMiniBoldLabel);

}
// Draw the profile.
m_ProfileMaterial.SetColor("_StdDev1", m_ProfileStdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", m_ProfileStdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", m_ProfileLerpWeight.floatValue);
m_ProfileMaterial.SetColor("_StdDev1", m_StdDev1.colorValue);
m_ProfileMaterial.SetColor("_StdDev2", m_StdDev2.colorValue);
m_ProfileMaterial.SetFloat("_LerpWeight", m_LerpWeight.floatValue);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(256, 256), m_ProfileImage, m_ProfileMaterial, ScaleMode.ScaleToFit, 1.0f);
EditorGUILayout.Space();

// Draw the transmittance graph.
m_TransmittanceMaterial.SetColor("_StdDev1", m_ProfileStdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", m_ProfileStdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", m_ProfileLerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", m_ProfileThicknessRemap.vector2Value);
m_TransmittanceMaterial.SetColor("_StdDev1", m_StdDev1.colorValue);
m_TransmittanceMaterial.SetColor("_StdDev2", m_StdDev2.colorValue);
m_TransmittanceMaterial.SetFloat("_LerpWeight", m_LerpWeight.floatValue);
m_TransmittanceMaterial.SetVector("_ThicknessRemap", m_ThicknessRemap.vector2Value);
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(16, 16), m_TransmittanceImage, m_TransmittanceMaterial, ScaleMode.ScaleToFit, 16.0f);
serializedObject.ApplyModifiedProperties();

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs


// It will allow to display our common parameters + setup keyword correctly for them
protected abstract void FindMaterialProperties(MaterialProperty[] props);
protected abstract void SetupMaterialKeywordsAndPassInternal(Material material);
protected abstract void MaterialPropertiesGUI();
protected abstract void MaterialPropertiesGUI(Material material);
// This function will said if emissive is use or not regarding enlighten/PVR
protected abstract bool ShouldEmissionBeEnabled(Material material);

EditorGUILayout.Space();
EditorGUILayout.Space();
MaterialPropertiesGUI();
MaterialPropertiesGUI(material);
DoEmissionArea(material);
m_MaterialEditor.EnableInstancingField();

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/UnlitUI.cs


emissiveIntensity = FindProperty(kEmissiveIntensity, props);
}
protected override void MaterialPropertiesGUI()
protected override void MaterialPropertiesGUI(Material material)
{
GUILayout.Label(Styles.InputsText, EditorStyles.boldLabel);

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/FragInputs.hlsl


ZERO_INITIALIZE(FragInputs, output);
// Init to some default value to make the computer quiet (else it output "divide by zero" warning even if value is not used).
output.worldToTangent[0] = float3(0.0, 0.0, 1.0);
output.worldToTangent[2] = float3(0.0, 0.0, 1.0);
output.worldToTangent[0] = float3(1, 0, 0);
output.worldToTangent[1] = float3(0, 1, 0);
output.worldToTangent[2] = float3(0, 0, 1);
return output;
}

5
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


}
#endif // INTRINSIC_BITFIELD_EXTRACT
bool IsBitSet(uint number, uint bitPos)
{
return ((number >> bitPos) & 1) != 0;
}
#ifndef INTRINSIC_CLAMP
// TODO: should we force all clamp to be intrinsic by default ?
// Some platform have one instruction clamp

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.1.0a5
m_EditorVersion: 2017.1.0a6

35
Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6e7465350bf0d248b4799d98e18cd24, type: 3}
m_Name: Default SSS Profile
m_EditorClassIdentifier:
stdDev1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
stdDev2: {r: 0.6, g: 0.6, b: 0.6, a: 0}
lerpWeight: 0.5
enableTransmission: 0
thicknessRemap: {x: 0, y: 1}
settingsIndex: 0
m_FilterKernel:
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.7609476}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.49358216}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: -0.000000048879357}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.10326859}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.21256521}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.33642715}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.4935822}
- {x: 0.09090909, y: 0.09090909, z: 0.09090909, w: 0.7609475}
m_HalfRcpVariances:
- {x: 5.5555553, y: 5.5555553, z: 5.5555553}
- {x: 1.3888888, y: 1.3888888, z: 1.3888888}
m_HalfRcpWeightedVariances: {x: 2.4691355, y: 2.4691355, z: 2.4691355, w: 2.4691355}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Default SSS Profile.asset.meta


fileFormatVersion: 2
guid: 09521380d86baee43bf09b32473ea5f3
timeCreated: 1490117690
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存