浏览代码

-Add base 2 lobe specular GGX along with inputs and UI.

-Fix missing base* keyword setting and gui virtual function callbacks (in addition to their abstract equivalent already handled) (see BaseUnlitUI)
/main
Stephane Laroche 7 年前
当前提交
ad31624f
共有 7 个文件被更改,包括 777 次插入47 次删除
  1. 278
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs
  2. 37
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs
  3. 92
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs.hlsl
  4. 123
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl
  5. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader
  6. 239
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl
  7. 23
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitProperties.hlsl

278
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs


protected static class Styles
{
public static string InputsText = "Inputs";
public static GUIContent doubleSidedNormalModeText = new GUIContent("Normal mode", "This will modify the normal base on the selected mode. Mirror: Mirror the normal with vertex normal plane, Flip: Flip the normal");
// Scalar scale factors for: metallic and the two lobe perceptual smoothness.
public static GUIContent metallicText = new GUIContent("Metallic", "Metallic scale factor");
public static GUIContent smoothnessAText = new GUIContent("Primary Lobe Smoothness", "Primary lobe smoothness scale factor");
public static GUIContent smoothnessBText = new GUIContent("Secondary Lobe Smoothness", "Secondary lobe smoothness scale factor");
public static GUIContent lobeMixText = new GUIContent("Lobe Mixing", "Lobe mixing factor");
public static GUIContent smoothnessARemappingText = new GUIContent("Primary Lobe Smoothness Remapping", "Primary lobe smoothness remapping");
public static GUIContent smoothnessBRemappingText = new GUIContent("Secondary Lobe Smoothness Remapping", "Secondary lobe smoothness remapping");
public static GUIContent maskMapASText = new GUIContent("Primary mask map - M(R), AO(G), D(B), S1(A)", "Primary mask map");
public static GUIContent maskMapBSText = new GUIContent("Secondary mask Map - (R), (G), (B), S2(A)", "Secondary mask map");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (BC7/BC5/DXT5(nm))");
public static GUIContent UVBaseMappingText = new GUIContent("UV mapping usage", "");
// Emissive
public static string emissiveLabelText = "Emissive Inputs";
public enum DoubleSidedNormalMode
{
Flip,
Mirror,
None
}
public enum UVBaseMapping
{
UV0,
UV1,
UV2,
UV3,
Planar,
Triplanar
}
protected MaterialProperty doubleSidedNormalMode = null;
protected const string kDoubleSidedNormalMode = "_DoubleSidedNormalMode";
// Example UV mapping mask, TODO: could have for multiple maps, and channel mask for scalars
protected MaterialProperty UVBase = null;
protected const string kUVBase = "_UVBase";
protected MaterialProperty UVMappingMask = null;
protected const string kUVMappingMask = "_UVMappingMask"; // hidden, see enum material property drawer in .shader
protected MaterialProperty baseColor = null;
protected const string kBaseColor = "_BaseColor";

protected const string kMetallic = "_Metallic";
protected MaterialProperty metallic = null;
// Primary lobe smoothness
protected MaterialProperty smoothnessA = null;
protected const string kSmoothnessA = "_SmoothnessA";
protected MaterialProperty smoothnessARemapMin = null;
protected const string kSmoothnessARemapMin = "_SmoothnessARemapMin";
protected MaterialProperty smoothnessARemapMax = null;
protected const string kSmoothnessARemapMax = "_SmoothnessARemapMax";
protected const string klobeMix = "_LobeMix";
protected MaterialProperty lobeMix = null;
// Secondary lobe smoothness
protected MaterialProperty smoothnessB = null;
protected const string kSmoothnessB = "_SmoothnessB";
protected MaterialProperty smoothnessBRemapMin = null;
protected const string kSmoothnessBRemapMin = "_SmoothnessBRemapMin";
protected MaterialProperty smoothnessBRemapMax = null;
protected const string kSmoothnessBRemapMax = "_SmoothnessBRemapMax";
// Two mask maps for the two smoothnesses
protected MaterialProperty maskMapA = null;
protected const string kMaskMapA = "_MaskMapA";
protected MaterialProperty maskMapB = null;
protected const string kMaskMapB = "_MaskMapB";
protected MaterialProperty normalScale = null;
protected const string kNormalScale = "_NormalScale";
protected MaterialProperty normalMap = null;
protected const string kNormalMap = "_NormalMap";
protected MaterialProperty emissiveColor = null;
protected const string kEmissiveColor = "_EmissiveColor";
protected MaterialProperty emissiveColorMap = null;

protected MaterialProperty albedoAffectEmissive = null;
protected const string kAlbedoAffectEmissive = "_AlbedoAffectEmissive";
protected override void FindBaseMaterialProperties(MaterialProperty[] props)
{
base.FindBaseMaterialProperties(props);
doubleSidedNormalMode = FindProperty(kDoubleSidedNormalMode, props);
}
UVBase = FindProperty(kUVBase, props);
UVMappingMask = FindProperty(kUVMappingMask, props);
metallic = FindProperty(kMetallic, props);
smoothnessA = FindProperty(kSmoothnessA, props);
smoothnessARemapMin = FindProperty(kSmoothnessARemapMin, props);
smoothnessARemapMax = FindProperty(kSmoothnessARemapMax, props);
smoothnessB = FindProperty(kSmoothnessB, props);
smoothnessBRemapMin = FindProperty(kSmoothnessBRemapMin, props);
smoothnessBRemapMax = FindProperty(kSmoothnessBRemapMax, props);
lobeMix = FindProperty(klobeMix, props);
maskMapA = FindProperty(kMaskMapA, props);
maskMapB = FindProperty(kMaskMapB, props);
normalMap = FindProperty(kNormalMap, props);
normalScale = FindProperty(kNormalScale, props);
emissiveColor = FindProperty(kEmissiveColor, props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);

protected override void BaseMaterialPropertiesGUI()
{
base.BaseMaterialPropertiesGUI();
EditorGUI.indentLevel++;
// This follow double sided option, see BaseUnlitUI.BaseMaterialPropertiesGUI()
// Don't put anything between base.BaseMaterialPropertiesGUI(); above and this:
if (doubleSidedEnable.floatValue > 0.0f)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(doubleSidedNormalMode, Styles.doubleSidedNormalModeText);
EditorGUI.indentLevel--;
}
//TODO: m_MaterialEditor.ShaderProperty(enableMotionVectorForVertexAnimation, StylesBaseUnlit.enableMotionVectorForVertexAnimationText);
//refs to this ?
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(metallic, Styles.metallicText);
// maskMaps and smoothness rescaling controls:
if(maskMapA.textureValue == null)
{
m_MaterialEditor.ShaderProperty(smoothnessA, Styles.smoothnessAText);
}
else
{
float remapMin = smoothnessARemapMin.floatValue;
float remapMax = smoothnessARemapMax.floatValue;
EditorGUI.BeginChangeCheck();
EditorGUILayout.MinMaxSlider(Styles.smoothnessARemappingText, ref remapMin, ref remapMax, 0.0f, 1.0f);
if (EditorGUI.EndChangeCheck())
{
smoothnessARemapMin.floatValue = remapMin;
smoothnessARemapMax.floatValue = remapMax;
}
}
if(maskMapB.textureValue == null)
{
m_MaterialEditor.ShaderProperty(smoothnessB, Styles.smoothnessBText);
}
else
{
float remapMin = smoothnessBRemapMin.floatValue;
float remapMax = smoothnessBRemapMax.floatValue;
EditorGUI.BeginChangeCheck();
EditorGUILayout.MinMaxSlider(Styles.smoothnessBRemappingText, ref remapMin, ref remapMax, 0.0f, 1.0f);
if (EditorGUI.EndChangeCheck())
{
smoothnessBRemapMin.floatValue = remapMin;
smoothnessBRemapMax.floatValue = remapMax;
}
}
m_MaterialEditor.ShaderProperty(lobeMix, Styles.lobeMixText);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapASText, maskMapA);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapBSText, maskMapB);
// Normal map:
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap, normalScale);
// UV Mapping:
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck(); // UV mapping selection
m_MaterialEditor.ShaderProperty(UVBase, Styles.UVBaseMappingText);
UVBaseMapping uvBaseMapping = (UVBaseMapping)UVBase.floatValue;
float X, Y, Z, W;
X = (uvBaseMapping == UVBaseMapping.UV0) ? 1.0f : 0.0f;
Y = (uvBaseMapping == UVBaseMapping.UV1) ? 1.0f : 0.0f;
Z = (uvBaseMapping == UVBaseMapping.UV2) ? 1.0f : 0.0f;
W = (uvBaseMapping == UVBaseMapping.UV3) ? 1.0f : 0.0f;
UVMappingMask.colorValue = new Color(X, Y, Z, W);
//TODO:
//if ((uvBaseMapping == UVBaseMapping.Planar) || (uvBaseMapping == UVBaseMapping.Triplanar))
//{
// m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText);
//}
if (EditorGUI.EndChangeCheck()) // ...UV mapping selection
{
}
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
m_MaterialEditor.TextureScaleOffsetProperty(emissiveColorMap);
m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.ShaderProperty(albedoAffectEmissive, Styles.albedoAffectEmissiveText);
EditorGUI.indentLevel--; // inputs
EditorGUILayout.Space();
// Surface type:
var surfaceTypeValue = (SurfaceType)surfaceType.floatValue;
if (surfaceTypeValue == SurfaceType.Transparent)
{

--EditorGUI.indentLevel;
}
// TODO: see DoEmissiveGUI( ) in LitUI.cs: custom uvmapping for emissive
EditorGUILayout.Space();
EditorGUILayout.LabelField(Styles.emissiveLabelText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.ShaderProperty(albedoAffectEmissive, Styles.albedoAffectEmissiveText);
EditorGUI.indentLevel--;
}
protected override void MaterialPropertiesAdvanceGUI(Material material)

// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change
static public void SetupMaterialKeywordsAndPass(Material material)
{
//TODO see BaseLitUI.cs:SetupBaseLitKeywords (stencil etc)
bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f;
if (doubleSidedEnable)
{
DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode);
switch (doubleSidedNormalMode)
{
case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f));
break;
case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f));
break;
case DoubleSidedNormalMode.None: // None mode (in tangent space)
material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f));
break;
}
}
//NOTE: For SSS in forward and split lighting, obviously we don't have a gbuffer pass,
// so no stencil tagging there, but velocity? To check...
//TODO: stencil state, displacement, wind, depthoffset, tesselation
SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material);
//TODO: disable DBUFFER
CoreUtils.SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", true);
CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap));
CoreUtils.SetKeyword(material, "_MASKMAPA", material.GetTexture(kMaskMapA));
CoreUtils.SetKeyword(material, "_MASKMAPB", material.GetTexture(kMaskMapB));
bool needUV2 = (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV2;
bool needUV3 = (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV3;
if (needUV3)
{
material.DisableKeyword("_REQUIRE_UV2");
material.EnableKeyword("_REQUIRE_UV3");
}
else if (needUV2)
{
material.EnableKeyword("_REQUIRE_UV2");
material.DisableKeyword("_REQUIRE_UV3");
}
else
{
material.DisableKeyword("_REQUIRE_UV2");
material.DisableKeyword("_REQUIRE_UV3");
}
CoreUtils.SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
}

37
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs


{
public class StackLit : RenderPipelineMaterial
{
[GenerateHLSL(PackingRules.Exact)]
public enum MaterialFeatureFlags
{
LitStandard = 1 << 0
};
//-----------------------------------------------------------------------------
// SurfaceData
//-----------------------------------------------------------------------------

public struct SurfaceData
{
[SurfaceDataAttributes("Material Features")]
public uint materialFeatures;
// Standard
[SurfaceDataAttributes("Base Color", false, true)]
public Vector3 baseColor;

[SurfaceDataAttributes("Smoothness A")]
public float perceptualSmoothnessA;
[SurfaceDataAttributes("Smoothness B")]
public float perceptualSmoothnessB;
[SurfaceDataAttributes("Lobe Mixing")]
public float lobeMix;
[SurfaceDataAttributes("Metallic")]
public float metallic;
};
//-----------------------------------------------------------------------------

[GenerateHLSL(PackingRules.Exact, false, true, 1400)]
public struct BSDFData
{
public uint materialFeatures;
public Vector3 fresnel0;
public float perceptualRoughnessA;
public float perceptualRoughnessB;
public float lobeMix;
public float roughnessAT;
public float roughnessAB;
public float roughnessBT;
public float roughnessBB;
public float anisotropy;
//public fixed float test[2];
};
}
}

92
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs.hlsl


#ifndef STACKLIT_CS_HLSL
#define STACKLIT_CS_HLSL
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+MaterialFeatureFlags: static fields
//
#define MATERIALFEATUREFLAGS_LIT_STANDARD (1)
//
#define DEBUGVIEW_STACKLIT_SURFACEDATA_BASE_COLOR (1300)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL (1301)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL_VIEW_SPACE (1302)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_MATERIAL_FEATURES (1300)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_BASE_COLOR (1301)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL (1302)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL_VIEW_SPACE (1303)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A (1304)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B (1305)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING (1306)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_METALLIC (1307)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSE_COLOR (1400)
#define DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_WS (1401)
#define DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_VIEW_SPACE (1402)
#define DEBUGVIEW_STACKLIT_BSDFDATA_MATERIAL_FEATURES (1400)
#define DEBUGVIEW_STACKLIT_BSDFDATA_DIFFUSE_COLOR (1401)
#define DEBUGVIEW_STACKLIT_BSDFDATA_FRESNEL0 (1402)
#define DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_WS (1403)
#define DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_VIEW_SPACE (1404)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A (1405)
#define DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_B (1406)
#define DEBUGVIEW_STACKLIT_BSDFDATA_LOBE_MIXING (1407)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AT (1408)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AB (1409)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BT (1410)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BB (1411)
#define DEBUGVIEW_STACKLIT_BSDFDATA_ANISOTROPY (1412)
uint materialFeatures;
float perceptualSmoothnessA;
float perceptualSmoothnessB;
float lobeMix;
float metallic;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.StackLit+BSDFData

uint materialFeatures;
float3 fresnel0;
float perceptualRoughnessA;
float perceptualRoughnessB;
float lobeMix;
float roughnessAT;
float roughnessAB;
float roughnessBT;
float roughnessBB;
float anisotropy;
};
//

