浏览代码

Refactor hwo specular material is considered: not anymore a materialId

/RenderPassXR_Sandbox
sebastienlagarde 7 年前
当前提交
70fcec1d
共有 5 个文件被更改,包括 66 次插入51 次删除
  1. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  2. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  3. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  4. 94
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  5. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


Vector4 screenParams = Shader.GetGlobalVector("_ScreenParams");
Vector4 zbufferParams = Shader.GetGlobalVector("_ZBufferParams");
Vector4 unity_OrthoParams = Shader.GetGlobalVector("unity_OrthoParams");
int envLightSkyEnabled = Shader.GetGlobalInt("_EnvLightSkyEnabled");
int envLightSkyEnabled = Shader.GetGlobalInt("_EnvLightSkyEnabled");
float[] thicknessRemaps = Shader.GetGlobalFloatArray("_ThicknessRemaps");
Vector4[] shapeParams = Shader.GetGlobalVectorArray("_ShapeParams");
float[] thicknessRemaps = Shader.GetGlobalFloatArray("_ThicknessRemaps");
Vector4[] shapeParams = Shader.GetGlobalVectorArray("_ShapeParams");
Vector4[] transmissionTints = Shader.GetGlobalVectorArray("_TransmissionTints");
for (int variant = 0; variant < numVariants; variant++)

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


LitStandard = 1,
LitUnused0 = 2,
LitUnused1 = 3,
LitAniso = 4, // Should be the last as it is not setup by the users but generated based on anisotropy property
LitSpecular = 5, // Should be the last as it is not setup by the users but generated based on anisotropy property and specular
// We don't store any materialId for aniso but instead deduce it from LitStandard + value of specular + anisotropy parameters
// Consequence is that when querying materialId alone, it will read 2 RT and not only one. This may be a performance hit when only materialId is desired (like in material classification pass)
// Alternative is to use a materialId slot, if any are available.
LitAniso = 4,
// LitSpecular (DiffuseColor/SpecularColor) is an alternate parametrization for LitStandard (BaseColor/Metal/Specular), but it is the same shading model
// We don't want any specific materialId for it, instead we use LitStandard as materialId. However for UI purpose we still define this value here.
LitSpecular = 5,
};
// If change, be sure it match what is done in Lit.hlsl: MaterialFeatureFlagsFromGBuffer

LitUnused0 = 1 << MaterialId.LitUnused0,
LitUnused1 = 1 << MaterialId.LitUnused1,
LitAniso = 1 << MaterialId.LitAniso,
LitSpecular = 1 << MaterialId.LitSpecular,
};
[GenerateHLSL]

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl


#define MATERIALFEATUREFLAGS_LIT_UNUSED0 (4)
#define MATERIALFEATUREFLAGS_LIT_UNUSED1 (8)
#define MATERIALFEATUREFLAGS_LIT_ANISO (16)
#define MATERIALFEATUREFLAGS_LIT_SPECULAR (32)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+SpecularValue: static fields

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


