浏览代码

Merge remote-tracking branch 'refs/remotes/origin/refactor-gbuffer-bitfield' into Refactor-GBuffer-with-material-feature

/iridesence
sebastienlagarde 7 年前
当前提交
221cd4e1
共有 7 个文件被更改,包括 139 次插入227 次删除
  1. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  2. 33
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  3. 155
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl
  4. 135
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitData.hlsl
  6. 26
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataIndividualLayer.hlsl
  7. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitReference.hlsl

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl


surfaceData.diffusionProfile = SURFACEDATA_BLEND_SSS_PROFILE(surfaceData, diffusionProfile, weights);
// Layered shader support SSS and Transmission features
surfaceData.enableSubsurfaceScattering = false;
surfaceData.enableTransmission = false;
surfaceData.enableAnisotropy = false;
surfaceData.enableClearCoat = false;
surfaceData.enableIridescence = false;
surfaceData.enableSpecularColor = false;
surfaceData.materialFeatures = 0;
surfaceData.enableSubsurfaceScattering = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
surfaceData.enableTransmission = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
#endif
// Init other parameters

33
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs


public enum MaterialFeatureFlags
{
LitStandard = 1 << 0, // For material classification we need to identify that we are indeed use as standard material, else we are consider as sky/background element
LitSubsurfaceScattering = 1 << 1,
LitTransmission = 1 << 2,
LitAnisotropy = 1 << 3,
LitIridescence = 1 << 4,
LitClearCoat = 1 << 5
// Note: // There is no material feature for LitSpecularColor as it is always dynamically tested
LitSpecularColor = 1 << 1, // LitSpecularColor is not use statically but only dynamically
LitSubsurfaceScattering = 1 << 2,
LitTransmission = 1 << 3,
LitAnisotropy = 1 << 4,
LitIridescence = 1 << 5,
LitClearCoat = 1 << 6
};
[GenerateHLSL(PackingRules.Exact)]