{
switch (paramId)
{
case DEBUGVIEW_STACKLIT_SURFACEDATA_MATERIAL_FEATURES:
result = GetIndexColor(surfacedata.materialFeatures);
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_BASE_COLOR:
result = surfacedata.baseColor;
needLinearToSRGB = true;

case DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL_VIEW_SPACE:
result = surfacedata.normalWS * 0.5 + 0.5;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_A:
result = surfacedata.perceptualSmoothnessA.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_SMOOTHNESS_B:
result = surfacedata.perceptualSmoothnessB.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_LOBE_MIXING:
result = surfacedata.lobeMix.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_METALLIC:
result = surfacedata.metallic.xxx;
break;
}
}

{
switch (paramId)
{
case DEBUGVIEW_STACKLIT_BSDFDATA_MATERIAL_FEATURES:
result = GetIndexColor(bsdfdata.materialFeatures);
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_FRESNEL0:
result = bsdfdata.fresnel0;
break;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_A:
result = bsdfdata.perceptualRoughnessA.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_PERCEPTUAL_ROUGHNESS_B:
result = bsdfdata.perceptualRoughnessB.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_LOBE_MIXING:
result = bsdfdata.lobeMix.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AT:
result = bsdfdata.roughnessAT.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_AB:
result = bsdfdata.roughnessAB.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BT:
result = bsdfdata.roughnessBT.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_ROUGHNESS_BB:
result = bsdfdata.roughnessBB.xxx;
break;
case DEBUGVIEW_STACKLIT_BSDFDATA_ANISOTROPY:
result = bsdfdata.anisotropy.xxx;
break;
}
}