// Configure what kind of combination is supported
//-----------------------------------------------------------------------------
// Only include material classification code if it it requested. Just check LIGHT_FEATURE_MASK_FLAGS define for this
#ifdef NUM_FEATURE_VARIANTS
// Lighting architecture and material are suppose to be decoupled files.
// However as we use material classification it is hard to be fully separated
// the dependecy is define in this include where there is shared define for material and lighting in case of deferred material.
// If a user do a lighting architecture without material classification, this can be remove
#include "../../Lighting/TilePass/TilePass.cs.hlsl"
/* 0 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_SPECULAR,
/* 1 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_SPECULAR,
/* 2 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_SPECULAR,
/* 3 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_SPECULAR,
/* 0 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 1 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 2 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 3 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_STANDARD,
// SSS
/* 4 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS,

/* 8 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 9 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 10 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 11 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_ANISO | MATERIALFEATUREFLAGS_LIT_SPECULAR,
/* 11 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_ANISO,
// Future usage
/* 12 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_UNUSED0,

{
return kFeatureVariantFlags[variant];
}
#endif // LIGHT_FEATURE_MASK_FLAGS
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material

bsdfData.roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);
bsdfData.materialId = surfaceData.materialId;
// IMPORTANT: In case of foward or gbuffer pass we know what we are, we don't need to check specular or aniso to know the materialId, this is because we have static compile shader feature for it
// IMPORTANT: In case of foward or gbuffer pass we must know what we are statically, so compiler can do compile time optimization
FillMaterialIdStandardData(surfaceData.baseColor, surfaceData.specular, surfaceData.metallic, bsdfData);
}
else if (bsdfData.materialId == MATERIALID_LIT_SPECULAR)
{
bsdfData.diffuseColor = surfaceData.baseColor;
bsdfData.fresnel0 = surfaceData.specularColor;
if (surfaceData.specular == SPECULARVALUE_SPECULAR_COLOR)
{
bsdfData.diffuseColor = surfaceData.baseColor;
bsdfData.fresnel0 = surfaceData.specularColor;
}
else
{
FillMaterialIdStandardData(surfaceData.baseColor, surfaceData.specular, surfaceData.metallic, bsdfData);
}
}
else if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{

if (surfaceData.materialId == MATERIALID_LIT_STANDARD)
{
// Encode specular on two bit for the enum
outGBuffer2 = float4(0.0, 0.0, 0.0, PackFloatInt8bit(surfaceData.metallic, surfaceData.specular, 4.0));
}
else if (surfaceData.materialId == MATERIALID_LIT_SPECULAR)
{
outGBuffer1.a = PackMaterialId(MATERIALID_LIT_STANDARD); // We save 1bit in gbuffer1 to store it in gbuffer2 instead
// Encode specular on two bit for the enum, must match encoding of MATERIALID_LIT_STANDARD
// TODO: encoding here could be optimize as we know what is the value of surfaceData.specular => (0.75294)
outGBuffer2 = float4(surfaceData.specularColor, PackFloatInt8bit(0.0, surfaceData.specular, 4.0));
// Note: we encode two parametrization at the same time, specularColor and metal/specular
outGBuffer2 = float4(surfaceData.specularColor, PackFloatInt8bit(surfaceData.metallic, surfaceData.specular, 4.0));
}
else if (surfaceData.materialId == MATERIALID_LIT_ANISO)
{

bsdfData.roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);
// The material features system for material classification must allow compile time optimization (i.e everything should be static)
// The code below define materialId based on material features so compiler know what to do.
// However as we store materialId for Aniso and Specular based on content of RT2, not just materialId, then we need to add severals condition.
// Goal of all this additional condition is to allow the compiler to optimize path that are not use.
// Note that the code is also call from MaterialFeatureFlagsFromGBuffer, so must work fully dynamic if featureFlags is 0xFFFF
// Aniso and Specular are encoded like standard + RT2 values
int supportsStandard = (featureFlags & (MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_ANISO | MATERIALFEATUREFLAGS_LIT_SPECULAR)) != 0;
// Note that as we store materialId for Aniso based on content of RT2 we need to add few extra condition.
// The code is also call from MaterialFeatureFlagsFromGBuffer, so must work fully dynamic if featureFlags is 0xFFFFFFFF
int supportsStandard = (featureFlags & (MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_ANISO)) != 0;
int supportsSSS = (featureFlags & (MATERIALFEATUREFLAGS_LIT_SSS)) != 0;
if (supportsStandard + supportsSSS > 1)

UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, specular);
float anisotropy = inGBuffer2.b;
if (((featureFlags & MATERIALFEATUREFLAGS_LIT_SPECULAR) && (featureFlags & MATERIALFEATUREFLAGS_LIT_STANDARD) == 0)
|| specular == SPECULARVALUE_SPECULAR_COLOR)
if (featureFlags & (MATERIAL_FEATURE_MASK_FLAGS) == MATERIALFEATUREFLAGS_LIT_STANDARD)
bsdfData.materialId = MATERIALID_LIT_SPECULAR;
bsdfData.diffuseColor = baseColor;
bsdfData.fresnel0 = inGBuffer2.rgb;
if (specular == SPECULARVALUE_SPECULAR_COLOR)
{
bsdfData.diffuseColor = baseColor;
bsdfData.fresnel0 = inGBuffer2.rgb;
}
else
{
FillMaterialIdStandardData(baseColor, specular, metallic, bsdfData);
}
else if ( ((featureFlags & MATERIALFEATUREFLAGS_LIT_ANISO) && (featureFlags & MATERIALFEATUREFLAGS_LIT_STANDARD) == 0)
|| anisotropy > 0)
else if (featureFlags & (MATERIAL_FEATURE_MASK_FLAGS) == MATERIALFEATUREFLAGS_LIT_ANISO)
{
bsdfData.materialId = MATERIALID_LIT_ANISO;
FillMaterialIdStandardData(baseColor, specular, metallic, bsdfData);

else
else // either MATERIAL_FEATURE_MASK_FLAGS or MATERIALFEATUREFLAGS_LIT_STANDARD | MATERIALFEATUREFLAGS_LIT_ANISO
FillMaterialIdStandardData(baseColor, specular, metallic, bsdfData);
if (specular == SPECULARVALUE_SPECULAR_COLOR)
{
bsdfData.diffuseColor = baseColor;
bsdfData.fresnel0 = inGBuffer2.rgb;
}
else if (anisotropy > 0)
{
bsdfData.materialId = MATERIALID_LIT_ANISO;
FillMaterialIdStandardData(baseColor, specular, metallic, bsdfData);
float3 tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0));
FillMaterialIdAnisoData(bsdfData.roughness, bsdfData.normalWS, tangentWS, anisotropy, bsdfData);
}
else
{
FillMaterialIdStandardData(baseColor, specular, metallic, bsdfData);
}
}
else // bsdfData.materialId == MATERIALID_LIT_SSS
{

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


#elif defined(_MATID_ANISO)
surfaceData.materialId = MATERIALID_LIT_ANISO;
#elif defined(_MATID_SPECULAR)
surfaceData.materialId = MATERIALID_LIT_SPECULAR;
surfaceData.materialId = MATERIALID_LIT_STANDARD; // Specular is not a different BRDF, it is just different parametrization, do'nt do a separate matId for it
#else // Default
surfaceData.materialId = MATERIALID_LIT_STANDARD;
#endif

#endif
surfaceData.anisotropy *= ADD_IDX(_Anisotropy);
// This surfaceData.specular must be static to allow the compiler to optimize the code when converting / encoding the values
// To save 1bit space in GBuffer we don't store specular as materialID but in the enum of the specular value
surfaceData.specular = SPECULARVALUE_SPECULAR_COLOR;
#else
surfaceData.specular = SPECULARVALUE_REGULAR;

正在加载...
取消
保存