浏览代码

Uniformity, dual lobe material feature keyword.

/main
Stephane Laroche 7 年前
当前提交
6a42ea81
共有 7 个文件被更改,包括 67 次插入67 次删除
  1. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs
  2. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  3. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs
  4. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.cs.hlsl
  5. 47
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl
  6. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader
  7. 33
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl

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


//CoreUtils.SetKeyword(material, "_USE_UV3", requireUv3);
CoreUtils.SetKeyword(material, "_USE_TRIPLANAR", requireTriplanar);
bool clearCoatEnabled = material.HasProperty(k_CoatEnable) && (material.GetFloat(k_CoatEnable) > 0.0f);
bool coatEnabled = material.HasProperty(k_CoatEnable) && (material.GetFloat(k_CoatEnable) > 0.0f);
bool dualLobeEnabled = material.HasProperty(k_LobeMix) && (material.GetFloat(k_LobeMix) > 0.0f);
CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_CLEAR_COAT", clearCoatEnabled);
CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_COAT", coatEnabled);
CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_DUAL_LOBE", dualLobeEnabled);
}
}

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


// * the auto-thickness mode uses the baked (textured) thickness to compute transmission from
// indirect lighting and non-shadow-casting lights; for shadowed lights, it calculates
// the thickness using the distance to the closest occluder sampled from the shadow map.
// If the distance is large, it may indicate that the closest occluder is not a (back) face of
// the current object and thus shouldn't theorically be considered as defining its thickness
// (as long as the volume defined by the mesh is closed and well-behaved with no self-intersection).
// That's not a problem here however since large thickness will result in low intensity.
// If the distance is large, it may indicate that the closest occluder is not the back face of
// the current object. That's not a problem, since large thickness will result in low intensity.
bool useThinObjectMode = IsBitSet(asuint(_TransmissionFlags), diffusionProfile);
bsdfData.materialFeatures |= useThinObjectMode ? 0 : MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_MIXED_THICKNESS;

// Note: Reuse thickness of transmission's property set
FillMaterialTransparencyData( surfaceData.baseColor, surfaceData.metallic, surfaceData.ior, surfaceData.transmittanceColor, surfaceData.atDistance,
surfaceData.thickness, surfaceData.transmittanceMask, bsdfData);
//slnote: bugbug fresnel0 will be overwritten if clear_coat in GetPreLightData even if we don't
// evaluate its reflections in EvaluateBSDF_Env ! (see also FillMaterialTransparencyData)
#endif
ApplyDebugToBSDFData(bsdfData);

// Clear coat
float coatPartLambdaV;
float3 coatIblR;
float coatIblF; // Fresnel term for view vector:
float coatIblF; // Fresnel term for view vector
float3x3 ltcTransformCoat; // Inverse transformation for GGX (4x VGPRs)
float ltcMagnitudeCoatFresnel;

}
}
// slnote: bugbug fresnel0 will be overwritten if clear_coat in GetPreLightData even if we don't
// evaluate its reflections in EvaluateBSDF_Env! (see also FillMaterialTransparencyData: we expect
// the calculated fresnel0 from IOR there to take over for transparency / refractions.)
// We modify the bsdfData.fresnel0 here for clearCoat
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{

preLightData.coatPartLambdaV = GetSmithJointGGXPartLambdaV(NdotV, CLEAR_COAT_ROUGHNESS);
preLightData.coatIblR = reflect(-V, N);
preLightData.coatIblF = F_Schlick(CLEAR_COAT_F0, NdotV) * bsdfData.coatMask; // slnote: apparently we do that so we don't have another FGD fetch for clearcoat
preLightData.coatIblF = F_Schlick(CLEAR_COAT_F0, NdotV) * bsdfData.coatMask;
}
float3 iblN, iblR;

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


[GenerateHLSL(PackingRules.Exact)]
public enum MaterialFeatureFlags
{
LitStandard = 1 << 0,
LitAnisotropy = 1 << 4,
LitClearCoat = 1 << 6
StackLitStandard = 1 << 0,
StackLitAnisotropy = 1 << 4,
StackLitCoat = 1 << 6,
};
//-----------------------------------------------------------------------------

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