123
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl


//#include "../SubsurfaceScattering/SubsurfaceScattering.hlsl"
//#include "CoreRP/ShaderLibrary/VolumeRendering.hlsl"
//NEWLITTODO : wireup CBUFFERs for ambientocclusion, and other uniforms and samplers used:
//NEWLITTODO : wireup CBUFFERs for ambientocclusion, and other uniforms and samplers used:
//-----------------------------------------------------------------------------
// Texture and constant buffer declaration
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Definition
//-----------------------------------------------------------------------------
#define DEFAULT_SPECULAR_VALUE 0.04
//-----------------------------------------------------------------------------
// Configuration
//-----------------------------------------------------------------------------
// TODO: once we use FGD pre-integration data
//#define LIT_USE_GGX_ENERGY_COMPENSATION
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material
//-----------------------------------------------------------------------------
// This method allows us to know at compile time what material features should be removed from the code by Tile (Indepenently of the value of material feature flag per pixel).
// This is only useful for classification during lighting, so it's not needed in EncodeIntoGBuffer and ConvertSurfaceDataToBSDFData (where we always know exactly what the material feature is)
bool HasFeatureFlag(uint featureFlags, uint flag)
{
return ((featureFlags & flag) != 0);
}
float3 ComputeDiffuseColor(float3 baseColor, float metallic)
{
return baseColor * (1.0 - metallic);
}
float3 ComputeFresnel0(float3 baseColor, float metallic, float dielectricF0)
{
return lerp(dielectricF0.xxx, baseColor, metallic);
}
// This function is use to help with debugging and must be implemented by any lit material
// Implementer must take into account what are the current override component and

// This function is similar to ApplyDebugToSurfaceData but for BSDFData
//
// NOTE:
// NOTE:
// This will be available and used in ShaderPassForward.hlsl since in StackLit.shader,
// just before including the core code of the pass (ShaderPassForward.hlsl) we include
// Material.hlsl (or Lighting.hlsl which includes it) which in turn includes us,
// This will be available and used in ShaderPassForward.hlsl since in StackLit.shader,
// just before including the core code of the pass (ShaderPassForward.hlsl) we include
// Material.hlsl (or Lighting.hlsl which includes it) which in turn includes us,
// StackLit.shader, via the #if defined(UNITY_MATERIAL_*) glue mechanism.
//
void ApplyDebugToBSDFData(inout BSDFData bsdfData)

// this can be use also in case of debug lighting mode like specular only
//NEWLITTODO
//bool overrideSpecularColor = _DebugLightingSpecularColor.x != 0.0;

