浏览代码

add support of basic specular occlusion (intersection of cone)

/main
Sebastien Lagarde 7 年前
当前提交
23bcdad7
共有 9 个文件被更改,包括 73 次插入5 次删除
  1. 31
      ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl
  2. 5
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  3. 3
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  4. 3
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  5. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  6. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  7. 22
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  8. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  9. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader

31
ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl


return saturate(PositivePow(NdotV + ambientOcclusion, exp2(-16.0 * roughness - 1.0)) - 1.0 + ambientOcclusion);
}
// Based on Oat and Sander's 2008 technique
// Area/solidAngle of intersection of two cone
float SphericalCapIntersectionSolidArea(float cosC1, float cosC2, float cosB)
{
float r1 = FastACos(cosC1);
float r2 = FastACos(cosC2);
float rd = FastACos(cosB);
float area = 0.0;
if (rd <= max(r1, r2) - min(r1, r2))
{
// One cap is completely inside the other
area = TWO_PI - TWO_PI * max(cosC1, cosC2);
}
else if (rd >= r1 + r2)
{
// No intersection exists
area = 0.0;
}
else
{
float diff = abs(r1 - r2);
float den = r1 + r2 - diff;
float x = 1.0 - saturate((rd - diff) / den);
area = smoothstep(0.0, 1.0, x);
area *= TWO_PI - TWO_PI * max(cosC1, cosC2);
}
return area;
}
//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------

5
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs


{
string propertyName = ShaderUtil.GetPropertyName(layerShader, i);
string layerPropertyName = propertyName + layerIndex;
if (!exclusionList.Contains(propertyName) || !excludeUVMappingProperties)
{
if (material.HasProperty(layerPropertyName))

}
bool DoMaterialReferencesGUI(AssetImporter materialImporter)
{
{
EditorGUILayout.LabelField(styles.materialReferencesText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;

}
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_ENABLESPECULAROCCLUSION", material.GetFloat(kEnableSpecularOcclusion) > 0.0f);
SetKeyword(material, "_MAIN_LAYER_INFLUENCE_MODE", material.GetFloat(kkUseMainLayerInfluence) != 0.0f);

3
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_ShiverDrag("Shiver Drag", float) = 0.2
_ShiverDirectionality("Shiver Directionality", Range(0.0, 1.0)) = 0.5
[ToggleOff] _EnableSpecularOcclusion("Enable specular occlusion", Float) = 0.0
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}
_EmissiveIntensity("EmissiveIntensity", Float) = 0

#pragma shader_feature _BENTNORMALMAP2
#pragma shader_feature _BENTNORMALMAP3
#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _ENABLESPECULAROCCLUSION
#pragma shader_feature _HEIGHTMAP0
#pragma shader_feature _HEIGHTMAP1
#pragma shader_feature _HEIGHTMAP2

3
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader


_ShiverDrag("Shiver Drag", float) = 0.2
_ShiverDirectionality("Shiver Directionality", Range(0.0, 1.0)) = 0.5
[ToggleOff] _EnableSpecularOcclusion("Enable specular occlusion", Float) = 0.0
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}
_EmissiveIntensity("EmissiveIntensity", Float) = 0

#pragma shader_feature _BENTNORMALMAP2
#pragma shader_feature _BENTNORMALMAP3
#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _ENABLESPECULAROCCLUSION
#pragma shader_feature _HEIGHTMAP0
#pragma shader_feature _HEIGHTMAP1
#pragma shader_feature _HEIGHTMAP2

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


// Specular color
public static GUIContent specularColorText = new GUIContent("Specular Color", "Specular color (RGB)");
// Specular occlusion
public static GUIContent enableSpecularOcclusionText = new GUIContent("Enable Specular Occlusion", "Require cosine weighted bent normal and cosine weighted ambient occlusion. Specular occlusion for reflection probe");
// Emissive
public static string lightingText = "Lighting Inputs";
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive");

protected const string kEmissiveIntensity = "_EmissiveIntensity";
protected MaterialProperty albedoAffectEmissive = null;
protected const string kAlbedoAffectEmissive = "_AlbedoAffectEmissive";
protected MaterialProperty enableSpecularOcclusion = null;
protected const string kEnableSpecularOcclusion = "_EnableSpecularOcclusion";
protected void FindMaterialLayerProperties(MaterialProperty[] props)
{

emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);
albedoAffectEmissive = FindProperty(kAlbedoAffectEmissive, props);
enableSpecularOcclusion = FindProperty(kEnableSpecularOcclusion, props);
}
protected override void FindMaterialProperties(MaterialProperty[] props)