[GenerateHLSL(PackingRules.Exact, false, true, 1000)]
public struct SurfaceData
{
[SurfaceDataAttributes("Enable Specular Color")]
public bool enableSpecularColor;
[SurfaceDataAttributes("Enable SubsurfaceScattering")]
public bool enableSubsurfaceScattering;
[SurfaceDataAttributes("Enable Transmission")]
public bool enableTransmission;
[SurfaceDataAttributes("Enable Anisotropy")]
public bool enableAnisotropy;
[SurfaceDataAttributes("Enable Iridescence")]
public bool enableIridescence;
[SurfaceDataAttributes("Enable Clear Coat")]
public bool enableClearCoat;
[SurfaceDataAttributes("MaterialFeatures")]
public uint materialFeatures;
// Standard
[SurfaceDataAttributes("Base Color", false, true)]

[GenerateHLSL(PackingRules.Exact, false, true, 1030)]
public struct BSDFData
{
public bool enableSpecularColor;
public bool enableSubsurfaceScattering;
public bool enableTransmission;
public bool enableAnisotropy;
public bool enableIridescence;
public bool enableClearCoat;
public uint materialFeatures;
[SurfaceDataAttributes("", false, true)]
public Vector3 diffuseColor;

155
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl


// UnityEngine.Experimental.Rendering.HDPipeline.Lit+MaterialFeatureFlags: static fields
//
#define MATERIALFEATUREFLAGS_LIT_STANDARD (1)
#define MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING (2)
#define MATERIALFEATUREFLAGS_LIT_TRANSMISSION (4)
#define MATERIALFEATUREFLAGS_LIT_ANISOTROPY (8)
#define MATERIALFEATUREFLAGS_LIT_IRIDESCENCE (16)
#define MATERIALFEATUREFLAGS_LIT_CLEAR_COAT (32)
#define MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR (2)
#define MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING (4)
#define MATERIALFEATUREFLAGS_LIT_TRANSMISSION (8)
#define MATERIALFEATUREFLAGS_LIT_ANISOTROPY (16)
#define MATERIALFEATUREFLAGS_LIT_IRIDESCENCE (32)
#define MATERIALFEATUREFLAGS_LIT_CLEAR_COAT (64)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+RefractionMode: static fields

//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+SurfaceData: static fields
//
#define DEBUGVIEW_LIT_SURFACEDATA_ENABLE_SPECULAR_COLOR (1000)
#define DEBUGVIEW_LIT_SURFACEDATA_ENABLE_SUBSURFACE_SCATTERING (1001)
#define DEBUGVIEW_LIT_SURFACEDATA_ENABLE_TRANSMISSION (1002)
#define DEBUGVIEW_LIT_SURFACEDATA_ENABLE_ANISOTROPY (1003)
#define DEBUGVIEW_LIT_SURFACEDATA_ENABLE_IRIDESCENCE (1004)
#define DEBUGVIEW_LIT_SURFACEDATA_ENABLE_CLEAR_COAT (1005)
#define DEBUGVIEW_LIT_SURFACEDATA_BASE_COLOR (1006)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_OCCLUSION (1007)
#define DEBUGVIEW_LIT_SURFACEDATA_NORMAL_WS (1008)
#define DEBUGVIEW_LIT_SURFACEDATA_PERCEPTUAL_SMOOTHNESS (1009)
#define DEBUGVIEW_LIT_SURFACEDATA_AMBIENT_OCCLUSION (1010)
#define DEBUGVIEW_LIT_SURFACEDATA_METALLIC (1011)
#define DEBUGVIEW_LIT_SURFACEDATA_COAT_MASK (1012)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_COLOR (1013)
#define DEBUGVIEW_LIT_SURFACEDATA_DIFFUSION_PROFILE (1014)
#define DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_MASK (1015)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS (1016)
#define DEBUGVIEW_LIT_SURFACEDATA_TANGENT_WS (1017)
#define DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY (1018)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS_IRID (1019)
#define DEBUGVIEW_LIT_SURFACEDATA_IOR (1020)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_COLOR (1021)
#define DEBUGVIEW_LIT_SURFACEDATA_AT_DISTANCE (1022)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_MASK (1023)
#define DEBUGVIEW_LIT_SURFACEDATA_MATERIAL_FEATURES (1000)
#define DEBUGVIEW_LIT_SURFACEDATA_BASE_COLOR (1001)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_OCCLUSION (1002)
#define DEBUGVIEW_LIT_SURFACEDATA_NORMAL_WS (1003)
#define DEBUGVIEW_LIT_SURFACEDATA_PERCEPTUAL_SMOOTHNESS (1004)
#define DEBUGVIEW_LIT_SURFACEDATA_AMBIENT_OCCLUSION (1005)
#define DEBUGVIEW_LIT_SURFACEDATA_METALLIC (1006)
#define DEBUGVIEW_LIT_SURFACEDATA_COAT_MASK (1007)
#define DEBUGVIEW_LIT_SURFACEDATA_SPECULAR_COLOR (1008)
#define DEBUGVIEW_LIT_SURFACEDATA_DIFFUSION_PROFILE (1009)
#define DEBUGVIEW_LIT_SURFACEDATA_SUBSURFACE_MASK (1010)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS (1011)
#define DEBUGVIEW_LIT_SURFACEDATA_TANGENT_WS (1012)
#define DEBUGVIEW_LIT_SURFACEDATA_ANISOTROPY (1013)
#define DEBUGVIEW_LIT_SURFACEDATA_THICKNESS_IRID (1014)
#define DEBUGVIEW_LIT_SURFACEDATA_IOR (1015)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_COLOR (1016)
#define DEBUGVIEW_LIT_SURFACEDATA_AT_DISTANCE (1017)
#define DEBUGVIEW_LIT_SURFACEDATA_TRANSMITTANCE_MASK (1018)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_SPECULAR_COLOR (1030)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_SUBSURFACE_SCATTERING (1031)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION (1032)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_ANISOTROPY (1033)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_IRIDESCENCE (1034)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_CLEAR_COAT (1035)
#define DEBUGVIEW_LIT_BSDFDATA_DIFFUSE_COLOR (1036)
#define DEBUGVIEW_LIT_BSDFDATA_FRESNEL0 (1037)
#define DEBUGVIEW_LIT_BSDFDATA_SPECULAR_OCCLUSION (1038)
#define DEBUGVIEW_LIT_BSDFDATA_NORMAL_WS (1039)
#define DEBUGVIEW_LIT_BSDFDATA_PERCEPTUAL_ROUGHNESS (1040)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_MASK (1041)
#define DEBUGVIEW_LIT_BSDFDATA_DIFFUSION_PROFILE (1042)
#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_MASK (1043)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1044)
#define DEBUGVIEW_LIT_BSDFDATA_USE_THICK_OBJECT_MODE (1045)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_TANGENT_WS (1047)
#define DEBUGVIEW_LIT_BSDFDATA_BITANGENT_WS (1048)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_T (1049)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_B (1050)
#define DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY (1051)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS_IRID (1052)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1053)
#define DEBUGVIEW_LIT_BSDFDATA_IOR (1054)
#define DEBUGVIEW_LIT_BSDFDATA_ABSORPTION_COEFFICIENT (1055)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE_MASK (1056)
#define DEBUGVIEW_LIT_BSDFDATA_MATERIAL_FEATURES (1030)
#define DEBUGVIEW_LIT_BSDFDATA_DIFFUSE_COLOR (1031)
#define DEBUGVIEW_LIT_BSDFDATA_FRESNEL0 (1032)
#define DEBUGVIEW_LIT_BSDFDATA_SPECULAR_OCCLUSION (1033)
#define DEBUGVIEW_LIT_BSDFDATA_NORMAL_WS (1034)
#define DEBUGVIEW_LIT_BSDFDATA_PERCEPTUAL_ROUGHNESS (1035)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_MASK (1036)
#define DEBUGVIEW_LIT_BSDFDATA_DIFFUSION_PROFILE (1037)
#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_MASK (1038)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1039)
#define DEBUGVIEW_LIT_BSDFDATA_USE_THICK_OBJECT_MODE (1040)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1041)
#define DEBUGVIEW_LIT_BSDFDATA_TANGENT_WS (1042)
#define DEBUGVIEW_LIT_BSDFDATA_BITANGENT_WS (1043)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_T (1044)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_B (1045)
#define DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY (1046)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS_IRID (1047)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1048)
#define DEBUGVIEW_LIT_BSDFDATA_IOR (1049)
#define DEBUGVIEW_LIT_BSDFDATA_ABSORPTION_COEFFICIENT (1050)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE_MASK (1051)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+GBufferMaterial: static fields

// PackingRules = Exact
struct SurfaceData
{
bool enableSpecularColor;
bool enableSubsurfaceScattering;
bool enableTransmission;
bool enableAnisotropy;
bool enableIridescence;
bool enableClearCoat;
uint materialFeatures;
float3 baseColor;
float specularOcclusion;
float3 normalWS;

// PackingRules = Exact
struct BSDFData
{
bool enableSpecularColor;
bool enableSubsurfaceScattering;
bool enableTransmission;
bool enableAnisotropy;
bool enableIridescence;
bool enableClearCoat;
uint materialFeatures;
float3 diffuseColor;
float3 fresnel0;
float specularOcclusion;

{
switch (paramId)
{
case DEBUGVIEW_LIT_SURFACEDATA_ENABLE_SPECULAR_COLOR:
result = (surfacedata.enableSpecularColor) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_SURFACEDATA_ENABLE_SUBSURFACE_SCATTERING:
result = (surfacedata.enableSubsurfaceScattering) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_SURFACEDATA_ENABLE_TRANSMISSION:
result = (surfacedata.enableTransmission) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_SURFACEDATA_ENABLE_ANISOTROPY:
result = (surfacedata.enableAnisotropy) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_SURFACEDATA_ENABLE_IRIDESCENCE:
result = (surfacedata.enableIridescence) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_SURFACEDATA_ENABLE_CLEAR_COAT:
result = (surfacedata.enableClearCoat) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
case DEBUGVIEW_LIT_SURFACEDATA_MATERIAL_FEATURES:
result = GetIndexColor(surfacedata.materialFeatures);
break;
case DEBUGVIEW_LIT_SURFACEDATA_BASE_COLOR:
result = surfacedata.baseColor;

{
switch (paramId)
{
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_SPECULAR_COLOR:
result = (bsdfdata.enableSpecularColor) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_SUBSURFACE_SCATTERING:
result = (bsdfdata.enableSubsurfaceScattering) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION:
result = (bsdfdata.enableTransmission) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_ANISOTROPY:
result = (bsdfdata.enableAnisotropy) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_IRIDESCENCE:
result = (bsdfdata.enableIridescence) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_CLEAR_COAT:
result = (bsdfdata.enableClearCoat) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
case DEBUGVIEW_LIT_BSDFDATA_MATERIAL_FEATURES:
result = GetIndexColor(bsdfdata.materialFeatures);
break;
case DEBUGVIEW_LIT_BSDFDATA_DIFFUSE_COLOR:
result = bsdfdata.diffuseColor;

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


return positionWS + rayWS * hitDistanceFromPosition;
}
// 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 HasMaterialFeatureFlag(uint featureFlags, uint flag)
{
return ((featureFlags & flag) != 0);
}
float3 ComputeDiffuseColor(float3 baseColor, float metallic)
{
return baseColor * (1.0 - metallic);

ZERO_INITIALIZE(BSDFData, bsdfData);
// IMPORTANT: In case of foward or gbuffer pass all enable flags are statically know at compile time, so the compiler can do compile time optimization
bsdfData.enableSpecularColor = surfaceData.enableSpecularColor;
bsdfData.enableSubsurfaceScattering = surfaceData.enableSubsurfaceScattering;
bsdfData.enableTransmission = surfaceData.enableTransmission;
bsdfData.enableAnisotropy = surfaceData.enableAnisotropy;
bsdfData.enableIridescence = surfaceData.enableIridescence;
bsdfData.enableClearCoat = surfaceData.enableClearCoat;
surfaceData.materialFeatures = surfaceData.materialFeatures | MATERIALFEATUREFLAGS_LIT_STANDARD; // Not really needed but for consistency with deferred path
// Standard material
bsdfData.specularOcclusion = surfaceData.specularOcclusion;

// There is no mettalic with SSS and specular color mode
float metallic = (bsdfData.enableSpecularColor || bsdfData.enableSubsurfaceScattering || bsdfData.enableTransmission || bsdfData.enableIridescence) ? 0.0 : surfaceData.metallic;
float metallic = HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE) ?
0.0 : surfaceData.metallic;
bsdfData.fresnel0 = bsdfData.enableSpecularColor ? surfaceData.specularColor : ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
bsdfData.fresnel0 = HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR) ? surfaceData.specularColor : ComputeFresnel0(surfaceData.baseColor, surfaceData.metallic, DEFAULT_SPECULAR_VALUE);
// Always assign even if not used, DIFFUSION_PROFILE_NEUTRAL_ID is 0
bsdfData.diffusionProfile = surfaceData.diffusionProfile;

// However in practice we keep parity between deferred and forward, so we should contrain the various features.
// The UI is in charge of setuping the constrain not the code, so if users is forward only and want full power, it is easy to unleash by some UI change
if (bsdfData.enableSubsurfaceScattering)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (bsdfData.enableTransmission)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
if (bsdfData.enableAnisotropy)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
if (bsdfData.enableIridescence)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Modify fresnel0 and perceptualRoughness
FillMaterialClearCoatData(surfaceData.coatMask, bsdfData);

// The priority of feature is handled in the code here and reflect in the UI (see LitUI.cs)
// Process SSS and Transmission together as they encode almost the same data, negligible cost
if (surfaceData.enableSubsurfaceScattering || surfaceData.enableTransmission)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
metallic15 = GBUFFER_LIT_SSS_OR_TRANSMISSION;
// Special case: For SSS we will store the profile id and the subsurface radius at the location of the specular occlusion (in alpha channel of GBuffer0)

outGBuffer2.rgb = float3(surfaceData.specularOcclusion, surfaceData.thickness, surfaceData.enableSubsurfaceScattering ? 1.0 : 0.0); // thickness for Transmission
outGBuffer2.rgb = float3(surfaceData.specularOcclusion, surfaceData.thickness, HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING) ? 1.0 : 0.0); // thickness for Transmission
if (surfaceData.enableSpecularColor)
if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR))
else if (surfaceData.enableAnisotropy)
else if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
else if (surfaceData.enableIridescence)
else if (HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
{
metallic15 = GBUFFER_LIT_IRIDESCENCE;
outGBuffer2.rgb = float3(0.0, surfaceData.thicknessIrid, 0.0);

}
// Encode coatMask (4bit) / mettalic (4bit)
outGBuffer2.a = PackFloatInt8bit(surfaceData.enableClearCoat ? surfaceData.coatMask : 0.0, metallic15, 16.0);
outGBuffer2.a = PackFloatInt8bit(HasMaterialFeatureFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? surfaceData.coatMask : 0.0, metallic15, 16.0);
// 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 HasMaterialFeatureFlag(uint featureFlags, uint flag)
{
return ((featureFlags & flag) != 0);
}
void DecodeFromGBuffer(uint2 positionSS, uint featureFlags, out BSDFData bsdfData, out float3 bakeDiffuseLighting, out uint materialFeatures)
void DecodeFromGBuffer(uint2 positionSS, uint featureFlags, out BSDFData bsdfData, out float3 bakeDiffuseLighting, out uint outMaterialFeatures)
{
GBufferType0 inGBuffer0 = LOAD_TEXTURE2D(_GBufferTexture0, positionSS);
GBufferType1 inGBuffer1 = LOAD_TEXTURE2D(_GBufferTexture1, positionSS);

int metallic15;
UnpackFloatInt8bit(inGBuffer2.a, 16.0, coatMask, metallic15);
// If any of the flags of g_MaterialFeatureFlags (tested with HasMaterialFeatureFlag) is not set, it mean we know statically that
// the material feature is not used, so the compiler can optimize related code. Else we don't know if the material feature will be use, it is a dynamic condition.
bsdfData.enableSpecularColor = (metallic15 == GBUFFER_LIT_SPECULAR_COLOR); // This is always a dynamic test as it is very cheap
bsdfData.enableTransmission = (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.g > 0.0) && // Thickness > 0
HasMaterialFeatureFlag(featureFlags, MATERIALFEATUREFLAGS_LIT_TRANSMISSION);
bsdfData.enableSubsurfaceScattering = (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.b > 0.0) && // SSS Flags > 0
HasMaterialFeatureFlag(featureFlags, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING);
bsdfData.enableAnisotropy = (metallic15 <= GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND && abs(inGBuffer2.g * 2.0 - 1.0) > 0.004) && // Anisotropy > 0
HasMaterialFeatureFlag(featureFlags, MATERIALFEATUREFLAGS_LIT_ANISOTROPY);
bsdfData.enableIridescence = (metallic15 == GBUFFER_LIT_IRIDESCENCE) &&
HasMaterialFeatureFlag(featureFlags, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE);
bsdfData.enableClearCoat = coatMask > 0.0 &&
HasMaterialFeatureFlag(featureFlags, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT);
// If any of the flags of featureFlags is not set, it mean we know statically that
// the material feature is not used, so the compiler can optimize related code.
// Else we don't know if the material feature will be use, it is a dynamic condition.
bool enableSpecularColor = (metallic15 == GBUFFER_LIT_SPECULAR_COLOR); // This is always a dynamic test as it is very cheap
bsdfData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; // It is mandatory to identity ourselve as standard shader, else we are consider as sky/background element
bsdfData.materialFeatures |= (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.g > 0.0) ? featureFlags & MATERIALFEATUREFLAGS_LIT_TRANSMISSION : 0; // Thickness > 0
bsdfData.materialFeatures |= (metallic15 == GBUFFER_LIT_SSS_OR_TRANSMISSION && inGBuffer2.b > 0.0) ? featureFlags & MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING : 0; // TagSSS > 0
bsdfData.materialFeatures |= (metallic15 <= GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND && abs(inGBuffer2.g - 0.5) > 0.004) ? featureFlags & MATERIALFEATUREFLAGS_LIT_ANISOTROPY : 0; // Anisotropy != 0
bsdfData.materialFeatures |= (metallic15 == GBUFFER_LIT_IRIDESCENCE) ? featureFlags & MATERIALFEATUREFLAGS_LIT_IRIDESCENCE : 0;
bsdfData.materialFeatures |= coatMask > 0.0 ? featureFlags & MATERIALFEATUREFLAGS_LIT_CLEAR_COAT : 0;
// Init material feature (will be optimize out in all pass but classification
materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; // It is mandatory to identity ourselve as standard shader, else we are consider as sky/background element
materialFeatures |= bsdfData.enableTransmission ? MATERIALFEATUREFLAGS_LIT_TRANSMISSION : 0;
materialFeatures |= bsdfData.enableSubsurfaceScattering ? MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING : 0;
materialFeatures |= bsdfData.enableAnisotropy ? MATERIALFEATUREFLAGS_LIT_ANISOTROPY : 0;
materialFeatures |= bsdfData.enableIridescence ? MATERIALFEATUREFLAGS_LIT_IRIDESCENCE : 0;
materialFeatures |= bsdfData.enableClearCoat ? MATERIALFEATUREFLAGS_LIT_CLEAR_COAT : 0;
// Save for material classification
outMaterialFeatures = bsdfData.materialFeatures;
// Start decompressing GBuffer
float3 baseColor = inGBuffer0.rgb;

// metallic15 is range [0..12] if mettallic data is needed
float metallic = (metallic15 <= GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND) ? metallic15 * (1.0 / GBUFFER_LIT_ANISOTROPIC_UPPER_BOUND) : 0.0;
bsdfData.diffuseColor = ComputeDiffuseColor(baseColor, metallic);
bsdfData.fresnel0 = bsdfData.enableSpecularColor ? Gamma20ToLinear(inGBuffer2.rgb) : ComputeFresnel0(baseColor, metallic, DEFAULT_SPECULAR_VALUE);
bsdfData.fresnel0 = enableSpecularColor ? Gamma20ToLinear(inGBuffer2.rgb) : ComputeFresnel0(baseColor, metallic, DEFAULT_SPECULAR_VALUE);
if (bsdfData.enableSubsurfaceScattering || bsdfData.enableTransmission)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// First we must extract the diffusion profile

bsdfData.diffusionProfile = sssData.diffusionProfile;
if (bsdfData.enableSubsurfaceScattering)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
if (bsdfData.enableTransmission)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
FillMaterialTransmission(inGBuffer0.g, bsdfData);
}

float anisotropy;
float3 tangentWS;
if (bsdfData.enableAnisotropy)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
anisotropy = inGBuffer2.b * 2.0 - 1.0;
tangentWS = UnpackNormalOctEncode(inGBuffer2.rg * 2.0 - 1.0);

FillMaterialAnisotropy(anisotropy, tangentWS, bsdfData);
// Force the compiler to use the anisotropy path all the time
bsdfData.enableAnisotropy = true;
bsdfData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
if (bsdfData.enableIridescence)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_IRIDESCENCE))
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Modify fresnel0 and perceptualRoughness
FillMaterialClearCoatData(coatMask, bsdfData);

preLightData.clampNdotV = NdotV; // Caution: The handling of edge cases where N is directed away from the screen is handled during Gbuffer/forward pass, so here do nothing
preLightData.iblPerceptualRoughness = bsdfData.perceptualRoughness;
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
preLightData.coatPartLambdaV = GetSmithJointGGXPartLambdaV(NdotV, CLEAR_COAT_ROUGHNESS);
preLightData.coatIblR = reflect(-V, N);

// We avoid divergent evaluation of the GGX, as that nearly doubles the cost.
// If the tile has anisotropy, all the pixels within the tile are evaluated as anisotropic.
if (bsdfData.enableAnisotropy)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);

// to match the reference for rough metals, but further darkens dielectrics.
preLightData.ltcMagnitudeFresnel = bsdfData.fresnel0 * ltcGGXFresnelMagnitudeDiff + (float3)ltcGGXFresnelMagnitude;
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
float2 uv = LTC_LUT_OFFSET + LTC_LUT_SCALE * float2(CLEAR_COAT_PERCEPTUAL_ROUGHNESS, theta * INV_HALF_PI);

// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLigthing(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
if (bsdfData.enableSubsurfaceScattering)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
{
bsdfData.diffuseColor = ApplySubsurfaceScatteringTexturingMode(bsdfData.diffuseColor, bsdfData.diffusionProfile);
}

bool HaveSubsurfaceScattering(BSDFData bsdfData)
{
return (_EnableSubsurfaceScattering != 0) && bsdfData.enableSubsurfaceScattering;
return (_EnableSubsurfaceScattering != 0) && HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING);
}
//-----------------------------------------------------------------------------

