You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
8.2 KiB
142 lines
8.2 KiB
void BuildSurfaceData(FragInputs fragInputs, inout SurfaceDescription surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
|
|
// specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct
|
|
// however specularOcclusion can come from the graph, so need to be init here so it can be override.
|
|
surfaceData.specularOcclusion = 1.0;
|
|
surfaceData.thickness = 0.0;
|
|
|
|
$SurfaceDescription.BaseColor: surfaceData.baseColor = surfaceDescription.BaseColor;
|
|
$SurfaceDescription.Smoothness: surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;
|
|
$SurfaceDescription.Occlusion: surfaceData.ambientOcclusion = surfaceDescription.Occlusion;
|
|
$SurfaceDescription.SpecularOcclusion: surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;
|
|
$SurfaceDescription.Metallic: surfaceData.metallic = surfaceDescription.Metallic;
|
|
$SurfaceDescription.SubsurfaceMask: surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;
|
|
$SurfaceDescription.TransmissionMask: surfaceData.transmissionMask = surfaceDescription.TransmissionMask.xxx;
|
|
$SurfaceDescription.Thickness: surfaceData.thickness = surfaceDescription.Thickness;
|
|
$SurfaceDescription.DiffusionProfileHash: surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);
|
|
$SurfaceDescription.Specular: surfaceData.specularColor = surfaceDescription.Specular;
|
|
$SurfaceDescription.CoatMask: surfaceData.coatMask = surfaceDescription.CoatMask;
|
|
$SurfaceDescription.Anisotropy: surfaceData.anisotropy = surfaceDescription.Anisotropy;
|
|
$SurfaceDescription.IridescenceMask: surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;
|
|
$SurfaceDescription.IridescenceThickness: surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;
|
|
|
|
#if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)
|
|
if (_EnableSSRefraction)
|
|
{
|
|
$SurfaceDescription.RefractionIndex: surfaceData.ior = surfaceDescription.RefractionIndex;
|
|
$SurfaceDescription.RefractionColor: surfaceData.transmittanceColor = surfaceDescription.RefractionColor;
|
|
$SurfaceDescription.RefractionDistance: surfaceData.atDistance = surfaceDescription.RefractionDistance;
|
|
|
|
surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
// These static material feature allow compile time optimization
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_COLORED_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_COLORED_TRANSMISSION;
|
|
|
|
$SurfaceDescription.TransmissionTint: surfaceData.transmissionMask = surfaceDescription.TransmissionTint;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
|
|
// Initialize the normal to something non-zero to avoid a div-zero warning for anisotropy.
|
|
surfaceData.normalWS = float3(0, 1, 0);
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_CLEAR_COAT
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
// Require to have setup baseColor
|
|
// Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
float3 doubleSidedConstants = GetDoubleSidedConstants();
|
|
|
|
ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, surfaceData);
|
|
|
|
surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];
|
|
|
|
surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
|
|
$SurfaceDescription.TangentOS: surfaceData.tangentWS = TransformObjectToWorldNormal(surfaceDescription.TangentOS);
|
|
$SurfaceDescription.TangentTS: surfaceData.tangentWS = TransformTangentToWorld(surfaceDescription.TangentTS, fragInputs.tangentToWorld);
|
|
$SurfaceDescription.TangentWS: surfaceData.tangentWS = surfaceDescription.TangentWS;
|
|
|
|
bentNormalWS = surfaceData.normalWS;
|
|
$BentNormal: GetNormalWS(fragInputs, surfaceDescription.BentNormal, bentNormalWS, doubleSidedConstants);
|
|
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#ifdef DEBUG_DISPLAY
|
|
#if !defined(SHADER_STAGE_RAY_TRACING)
|
|
// Mipmap mode debugging isn't supported with ray tracing as it relies on derivatives
|
|
if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)
|
|
{
|
|
#ifdef FRAG_INPUTS_USE_TEXCOORD0
|
|
surfaceData.baseColor = GET_TEXTURE_STREAMING_DEBUG(posInput.positionSS, fragInputs.texCoord0);
|
|
#else
|
|
surfaceData.baseColor = GET_TEXTURE_STREAMING_DEBUG_NO_UV(posInput.positionSS);
|
|
#endif
|
|
surfaceData.metallic = 0;
|
|
}
|
|
#endif
|
|
|
|
// We need to call ApplyDebugToSurfaceData after filling the surfaceData and before filling builtinData
|
|
// as it can modify attribute use for static lighting
|
|
ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);
|
|
#endif
|
|
|
|
// By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.
|
|
// If user provide bent normal then we process a better term
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
// Just use the value passed through via the slot (not active otherwise)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
// If we have bent normal and ambient occlusion, process a specular occlusion
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#endif
|
|
|
|
#if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|