//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+MaterialFeatureFlags: static fields
//
#define MATERIALFEATUREFLAGS_LIT_STANDARD (1)
#define MATERIALFEATUREFLAGS_LIT_ANISOTROPY (16)
#define MATERIALFEATUREFLAGS_LIT_CLEAR_COAT (64)
#define MATERIALFEATUREFLAGS_STACK_LIT_STANDARD (1)
#define MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY (16)
#define MATERIALFEATUREFLAGS_STACK_LIT_COAT (64)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+SurfaceData: static fields

#define DEBUGVIEW_STACKLIT_SURFACEDATA_METALLIC (1307)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_TANGENT (1308)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY (1309)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_ROUGHNESS (1310)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_IOR (1311)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_THICKNESS (1312)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_EXTINCTION_COEFFICIENT (1313)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_ROUGHNESS (1310)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR (1311)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS (1312)
#define DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT (1313)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StackLit+BSDFData: static fields

case DEBUGVIEW_STACKLIT_SURFACEDATA_ANISOTROPY:
result = surfacedata.anisotropy.xxx;
break;
case DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_ROUGHNESS:
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_ROUGHNESS:
case DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_IOR:
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_IOR:
case DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_THICKNESS:
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_THICKNESS:
case DEBUGVIEW_STACKLIT_SURFACEDATA_CLEAR_COAT_EXTINCTION_COEFFICIENT:
case DEBUGVIEW_STACKLIT_SURFACEDATA_COAT_EXTINCTION_COEFFICIENT:
result = surfacedata.coatExtinction;
break;
}

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


#define DEFAULT_SPECULAR_VALUE 0.04
//
// Vertically Layered BSDF : "VLayering"
// Vertically Layered BSDF : "vlayering"
//
//#define VLAYERED_RECOMPUTE_PERLIGHT // TODOTODO, and to test, make it a shader_features

// Mostly for struct array declarations, not really loops:
#ifdef _MATERIAL_FEATURE_CLEAR_COAT
# define VLAYERED_ENABLED
#ifdef _MATERIAL_FEATURE_COAT
# define COAT_NB_LOBES 1
# define COAT_LOBE_IDX 0
#else

// The only way to get Coat now is with vlayering
bool IsVLayeredEnabled(BSDFData bsdfData)
{
return (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT));
return (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT));
}
float3 ComputeDiffuseColor(float3 baseColor, float metallic)