float3 F = F_Schlick(bsdfData.fresnel0, LdotH);
float DV;
if (bsdfData.enableAnisotropy)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float3 H = (L + V) * invLenLV;
// For anisotropy we must not saturate these values

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
diffuseLighting = diffuseTerm;
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// Apply isotropic GGX for clear coat
// Note: coat F is scalar as it is a dieletric

lighting.specular *= intensity * lightData.specularScale;
}
[branch] if (bsdfData.enableTransmission)
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, NdotL, preLightData.clampNdotV, attenuation * lightData.diffuseScale);

lighting.specular *= intensity * lightData.specularScale;
}
[branch] if (bsdfData.enableTransmission)
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, NdotL, preLightData.clampNdotV, attenuation * lightData.diffuseScale);

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
[branch] if (bsdfData.enableTransmission)
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

lighting.specular = preLightData.ltcMagnitudeFresnel * ltcValue;
// Evaluate the coat part
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);

// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
[branch] if (bsdfData.enableTransmission)
[branch] if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// Flip the view vector and the normal. The bitangent stays the same.
float3x3 flipMatrix = float3x3(-1, 0, 0,

lighting.specular += preLightData.ltcMagnitudeFresnel * ltcValue;
// Evaluate the coat part
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel);

R = (positionWS + projectionDistance * R) - lightData.positionWS;
// Test again for clear code
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && bsdfData.enableClearCoat)
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirLS = mul(coatR, worldToLocal);
projectionDistance = SphereRayIntersectSimple(positionLS, dirLS, sphereOuterDistance);