BSDFData bsdfData;
ZERO_INITIALIZE(BSDFData, bsdfData);
// NEWLITTODO: will be much more involved obviously, and use metallic, etc.
bsdfData.diffuseColor = surfaceData.baseColor;
// IMPORTANT: In our forward only case, all enable flags are statically know at compile time, so the compiler can do compile time optimization
bsdfData.materialFeatures = surfaceData.materialFeatures;
// Two lobe base material
bsdfData.perceptualRoughnessA = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothnessA);
bsdfData.perceptualRoughnessB = PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothnessB);
bsdfData.lobeMix = surfaceData.lobeMix;
// There is no metallic with SSS and specular color mode
//todo: float metallic = HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION) ? 0.0 : surfaceData.metallic;
float metallic = surfaceData.metallic;
bsdfData.diffuseColor = ComputeDiffuseColor(surfaceData.baseColor, metallic);
bsdfData.fresnel0 = ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
// roughnessT and roughnessB are clamped, and are meant to be used with punctual and directional lights.
// perceptualRoughness is not clamped, and is meant to be used for IBL.
// TODO: add ui inputs, +tangent map, tangentws to use anisotropy; for now bsdfData.anisotropy = 0,
// so only bsdfData.roughnessT is used.
ConvertAnisotropyToClampRoughness(bsdfData.perceptualRoughnessA, bsdfData.anisotropy, bsdfData.roughnessAT, bsdfData.roughnessAB);
ConvertAnisotropyToClampRoughness(bsdfData.perceptualRoughnessB, bsdfData.anisotropy, bsdfData.roughnessBT, bsdfData.roughnessBB);
ApplyDebugToBSDFData(bsdfData);
return bsdfData;

// Overide debug value output to be more readable
switch (paramId)
{
case DEBUGVIEW_LIT_SURFACEDATA_NORMAL_VIEW_SPACE:
case DEBUGVIEW_STACKLIT_SURFACEDATA_NORMAL_VIEW_SPACE:
// Convert to view space
result = TransformWorldToViewDir(surfaceData.normalWS) * 0.5 + 0.5;
break;

// Overide debug value output to be more readable
switch (paramId)
{
case DEBUGVIEW_LIT_BSDFDATA_NORMAL_VIEW_SPACE:
case DEBUGVIEW_STACKLIT_BSDFDATA_NORMAL_VIEW_SPACE:
// Convert to view space
result = TransformWorldToViewDir(bsdfData.normalWS) * 0.5 + 0.5;
break;

//-----------------------------------------------------------------------------
// PreLightData
//
// PreLightData
//
// Make sure we respect naming conventions to reuse ShaderPassForward as is,
// ie struct (even if opaque to the ShaderPassForward) name is PreLightData,
// GetPreLightData prototype.

struct PreLightData
{
float NdotV; // Could be negative due to normal mapping, use ClampNdotV()
//NEWLITTODO
// GGX
float partLambdaV[2]; // One for each lobe
float energyCompensation;
};
PreLightData GetPreLightData(float3 V, PositionInputs posInput, inout BSDFData bsdfData)

float3 N = bsdfData.normalWS;
preLightData.NdotV = dot(N, V);
//float NdotV = ClampNdotV(preLightData.NdotV);
float NdotV = ClampNdotV(preLightData.NdotV);
preLightData.partLambdaV[0] = GetSmithJointGGXPartLambdaV(NdotV, bsdfData.roughnessAT);
preLightData.partLambdaV[1] = GetSmithJointGGXPartLambdaV(NdotV, bsdfData.roughnessBT);
// TODO: LIT_USE_GGX_ENERGY_COMPENSATION
return preLightData;
}

// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------
// NEWLITTODO
// This function apply BSDF. Assumes that NdotL is positive.
void BSDF( float3 V, float3 L, float NdotL, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,

float3 N = bsdfData.normalWS;
// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114).
float LdotV = dot(L, V);
float invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)), clamp to avoid rsqrt(0) = NaN
float NdotH = saturate((NdotL + preLightData.NdotV) * invLenLV); // Do not clamp NdotV here
float LdotH = saturate(invLenLV * LdotV + invLenLV);
float NdotV = ClampNdotV(preLightData.NdotV);
// TODO: Proper Fresnel
float3 F = F_Schlick(bsdfData.fresnel0, LdotH);
// TODO: with iridescence, will be per light sample.
float DV[2];
DV[0] = DV_SmithJointGGX(NdotH, NdotL, NdotV, bsdfData.roughnessAT, preLightData.partLambdaV[0]);
DV[1] = DV_SmithJointGGX(NdotH, NdotL, NdotV, bsdfData.roughnessBT, preLightData.partLambdaV[1]);
specularLighting = F * lerp(DV[0], DV[1], bsdfData.lobeMix);
// TODO: config option + diffuse GGX
specularLighting = float3(0.0, 0.0, 0.0);
// TODO: coat
}
//-----------------------------------------------------------------------------

float NdotL = dot(N, L);
//float LdotV = dot(L, V);
// color and attenuation are outputted by EvaluateLight:
// color and attenuation are outputted by EvaluateLight:
float3 color;
float attenuation;
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, N, L, color, attenuation);

return lighting;
}
// NEWLITTODO: For a refence rendering option for area light, like LIT_DISPLAY_REFERENCE_AREA option in eg EvaluateBSDF_<area light type> :
// NEWLITTODO: For a refence rendering option for area light, like LIT_DISPLAY_REFERENCE_AREA option in eg EvaluateBSDF_<area light type> :
//#include "LitReference.hlsl"
//-----------------------------------------------------------------------------