EditorGUILayout.LabelField(Styles.lightingText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(enableSpecularOcclusion, Styles.enableSpecularOcclusionText);
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.ShaderProperty(albedoAffectEmissive, Styles.albedoAffectEmissiveText);

}
SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap));
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_ENABLESPECULAROCCLUSION", material.GetFloat(kEnableSpecularOcclusion) > 0.0f);
SetKeyword(material, "_HEIGHTMAP", material.GetTexture(kHeightMap));
SetKeyword(material, "_ANISOTROPYMAP", material.GetTexture(kAnisotropyMap));
SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));

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


// Following options are for the GUI inspector and different from the input parameters above
// These option below will cause different compilation flag.
[ToggleOff] _EnableSpecularOcclusion("Enable specular occlusion", Float) = 0.0
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}

#pragma shader_feature _MASKMAP
#pragma shader_feature _BENTNORMALMAP
#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _ENABLESPECULAROCCLUSION
#pragma shader_feature _HEIGHTMAP
#pragma shader_feature _TANGENTMAP
#pragma shader_feature _ANISOTROPYMAP

22
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


#include "../../../Core/ShaderLibrary/SampleUVMapping.hlsl"
#include "../MaterialUtilities.hlsl"
// TODO: move this function to commonLighting.hlsl once validated it work correctly
float GetSpecularOcclusionFromBentAO(float3 V, float3 bentNormalWS, SurfaceData surfaceData)
{
// Retrieve cone angle
// Ambient occlusion is cosine weighted, thus use following equation. See slide 129
float cosAv = sqrt(1.0 - surfaceData.ambientOcclusion);
float roughness = PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness);
float cosAs = exp2(-3.32193 * Sqr(roughness));
float cosB = dot(bentNormalWS, reflect(-V, surfaceData.normalWS));
return SphericalCapIntersectionSolidArea(cosAv, cosAs, cosB) / (TWO_PI * (1.0 - cosAs));
}
void GetBuiltinData(FragInputs input, SurfaceData surfaceData, float alpha, float3 bentNormalWS, float depthOffset, out BuiltinData builtinData)
{

surfaceData.specularOcclusion = 1.0;
#ifdef _BENTNORMALMAP
GetNormalWS(input, V, bentNormalTS, bentNormalWS);
#ifdef _ENABLESPECULAROCCLUSION
surfaceData.specularOcclusion = 1.0; // TODO
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData);
#endif
#else
bentNormalWS = surfaceData.normalWS;
#endif

mappingType = UV_MAPPING_TRIPLANAR;
#endif
// Note: Blend mask have its dedicated mapping and tiling.
// Note: Blend mask have its dedicated mapping and tiling.
// To share code, we simply call the regular code from the main layer for it then save the result, then do regular call for all layers.
ComputeLayerTexCoord0( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMaskBlendMask, _UVMappingMaskBlendMask,
positionWS, mappingType, _TexWorldScaleBlendMask, layerTexCoord, _LayerTilingBlendMask);

surfaceData.specularOcclusion = 1.0;
#if defined(_BENTNORMALMAP0) || defined(_BENTNORMALMAP1) || defined(_BENTNORMALMAP2) || defined(_BENTNORMALMAP3)
GetNormalWS(input, V, bentNormalTS, bentNormalWS);
#ifdef _ENABLESPECULAROCCLUSION
surfaceData.specularOcclusion = 1.0; // TODO
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData);
#endif
#else // if no bent normal are available at all just keep the calculation fully
bentNormalWS = surfaceData.normalWS;
#endif

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl


float _EmissiveIntensity;
float _AlbedoAffectEmissive;
float _EnableSpecularOcclusion;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.
// In our case we don't use such a mechanism but need to keep the code quiet. We declare the value and always enable it.

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


// Following options are for the GUI inspector and different from the input parameters above
// These option below will cause different compilation flag.
[ToggleOff] _EnableSpecularOcclusion("Enable specular occlusion", Float) = 0.0
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}

#pragma shader_feature _MASKMAP
#pragma shader_feature _SPECULAROCCLUSIONMAP
#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _ENABLESPECULAROCCLUSION
#pragma shader_feature _HEIGHTMAP
#pragma shader_feature _TANGENTMAP
#pragma shader_feature _ANISOTROPYMAP

正在加载...
取消
保存