bsdfData.bitangentWS = bitangentWS;
}
void FillMaterialClearCoatData(float coatPerceptualRoughness, float coatIor, float coatThickness, float3 coatExtinction, inout BSDFData bsdfData)
void FillMaterialCoatData(float coatPerceptualRoughness, float coatIor, float coatThickness, float3 coatExtinction, inout BSDFData bsdfData)
{
bsdfData.coatPerceptualRoughness = coatPerceptualRoughness;
bsdfData.coatIor = coatIor;

float GetClearCoatEta(in BSDFData bsdfData)
float GetCoatEta(in BSDFData bsdfData)
{
float eta = bsdfData.coatIor / 1.0;
//ieta = 1.0 / eta;

// Kind of obsolete without gbuffer, ie could use _MATERIAL_FEATURE* shader_features directly, but
// if anything, makes the code more readable.
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
if (HasFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_COAT))
FillMaterialClearCoatData(PerceptualSmoothnessToPerceptualRoughness(surfaceData.coatPerceptualSmoothness),
surfaceData.coatIor, surfaceData.coatThickness, surfaceData.coatExtinction, bsdfData);
FillMaterialCoatData(PerceptualSmoothnessToPerceptualRoughness(surfaceData.coatPerceptualSmoothness),
surfaceData.coatIor, surfaceData.coatThickness, surfaceData.coatExtinction, bsdfData);
// vlayering:
// We can't calculate final roughnesses including anisotropy right away in this case: we will either do it

/* Update energy */
float R0, n12;
n12 = GetClearCoatEta(bsdfData); //n2/n1;
n12 = GetCoatEta(bsdfData); //n2/n1;
R0 = FresnelUnpolarized(cti, n12, 1.0); // TODO
R12 = R0; // sltodo: FGD

ComputeStatistics(cti, i, bsdfData, ctt, R12, T12, R21, T21, s_r12, s_t12, j12, s_r21, s_t21, j21);
/* Multiple scattering forms */
float3 denom = (float3(1.0, 1.0, 1.0) - Ri0*R12); //slok - i = new layer, 0 = cumulative top (lab3.1 to 3.4)
float3 m_R0i = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (T0i*R12*Ti0) / denom; //slok (lab3.1)
float3 m_Ri0 = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (T21*Ri0*T12) / denom; //slok (lab3.2)
float3 denom = (float3(1.0, 1.0, 1.0) - Ri0*R12); //i = new layer, 0 = cumulative top (llab3.1 to 3.4)
float3 m_R0i = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (T0i*R12*Ti0) / denom; //(llab3.1)
float3 m_Ri0 = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (T21*Ri0*T12) / denom; //(llab3.2)
float3 m_Rr = (mean(denom) <= 0.0f)? float3(0.0, 0.0, 0.0) : (Ri0*R12) / denom;
float m_r0i = mean(m_R0i);
float m_ri0 = mean(m_Ri0);

float3 e_R0i = R0i + m_R0i; //slok (lab3.1)
float3 e_T0i = (T0i*T12) / denom; //slok (lab3.3)
float3 e_Ri0 = R21 + (T21*Ri0*T12) / denom; // slok (lab3.2) slnote: 2nd term = m_Ri0, why not use that
float3 e_Ti0 = (T21*Ti0) / denom; //slok (lab3.4)
float3 e_R0i = R0i + m_R0i; //(llab3.1)
float3 e_T0i = (T0i*T12) / denom; //(llab3.3)
float3 e_Ri0 = R21 + (T21*Ri0*T12) / denom; //(llab3.2)
float3 e_Ti0 = (T21*Ti0) / denom; //(llab3.4)
/* Scalar forms for the energy */
float r21 = mean(R21);

_s_r0m = s_ti0 + j0i*(s_t0i + s_r12 + m_rr*(s_r12+s_ri0));
preLightData.layeredRoughnessT[1] = ClampRoughnessForAnalyticalLights(LinearVarianceToRoughness(_s_r0m));
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
{
// LOBEA roughness for analytical (B part)

if( IsVLayeredEnabled(bsdfData) )
{
//preLightData.fresnel0[COAT_LOBE_IDX] = IorToFresnel0(bsdfData.coatIor);
preLightData.coatIeta = 1.0 / GetClearCoatEta(bsdfData);
preLightData.coatIeta = 1.0 / GetCoatEta(bsdfData);
// First thing we need is compute the energy coefficients and new roughnesses.
// Even if configured to do it also per analytical light, we need it for IBLs too.

// Otherwise, the calculation of these is done for each light
//
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
// Note: there's no anisotropy possible on clearcoat.
// Note: there's no anisotropy possible on coat.
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);

stretch[0] = abs(bsdfData.anisotropy) * saturate(5 * preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX]);
stretch[1] = abs(bsdfData.anisotropy) * saturate(5 * preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX]);
iblN[COAT_LOBE_IDX] = N; // no anisotropy for clearcoat.
iblN[COAT_LOBE_IDX] = N; // no anisotropy for coat.
iblN[BASE_LOBEA_IDX] = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch[0]);
iblN[BASE_LOBEB_IDX] = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch[1]);

preLightData.iblPerceptualRoughness[0] = bsdfData.perceptualRoughnessA;
preLightData.iblPerceptualRoughness[1] = bsdfData.perceptualRoughnessB;
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);

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


// MaterialFeature are used as shader feature to allow compiler to optimize properly
#pragma shader_feature _MATERIAL_FEATURE_ANISOTROPY
#pragma shader_feature _MATERIAL_FEATURE_CLEAR_COAT
#pragma shader_feature _MATERIAL_FEATURE_COAT
#pragma shader_feature _MATERIAL_FEATURE_DUAL_LOBE
//enable GPU instancing support
#pragma multi_compile_instancing

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