32
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader


_BaseColor("BaseColor", Color) = (1,1,1,1)
_BaseColorMap("BaseColorMap", 2D) = "white" {}
_Metallic("Metallic", Range(0.0, 1.0)) = 0
_SmoothnessA("SmoothnessA", Range(0.0, 1.0)) = 1.0
_SmoothnessARemapMin("SmoothnessARemapMin", Float) = 0.0
_SmoothnessARemapMax("SmoothnessARemapMax", Float) = 1.0
_SmoothnessB("SmoothnessB", Range(0.0, 1.0)) = 1.0
_SmoothnessBRemapMin("SmoothnessBRemapMin", Float) = 0.0
_SmoothnessBRemapMax("SmoothnessBRemapMax", Float) = 1.0
_LobeMix("lobeMix", Range(0.0, 1.0)) = 0
_MaskMapA("MaskMapA", 2D) = "white" {}
_MaskMapB("MaskMapB", 2D) = "white" {}
_NormalMap("NormalMap", 2D) = "bump" {} // Tangent space normal map
_NormalScale("_NormalScale", Range(0.0, 2.0)) = 1
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase("UV Set for base", Float) = 0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
_EmissiveColor("EmissiveColor", Color) = (1, 1, 1)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}
_EmissiveIntensity("EmissiveIntensity", Float) = 0

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _ _REQUIRE_UV2 _REQUIRE_UV3
// ...TODO: for surface gradient framework eg see litdata.hlsl,
// but we need it right away for toggle with LayerTexCoord mapping so we might need them
// from the Frag input right away. See also ShaderPass/StackLitSharePass.hlsl.
#pragma shader_feature _NORMALMAP
#pragma shader_feature _MASKMAPA
#pragma shader_feature _MASKMAPB
#pragma shader_feature _EMISSIVE_COLOR_MAP
// Keyword for transparent

239
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl


