Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFAPI.cs
2024-08-26 23:07:20 +03:00

192 lines
9.4 KiB
C#

using UnityEditor.Rendering.HighDefinition;
// Include material common properties names
using static UnityEngine.Rendering.HighDefinition.HDMaterialProperties;
namespace UnityEngine.Rendering.HighDefinition
{
internal enum AxfBrdfType
{
SVBRDF,
CAR_PAINT,
//unsupported for now: BTF,
}
internal enum SvbrdfDiffuseType
{
LAMBERT = 0,
OREN_NAYAR = 1,
}
internal enum SvbrdfSpecularType
{
WARD = 0,
BLINN_PHONG = 1,
COOK_TORRANCE = 2,
GGX = 3,
PHONG = 4,
}
internal enum SvbrdfSpecularVariantWard // Ward variants
{
GEISLERMORODER, // 2010 (albedo-conservative, should always be preferred!)
DUER, // 2006
WARD, // 1992 (original paper)
}
internal enum SvbrdfSpecularVariantBlinn // Blinn-Phong variants
{
ASHIKHMIN_SHIRLEY, // 2000
BLINN, // 1977 (original paper)
VRAY,
LEWIS, // 1993
}
internal enum SvbrdfFresnelVariant
{
NO_FRESNEL, // No fresnel
FRESNEL, // Full fresnel (1818)
SCHLICK, // Schlick's Approximation (1994)
}
internal enum AxFMappingMode
{
UV0,
UV1,
UV2,
UV3,
PlanarXY,
PlanarYZ,
PlanarZX,
Triplanar,
}
internal static class AxFAPI
{
/////////////////////////////////////////////////////////////////////////////////////////////////
// AxF material keywords
const string kIntPropAsFloatSuffix = "F"; // for _FlagsF _SVBRDF_BRDFTypeF _SVBRDF_BRDFVariantsF _CarPaint2_FlakeMaxThetaIF _CarPaint2_FlakeNumThetaFF _CarPaint2_FlakeNumThetaIF
const string kFlags = "_Flags";
const string kFlagsB = "_FlagsB";
const string kSVBRDF_BRDFType = "_SVBRDF_BRDFType";
const string kSVBRDF_BRDFVariants = "_SVBRDF_BRDFVariants";
const string kSVBRDF_BRDFType_DiffuseType = "_SVBRDF_BRDFType_DiffuseType";
const string kSVBRDF_BRDFType_SpecularType = "_SVBRDF_BRDFType_SpecularType";
const string kSVBRDF_BRDFVariants_FresnelType = "_SVBRDF_BRDFVariants_FresnelType";
const string kSVBRDF_BRDFVariants_WardType = "_SVBRDF_BRDFVariants_WardType";
const string kSVBRDF_BRDFVariants_BlinnType = "_SVBRDF_BRDFVariants_BlinnType";
const string kCarPaint2_FlakeMaxThetaI = "_CarPaint2_FlakeMaxThetaI";
const string kCarPaint2_FlakeNumThetaF = "_CarPaint2_FlakeNumThetaF";
const string kCarPaint2_FlakeNumThetaI = "_CarPaint2_FlakeNumThetaI";
const string kAxF_BRDFType = "_AxF_BRDFType";
const string kMappingMode = "_MappingMode";
const string kMappingMask = "_MappingMask";
const string kPlanarSpace = "_PlanarSpace";
static public Vector4 AxFMappingModeToMask(AxFMappingMode mappingMode)
{
Vector4 mask = Vector4.zero;
if (mappingMode <= AxFMappingMode.UV3)
{
float X, Y, Z, W;
X = (mappingMode == AxFMappingMode.UV0) ? 1.0f : 0.0f;
Y = (mappingMode == AxFMappingMode.UV1) ? 1.0f : 0.0f;
Z = (mappingMode == AxFMappingMode.UV2) ? 1.0f : 0.0f;
W = (mappingMode == AxFMappingMode.UV3) ? 1.0f : 0.0f;
mask = new Vector4(X, Y, Z, W);
}
else if (mappingMode < AxFMappingMode.Triplanar)
{
float X, Y, Z, W;
X = (mappingMode == AxFMappingMode.PlanarYZ) ? 1.0f : 0.0f;
Y = (mappingMode == AxFMappingMode.PlanarZX) ? 1.0f : 0.0f;
Z = (mappingMode == AxFMappingMode.PlanarXY) ? 1.0f : 0.0f;
W = 0.0f;
mask = new Vector4(X, Y, Z, W);
}
return mask;
}
// All Validate functions must be static. It allows to automatically update the shaders with a script if code changes
public static void ValidateMaterial(Material material)
{
material.SetupBaseUnlitKeywords();
material.SetupBaseUnlitPass();
AxfBrdfType BRDFType = (AxfBrdfType)material.GetFloat(kAxF_BRDFType);
CoreUtils.SetKeyword(material, "_AXF_BRDF_TYPE_SVBRDF", BRDFType == AxfBrdfType.SVBRDF);
CoreUtils.SetKeyword(material, "_AXF_BRDF_TYPE_CAR_PAINT", BRDFType == AxfBrdfType.CAR_PAINT);
//unsupported for now: CoreUtils.SetKeyword(material, "_AXF_BRDF_TYPE_BTF", BRDFType == AxfBrdfType.BTF);
// Mapping Modes:
AxFMappingMode mappingMode = (AxFMappingMode)material.GetFloat(kMappingMode);
// Make sure the mask is synched:
material.SetVector(kMappingMask, AxFMappingModeToMask(mappingMode));
bool mappingIsPlanar = (mappingMode >= AxFMappingMode.PlanarXY) && (mappingMode < AxFMappingMode.Triplanar);
bool planarIsLocal = (material.GetFloat(kPlanarSpace) > 0.0f);
CoreUtils.SetKeyword(material, "_MAPPING_PLANAR", mappingIsPlanar);
CoreUtils.SetKeyword(material, "_MAPPING_TRIPLANAR", mappingMode == AxFMappingMode.Triplanar);
if (mappingIsPlanar || mappingMode == AxFMappingMode.Triplanar)
{
CoreUtils.SetKeyword(material, "_PLANAR_LOCAL", planarIsLocal);
}
// Note: for ShaderPass defines for vertmesh/varyingmesh setup, we still use the same
// defines _REQUIRE_UV2 and _REQUIRE_UV3, and thus if eg _REQUIRE_UV3 is defined, _REQUIRE_UV2 will
// be assumed to be needed. But here in the AxFData sampling code, we use these to indicate precisely
// the single set used (if not using planar/triplanar) only and thus add _REQUIRE_UV1.
// Extra UVs might be transfered but we only need and support a single set at a time for the whole material.
CoreUtils.SetKeyword(material, "_REQUIRE_UV1", mappingMode == AxFMappingMode.UV1);
CoreUtils.SetKeyword(material, "_REQUIRE_UV2", mappingMode == AxFMappingMode.UV2);
CoreUtils.SetKeyword(material, "_REQUIRE_UV3", mappingMode == AxFMappingMode.UV3);
// Keywords for opt-out of decals and SSR:
bool decalsEnabled = material.HasProperty(kEnableDecals) && material.GetFloat(kEnableDecals) > 0.0f;
CoreUtils.SetKeyword(material, "_DISABLE_DECALS", !decalsEnabled);
bool ssrEnabled = false;
if (material.GetSurfaceType() == SurfaceType.Transparent)
ssrEnabled = material.HasProperty(kReceivesSSRTransparent) ? material.GetFloat(kReceivesSSRTransparent) != 0 : false;
else
ssrEnabled = material.HasProperty(kReceivesSSR) ? material.GetFloat(kReceivesSSR) != 0 : false;
CoreUtils.SetKeyword(material, "_DISABLE_SSR", material.HasProperty(kReceivesSSR) && material.GetFloat(kReceivesSSR) == 0.0f);
CoreUtils.SetKeyword(material, "_DISABLE_SSR_TRANSPARENT", material.HasProperty(kReceivesSSRTransparent) && material.GetFloat(kReceivesSSRTransparent) == 0.0);
CoreUtils.SetKeyword(material, "_ENABLE_GEOMETRIC_SPECULAR_AA", material.HasProperty(kEnableGeometricSpecularAA) && material.GetFloat(kEnableGeometricSpecularAA) > 0.0f);
CoreUtils.SetKeyword(material, "_SPECULAR_OCCLUSION_NONE", material.HasProperty(kSpecularOcclusionMode) && material.GetFloat(kSpecularOcclusionMode) == 0.0f);
bool excludeFromTUAndAA = BaseLitAPI.CompatibleWithExcludeFromTUAndAA(material) && material.GetInt(kExcludeFromTUAndAA) != 0;
BaseLitAPI.SetupStencil(material, receivesLighting: true, receivesSSR: ssrEnabled, useSplitLighting: false, excludeFromTUAndAA: excludeFromTUAndAA);
//
// Patch for raytracing for now: mirror int props as float explicitly
//
uint flags = (uint)material.GetFloat(kFlags);
flags |= (uint)AxF.FeatureFlags.AxfDebugTest; // force bit 23 = 1
material.SetFloat(kFlagsB, flags);
uint SVBRDFType = (uint)material.GetFloat(kSVBRDF_BRDFType);
uint SVBRDFVariants = (uint)material.GetFloat(kSVBRDF_BRDFVariants);
SvbrdfDiffuseType diffuseType = (SvbrdfDiffuseType)(SVBRDFType & 0x1);
SvbrdfSpecularType specularType = (SvbrdfSpecularType)((SVBRDFType >> 1) & 0x7);
SvbrdfFresnelVariant fresnelVariant = (SvbrdfFresnelVariant)(SVBRDFVariants & 0x3);
SvbrdfSpecularVariantWard wardVariant = (SvbrdfSpecularVariantWard)((SVBRDFVariants >> 2) & 0x3);
SvbrdfSpecularVariantBlinn blinnVariant = (SvbrdfSpecularVariantBlinn)((SVBRDFVariants >> 4) & 0x3);
material.SetFloat(kSVBRDF_BRDFType_DiffuseType, (float)diffuseType);
material.SetFloat(kSVBRDF_BRDFType_SpecularType, (float)specularType);
material.SetFloat(kSVBRDF_BRDFVariants_FresnelType, (float)fresnelVariant);
material.SetFloat(kSVBRDF_BRDFVariants_WardType, (float)wardVariant);
material.SetFloat(kSVBRDF_BRDFVariants_BlinnType, (float)blinnVariant);
material.SetFloat(kCarPaint2_FlakeMaxThetaI + kIntPropAsFloatSuffix, material.GetFloat(kCarPaint2_FlakeMaxThetaI));
material.SetFloat(kCarPaint2_FlakeNumThetaF + kIntPropAsFloatSuffix, material.GetFloat(kCarPaint2_FlakeNumThetaF));
material.SetFloat(kCarPaint2_FlakeNumThetaI + kIntPropAsFloatSuffix, material.GetFloat(kCarPaint2_FlakeNumThetaI));
}
}
}