// TODO: add distance based roughness
// Test again for clear code
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && bsdfData.enableClearCoat)
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirLS = mul(coatR, worldToLocal);
projectionDistance = BoxRayIntersectSimple(positionLS, dirLS, -boxOuterDistance, boxOuterDistance);

envLighting = F * preLD.rgb;
// Evaluate the Clear Coat component if needed
if (bsdfData.enableClearCoat)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
// No correction needed for coatR as it is smooth
// Note: coat F is scalar as it is a dieletric

#endif
float3 modifiedDiffuseColor;
if (bsdfData.enableSubsurfaceScattering)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING))
modifiedDiffuseColor = ApplySubsurfaceScatteringTexturingMode(bsdfData.diffuseColor, bsdfData.diffusionProfile);
else
modifiedDiffuseColor = bsdfData.diffuseColor;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitData.hlsl


// It is safe to call this function here as surfaceData have been filled
// We want to know if we must enable transmission on GI for SSS material, if the material have no SSS, this code will be remove by the compiler.
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
if (bsdfData.enableTransmission)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION))
{
// For now simply recall the function with inverted normal, the compiler should be able to optimize the lightmap case to not resample the directional lightmap
// however it will not optimize the lightprobe case due to the proxy volume relying on dynamic if (we rely must get right of this dynamic if), not a problem for SH9, but a problem for proxy volume.

26
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitDataIndividualLayer.hlsl


#if !defined(LAYERED_LIT_SHADER)
// These static material feature allow compile time optimization
surfaceData.enableSubsurfaceScattering = false;
surfaceData.enableTransmission = false;
surfaceData.enableAnisotropy = false;
surfaceData.enableClearCoat = false;
surfaceData.enableIridescence = false;
surfaceData.enableSpecularColor = false;
surfaceData.materialFeatures = 0;
surfaceData.enableSubsurfaceScattering = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
surfaceData.enableTransmission = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
surfaceData.enableAnisotropy = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
surfaceData.enableClearCoat = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
surfaceData.enableIridescence = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
surfaceData.enableSpecularColor = true;
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
#endif
#ifdef _TANGENTMAP

// Mandatory to setup value to keep compiler quiet
// Layered shader material feature are define outside of this call
surfaceData.enableSubsurfaceScattering = false;
surfaceData.enableTransmission = false;
surfaceData.enableAnisotropy = false;
surfaceData.enableClearCoat = false;
surfaceData.enableIridescence = false;
surfaceData.enableSpecularColor = false;
surfaceData.materialFeatures = 0;
// All these parameters are ignore as they are re-setup outside of the layers function
// Note: any parameters set here must also be set in GetSurfaceAndBuiltinData() layer version

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitReference.hlsl


{
float3x3 localToWorld;
if (bsdfData.enableAnisotropy)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
}

float weightOverPdf;
// GGX BRDF
if (bsdfData.enableAnisotropy)
if (HasMaterialFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
ImportanceSampleAnisoGGX(u, V, localToWorld, bsdfData.roughnessT, bsdfData.roughnessB, NdotV, L, VdotH, NdotL, weightOverPdf);
}

正在加载...
取消
保存