//-------------------------------------------------------------------------------------
// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------
#include "CoreRP/ShaderLibrary/Sampling/SampleUVMapping.hlsl"
//-----------------------------------------------------------------------------
// Texture Mapping (think of LayerTexCoord as simply TexCoordMappings,
// ie no more layers here - cf Lit materials)
//-----------------------------------------------------------------------------
//
// For easier copying of code for now use a LayerTexCoord wrapping struct.
// We don't have details yet.
//
// NEWLITTODO: Eventually, we could quickly share GetBuiltinData of LitBuiltinData.hlsl
// in our GetSurfaceAndBuiltinData( ) here, since we will use the LayerTexCoord identifier,
// and an identical ComputeLayerTexCoord( ) prototype
//
struct LayerTexCoord
{
UVMapping base;
UVMapping details;
// Store information that will be share by all UVMapping
float3 vertexNormalWS; // TODO: store also object normal map for object triplanar
};
// Want to use only one sampler for normalmap/bentnormalmap either we use OS or TS. And either we have normal map or bent normal or both.
//
// Note (compared to Lit shader):
//
// We don't have a layered material with which we are sharing code here like the LayeredLit shader, but we can also save a couple of
// samplers later if we use bentnormals.
//
// _IDX suffix is meaningless here, could use the name SAMPLER_NORMALMAP_ID instead of SAMPLER_NORMALMAP_IDX and replace all
// indirect #ifdef _NORMALMAP_TANGENT_SPACE_IDX #ifdef and _NORMALMAP_IDX tests with the more direct
// shader_feature keywords _NORMALMAP_TANGENT_SPACE and _NORMALMAP.
//
// (Originally in the LayeredLit shader, shader_feature keywords like _NORMALMAP become _NORMALMAP0 but since files are shared,
// LitDataIndividualLayer will use a generic _NORMALMAP_IDX defined before its inclusion by the client LitData or LayeredLitData.
// That way, LitDataIndividualLayer supports multiple inclusions)
//
//
#ifdef _NORMALMAP_TANGENT_SPACE
#if defined(_NORMALMAP)
#define SAMPLER_NORMALMAP_ID sampler_NormalMap
// TODO:
//#elif defined(_BENTNORMALMAP)
//#define SAMPLER_NORMALMAP_ID sampler_BentNormalMap
#endif
#else
// TODO:
//#error STACKLIT_USES_ONLY_TANGENT_SPACE_FOR_NOW
//#if defined(_NORMALMAP)
//#define SAMPLER_NORMALMAP_ID sampler_NormalMapOS
//#elif defined(_BENTNORMALMAP)
//#define SAMPLER_NORMALMAP_ID sampler_BentNormalMapOS
//#endif
#endif
void ComputeLayerTexCoord( // Uv related parameters
float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 uvMappingMask,
// scale and bias for base
float2 texScale, float2 texBias,
// mapping type and output
int mappingType, inout LayerTexCoord layerTexCoord)
{
//TODO: Planar, Triplanar, detail map, surface_gradient.
// Handle uv0, uv1, uv2, uv3 based on _UVMappingMask weight (exclusif 0..1)
float2 uvBase = uvMappingMask.x * texCoord0 +
uvMappingMask.y * texCoord1 +
uvMappingMask.z * texCoord2 +
uvMappingMask.w * texCoord3;
// Copy data in uvmapping fields: used by generic sampling code (see especially SampleUVMappingNormalInternal.hlsl)
layerTexCoord.base.mappingType = mappingType;
layerTexCoord.base.normalWS = layerTexCoord.vertexNormalWS;
// Apply tiling options
layerTexCoord.base.uv = uvBase * texScale + texBias;
}
float3 GetNormalTS(FragInputs input, LayerTexCoord layerTexCoord, float3 detailNormalTS, float detailMask)
{
// TODO: different spaces (eg #ifdef _NORMALMAP_TANGENT_SPACE #elif object space, SURFACE_GRADIENT, etc.)
// and use detail map
float3 normalTS;
// Note we don't use the _NORMALMAP_IDX mechanism of the Lit shader, since we don't have "layers", we can
// directly use the shader_feature keyword:
#ifdef _NORMALMAP
normalTS = SAMPLE_UVMAPPING_NORMALMAP(_NormalMap, SAMPLER_NORMALMAP_ID, layerTexCoord.base, _NormalScale);
#else
normalTS = float3(0.0, 0.0, 1.0);
#endif
return normalTS;
}
// This maybe call directly by tessellation (domain) shader, thus all part regarding surface gradient must be done
// in function with FragInputs input as parameters
// layerTexCoord must have been initialize to 0 outside of this function
void GetLayerTexCoord(float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3,
float3 positionWS, float3 vertexNormalWS, inout LayerTexCoord layerTexCoord)
{
layerTexCoord.vertexNormalWS = vertexNormalWS;
// TODO:
//layerTexCoord.triplanarWeights = ComputeTriplanarWeights(vertexNormalWS);
int mappingType = UV_MAPPING_UVSET;
//TODO: _MAPPING_PLANAR, _MAPPING_TRIPLANAR
// Be sure that the compiler is aware that we don't use UV1 to UV3 for main layer so it can optimize code
ComputeLayerTexCoord( texCoord0, texCoord1, texCoord2, texCoord3, _UVMappingMask, /* TODO _UVDetailsMappingMask, */
_BaseColorMap_ST.xy, _BaseColorMap_ST.zw, /* TODO _DetailMap_ST.xy, _DetailMap_ST.zw, 1.0, _LinkDetailsWithBase,
/* TODO positionWS, _TexWorldScale, */
mappingType, layerTexCoord);
}
// This is call only in this file
// layerTexCoord must have been initialize to 0 outside of this function
void GetLayerTexCoord(FragInputs input, inout LayerTexCoord layerTexCoord)
{
// TODO: SURFACE_GRADIENT
//#ifdef SURFACE_GRADIENT
//GenerateLayerTexCoordBasisTB(input, layerTexCoord);
//#endif
GetLayerTexCoord( input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
}
//-----------------------------------------------------------------------------
// ...Texture Mapping
//-----------------------------------------------------------------------------
//
// cf with
// LitData.hlsl:GetSurfaceAndBuiltinData()
// LitDataIndividualLayer.hlsl:GetSurfaceData( )
// LitBuiltinData.hlsl:GetBuiltinData()
//
// Here we can combine them
//
// NEWLITTODO:
// For now, just use the interpolated vertex normal. This has been normalized in the initial fragment interpolators unpacking.
// Eventually, we want to share all the LitData LayerTexCoord (and surface gradient frame + uv, planar, triplanar, etc.) logic, also
// spread in LitDataIndividualLayer and LitDataMeshModification.
surfaceData.normalWS = input.worldToTangent[2].xyz;
float2 baseColorMapUv = TRANSFORM_TEX(input.texCoord0, _BaseColorMap);
surfaceData.baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, baseColorMapUv).rgb * _BaseColor.rgb;
float alpha = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, baseColorMapUv).a * _BaseColor.a;
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
GetLayerTexCoord(input, layerTexCoord);
// -------------------------------------------------------------
// Surface Data:
// -------------------------------------------------------------
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;
// TODO: Those are only needed once we handle specular occlusion and optionnally bent normal maps.
// Also, for the builtinData part, use bentnormal to sample diffuse GI
//float3 bentNormalTS;
//float3 bentNormalWS;
//float alpha = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, baseColorMapUv).a * _BaseColor.a;
float alpha = SAMPLE_UVMAPPING_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, layerTexCoord.base).a * _BaseColor.a;
#ifdef _ALPHATEST_ON
//NEWLITTODO: Once we include those passes in the main StackLit.shader, add handling of CUTOFF_TRANSPARENT_DEPTH_PREPASS and _POSTPASS
// and the related properties (in the .shader) and uniforms (in the StackLitProperties file) _AlphaCutoffPrepass, _AlphaCutoffPostpass