// We forbid scale in case of object space as it make no sense
// Decompress normal ourselve
float3 normalOS = SampleTexture2DTriplanarScaleBias(TEXTURE2D_PARAM(textureName, samplerName), textureNameUV, textureNameUVLocal, textureNameST, uvMapping) * 2.0 - 1.0;
float3 normalOS = SampleTexture2DTriplanarScaleBias(TEXTURE2D_PARAM(textureName, samplerName), textureNameUV, textureNameUVLocal, textureNameST, uvMapping).xyz * 2.0 - 1.0;
// no need to renormalize normalOS for SurfaceGradientFromPerturbedNormal
return SurfaceGradientFromPerturbedNormal(uvMapping.vertexNormalWS, TransformObjectToWorldDir(normalOS));
}

surfaceData.perceptualSmoothnessA = lerp(_SmoothnessARange.x, _SmoothnessARange.y, surfaceData.perceptualSmoothnessA);
surfaceData.perceptualSmoothnessA = lerp(_SmoothnessA, surfaceData.perceptualSmoothnessA, _SmoothnessAUseMap);
surfaceData.perceptualSmoothnessB = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_SmoothnessBMap), _SmoothnessBMapChannelMask);
surfaceData.perceptualSmoothnessB = lerp(_SmoothnessBRange.x, _SmoothnessBRange.y, surfaceData.perceptualSmoothnessB);
surfaceData.perceptualSmoothnessB = lerp(_SmoothnessB, surfaceData.perceptualSmoothnessB, _SmoothnessBUseMap);
surfaceData.lobeMix = _LobeMix;
// TODO: Ambient occlusion, detail mask.
surfaceData.metallic = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_MetallicMap), _MetallicMapChannelMask);
surfaceData.metallic = lerp(_MetallicRange.x, _MetallicRange.y, surfaceData.metallic);

// These static material feature allow compile time optimization
// TODO: As we add features, or-set the flags eg MATERIALFEATUREFLAGS_LIT_* with #ifdef
// TODO: As we add features, or-set the flags eg MATERIALFEATUREFLAGS_STACK_LIT_* with #ifdef
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_STACK_LIT_STANDARD;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY;
#ifdef _MATERIAL_FEATURE_CLEAR_COAT
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
#ifdef _MATERIAL_FEATURE_COAT
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_STACK_LIT_COAT;
// Not used for now aside from here in GetSurfaceAndBuiltinData
//#ifdef _MATERIAL_FEATURE_DUAL_LOBE
//#endif
// -------------------------------------------------------------
// Feature dependent data

surfaceData.tangentWS = normalize(input.worldToTangent[0].xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
#ifdef _MATERIAL_FEATURE_DUAL_LOBE
surfaceData.lobeMix = _LobeMix;
surfaceData.perceptualSmoothnessB = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_SmoothnessBMap), _SmoothnessBMapChannelMask);
surfaceData.perceptualSmoothnessB = lerp(_SmoothnessBRange.x, _SmoothnessBRange.y, surfaceData.perceptualSmoothnessB);
surfaceData.perceptualSmoothnessB = lerp(_SmoothnessB, surfaceData.perceptualSmoothnessB, _SmoothnessBUseMap);
#else
surfaceData.lobeMix = 0.0;
surfaceData.perceptualSmoothnessB = 1.0;
#endif
// TODO: #ifdef _ANISOTROPYMAP
surfaceData.anisotropy = 1.0;
#ifdef _MATERIAL_FEATURE_ANISOTROPY

#ifdef _MATERIAL_FEATURE_CLEAR_COAT
#ifdef _MATERIAL_FEATURE_COAT
surfaceData.coatPerceptualSmoothness = _CoatSmoothness;
surfaceData.coatIor = _CoatIor;
surfaceData.coatThickness = _CoatThickness;

正在加载...
取消
保存