// TODO detail map:
float3 detailNormalTS = float3(0.0, 0.0, 0.0);
float detailMask = 0.0;
//TODO remove the following and use fetching macros that use uvmapping :
//float2 baseColorMapUv = TRANSFORM_TEX(input.texCoord0, _BaseColorMap);
//surfaceData.baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, baseColorMapUv).rgb * _BaseColor.rgb;
surfaceData.baseColor = SAMPLE_UVMAPPING_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, layerTexCoord.base).rgb * _BaseColor.rgb;
//surfaceData.normalWS = float3(0.0, 0.0, 0.0);
normalTS = GetNormalTS(input, layerTexCoord, detailNormalTS, detailMask);
//TODO: bentNormalTS
#if defined(_MASKMAPA)
surfaceData.perceptualSmoothnessA = SAMPLE_UVMAPPING_TEXTURE2D(_MaskMapA, sampler_MaskMapA, layerTexCoord.base).a;
surfaceData.perceptualSmoothnessA = lerp(_SmoothnessARemapMin, _SmoothnessARemapMax, surfaceData.perceptualSmoothnessA);
#else
surfaceData.perceptualSmoothnessA = _SmoothnessA;
#endif
#if defined(_MASKMAPB)
surfaceData.perceptualSmoothnessB = SAMPLE_UVMAPPING_TEXTURE2D(_MaskMapB, sampler_MaskMapB, layerTexCoord.base).a;
surfaceData.perceptualSmoothnessB = lerp(_SmoothnessBRemapMin, _SmoothnessBRemapMax, surfaceData.perceptualSmoothnessB);
#else
surfaceData.perceptualSmoothnessB = _SmoothnessB;
#endif
// TODOSTACKLIT: lobe weighting
surfaceData.lobeMix = _LobeMix;
// MaskMapA is RGBA: Metallic, Ambient Occlusion (Optional), detail Mask (Optional), Smoothness
// TODO: Ambient occlusion, detail mask.
#ifdef _MASKMAPA
surfaceData.metallic = SAMPLE_UVMAPPING_TEXTURE2D(_MaskMapA, sampler_MaskMapA, layerTexCoord.base).r;
#else
surfaceData.metallic = 1.0;
#endif
surfaceData.metallic *= _Metallic;
// These static material feature allow compile time optimization
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
// -------------------------------------------------------------
// Surface Data Part 2 (outsite GetSurfaceData( ) in Lit shader):
// -------------------------------------------------------------
GetNormalWS(input, V, normalTS, surfaceData.normalWS); // MaterialUtilities.hlsl
// TODO: decal etc.
surfaceData.color = GetTextureDataDebug(_DebugMipMapMode, baseColorMapUv, _BaseColorMap, _BaseColorMap_TexelSize, _BaseColorMap_MipInfo, surfaceData.color);
surfaceData.baseColor = GetTextureDataDebug(_DebugMipMapMode, layerTexCoord.base.uv, _BaseColorMap, _BaseColorMap_TexelSize, _BaseColorMap_MipInfo, surfaceData.baseColor);
surfaceData.metallic = 0;
// Builtin Data
// -------------------------------------------------------------
// Builtin Data:
// -------------------------------------------------------------
// NEWLITTODO: for all BuiltinData, might need to just refactor and use a comon function like that
// contained in LitBuiltinData.hlsl

// Emissive Intensity is only use here, but is part of BuiltinData to enforce UI parameters as we want the users to fill one color and one intensity
builtinData.emissiveIntensity = _EmissiveIntensity;
builtinData.emissiveIntensity = _EmissiveIntensity; // We still store intensity here so we can reuse it with debug code
#ifdef _EMISSIVE_COLOR_MAP
builtinData.emissiveColor *= SAMPLE_TEXTURE2D(_EmissiveColorMap, sampler_EmissiveColorMap, TRANSFORM_TEX(input.texCoord0, _EmissiveColorMap)).rgb;

23
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitProperties.hlsl


TEXTURE2D(_BaseColorMap);
SAMPLER(sampler_BaseColorMap);
TEXTURE2D(_MaskMapA);
SAMPLER(sampler_MaskMapA);
TEXTURE2D(_MaskMapB);
SAMPLER(sampler_MaskMapB);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
CBUFFER_START(UnityPerMaterial)

float4 _BaseColorMap_MipInfo;
float _Metallic;
float _SmoothnessA;
float _SmoothnessARemapMin;
float _SmoothnessARemapMax;
float _SmoothnessB;
float _SmoothnessBRemapMin;
float _SmoothnessBRemapMax;
float _LobeMix;
float _NormalScale;
float4 _UVMappingMask;
float3 _EmissiveColor;
float4 _EmissiveColorMap_ST;

正在加载...
取消
保存