Refactor in prepration for ATOM-14688 "Disable Individual Layers"
Refactored StandardMultilayerPBR to collate all the code for each layer into a couple structs and utility functions. This makes the code easier to maintain, and in particular will make it easy for me to add Enable flags for the layers in a subsequent commit. Also removed subsurface scattering and translucency from StandardMultilayerPBR, according to ATOM-4120 "Stabilize Standard PBR Regarding Subsurface and Translucency". Squashed commit of the following: commit a6052d6ad4f70183d0ce72e84c7dc5512dc24d5e Author: Chris Santora <santorac@amazon.com> Date: Tue May 11 16:32:15 2021 -0700 Got the refactor finally working. I had change it to blend the baseColor, spec factor, and metalness before converting to albedo and spec, in order to get exactly the same results as before. commit 42d6da7f405097dea07b6ed0426d6a662b61440d Author: Chris Santora <santorac@amazon.com> Date: Tue May 11 15:58:38 2021 -0700 Fixed clear coat issue due to LightingData initialized too late. commit 358194a5caf6f9eb99b0e5345ad5f7768b244a93 Author: Chris Santora <santorac@amazon.com> Date: Tue May 11 15:18:30 2021 -0700 Fixed a couple issues. commit adb431f8113b945057959db288a7ee2dd825dd69 Author: Chris Santora <santorac@amazon.com> Date: Tue May 11 12:42:12 2021 -0700 WIP refactor of StandardMultilayerPBR to collate the code for each layer. Also removed subsurface scattering from multilayer.
This commit is contained in:
@@ -23,11 +23,6 @@
|
||||
"displayName": "UVs",
|
||||
"description": "Properties for configuring UV transforms for the entire material, including the blend masks."
|
||||
},
|
||||
{
|
||||
"id": "subsurfaceScattering",
|
||||
"displayName": "Subsurface Scattering",
|
||||
"description": "Properties for configuring subsurface scattering effects."
|
||||
},
|
||||
{
|
||||
// Note: this property group is used in the DiffuseGlobalIllumination pass, it is not read by the StandardPBR shader
|
||||
"id": "irradiance",
|
||||
@@ -467,183 +462,6 @@
|
||||
"step": 0.1
|
||||
}
|
||||
],
|
||||
"subsurfaceScattering": [
|
||||
{
|
||||
"id": "enableSubsurfaceScattering",
|
||||
"displayName": "Subsurface Scattering",
|
||||
"description": "Enable subsurface scattering feature, this will disable metallic and parallax mapping property due to incompatibility",
|
||||
"type": "Bool",
|
||||
"defaultValue": false,
|
||||
"connection": {
|
||||
"type": "ShaderOption",
|
||||
"id": "o_enableSubsurfaceScattering"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "subsurfaceScatterFactor",
|
||||
"displayName": " Factor",
|
||||
"description": "Strength factor for scaling percentage of subsurface scattering effect applied",
|
||||
"type": "float",
|
||||
"defaultValue": 1.0,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"id": "m_subsurfaceScatteringFactor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "influenceMap",
|
||||
"displayName": " Influence Map",
|
||||
"description": "Use texture map to control the strength of subsurface scattering",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"id": "m_subsurfaceScatteringInfluenceMap"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "useInfluenceMap",
|
||||
"displayName": " Use Influence Map",
|
||||
"description": "Whether to use the texture map as influence mask.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "influenceMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Influence map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"id": "m_subsurfaceScatteringInfluenceMapUvIndex"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "scatterColor",
|
||||
"displayName": " Scatter color",
|
||||
"description": "Color of volume light traveled through",
|
||||
"type": "Color",
|
||||
"defaultValue": [ 1.0, 0.27, 0.13 ]
|
||||
},
|
||||
{
|
||||
"id": "scatterDistance",
|
||||
"displayName": " Scatter distance",
|
||||
"description": "How far light traveled inside the volume",
|
||||
"type": "float",
|
||||
"defaultValue": 8,
|
||||
"min": 0.0,
|
||||
"softMax": 20.0
|
||||
},
|
||||
{
|
||||
"id": "quality",
|
||||
"displayName": " Quality",
|
||||
"description": "How much percent of sample will be used for each pixel, more samples improve quality and reduce artifacts, especially when the scatter distance is relatively large, but slow down computation time, 1.0 = full set 200 samples per pixel",
|
||||
"type": "float",
|
||||
"defaultValue": 0.4,
|
||||
"min": 0.2,
|
||||
"max": 1.0,
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"id": "m_subsurfaceScatteringQuality"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "transmissionMode",
|
||||
"displayName": "Transmission",
|
||||
"description": "Algorithm used for calculating transmission",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "None", "ThickObject", "ThinObject" ],
|
||||
"defaultValue": "None",
|
||||
"connection": {
|
||||
"type": "ShaderOption",
|
||||
"id": "o_transmission_mode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "thickness",
|
||||
"displayName": " Thickness",
|
||||
"description": "Normalized global thickness, the maxima between this value (multiplied by thickness map if enabled) and thickness from shadow map (if applicable) will be used as final thickness of pixel",
|
||||
"type": "float",
|
||||
"defaultValue": 0.5,
|
||||
"min": 0.0,
|
||||
"max": 1.0
|
||||
},
|
||||
{
|
||||
"id": "thicknessMap",
|
||||
"displayName": " Thickness Map",
|
||||
"description": "Use a greyscale texture for per pixel thickness",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"id": "m_transmissionThicknessMap"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "useThicknessMap",
|
||||
"displayName": " Use Thickness Map",
|
||||
"description": "Whether to use the thickness map",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "thicknessMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Thickness map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
"id": "m_transmissionThicknessMapUvIndex"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "transmissionTint",
|
||||
"displayName": " Transmission Tint",
|
||||
"description": "Color of the volume light travelling through",
|
||||
"type": "Color",
|
||||
"defaultValue": [ 1.0, 0.8, 0.6 ]
|
||||
},
|
||||
{
|
||||
"id": "transmissionPower",
|
||||
"displayName": " Power",
|
||||
"description": "How much transmitted light scatter radially ",
|
||||
"type": "float",
|
||||
"defaultValue": 6.0,
|
||||
"min": 0.0,
|
||||
"softMax": 20.0
|
||||
},
|
||||
{
|
||||
"id": "transmissionDistortion",
|
||||
"displayName": " Distortion",
|
||||
"description": "How much light direction distorted towards surface normal",
|
||||
"type": "float",
|
||||
"defaultValue": 0.1,
|
||||
"min": 0.0,
|
||||
"max": 1.0
|
||||
},
|
||||
{
|
||||
"id": "transmissionAttenuation",
|
||||
"displayName": " Attenuation",
|
||||
"description": "How fast transmitted light fade with thickness",
|
||||
"type": "float",
|
||||
"defaultValue": 4.0,
|
||||
"min": 0.0,
|
||||
"softMax": 20.0
|
||||
},
|
||||
{
|
||||
"id": "transmissionScale",
|
||||
"displayName": " Scale",
|
||||
"description": "Strength of transmission",
|
||||
"type": "float",
|
||||
"defaultValue": 3.0,
|
||||
"min": 0.0,
|
||||
"softMax": 20.0
|
||||
}
|
||||
],
|
||||
"irradiance": [
|
||||
// Note: this property group is used in the DiffuseGlobalIllumination pass, it is not read by the StandardPBR shader
|
||||
{
|
||||
@@ -2844,25 +2662,6 @@
|
||||
"file": "StandardMultilayerPBR_ShaderEnable.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
// Preprocess & build parameter set for subsurface scattering and translucency
|
||||
"type": "HandleSubsurfaceScatteringParameters",
|
||||
"args": {
|
||||
"mode": "subsurfaceScattering.transmissionMode",
|
||||
"scale" : "subsurfaceScattering.transmissionScale",
|
||||
"power" : "subsurfaceScattering.transmissionPower",
|
||||
"distortion" : "subsurfaceScattering.transmissionDistortion",
|
||||
"attenuation" : "subsurfaceScattering.transmissionAttenuation",
|
||||
"tintColor" : "subsurfaceScattering.transmissionTint",
|
||||
"thickness" : "subsurfaceScattering.thickness",
|
||||
"enabled": "subsurfaceScattering.enableSubsurfaceScattering",
|
||||
"scatterDistanceColor" : "subsurfaceScattering.scatterColor",
|
||||
"scatterDistanceIntensity" : "subsurfaceScattering.scatterDistance",
|
||||
"scatterDistanceShaderInput" : "m_scatterDistance",
|
||||
"parametersShaderInput" : "m_transmissionParams",
|
||||
"tintThickenssShaderInput" : "m_transmissionTintThickness"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Lua",
|
||||
"args": {
|
||||
@@ -2875,12 +2674,6 @@
|
||||
"file": "StandardMultilayerPBR_Parallax.lua"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Lua",
|
||||
"args": {
|
||||
"file": "StandardPBR_SubsurfaceState.lua"
|
||||
}
|
||||
},
|
||||
//##############################################################################################
|
||||
// Layer 1 Functors
|
||||
//##############################################################################################
|
||||
|
||||
@@ -91,24 +91,6 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
|
||||
MipFilter = Linear;
|
||||
};
|
||||
|
||||
// Parameters for subsurface scattering
|
||||
float m_subsurfaceScatteringFactor;
|
||||
float m_subsurfaceScatteringQuality;
|
||||
float3 m_scatterDistance;
|
||||
Texture2D m_subsurfaceScatteringInfluenceMap;
|
||||
uint m_subsurfaceScatteringInfluenceMapUvIndex;
|
||||
|
||||
// Parameters for transmission
|
||||
|
||||
// Elements of m_transmissionParams:
|
||||
// Thick object mode: (attenuation coefficient, power, distortion, scale)
|
||||
// Thin object mode: (float3 scatter distance, scale)
|
||||
float4 m_transmissionParams;
|
||||
|
||||
// (float3 TintColor, thickness)
|
||||
float4 m_transmissionTintThickness;
|
||||
Texture2D m_transmissionThicknessMap;
|
||||
uint m_transmissionThicknessMapUvIndex;
|
||||
}
|
||||
|
||||
// ------ Shader Options ----------------------------------------
|
||||
|
||||
+230
-168
@@ -55,7 +55,6 @@ DEFINE_LAYER_OPTIONS(o_layer1_)
|
||||
DEFINE_LAYER_OPTIONS(o_layer2_)
|
||||
DEFINE_LAYER_OPTIONS(o_layer3_)
|
||||
|
||||
#include "MaterialInputs/SubsurfaceInput.azsli"
|
||||
#include "MaterialInputs/TransmissionInput.azsli"
|
||||
#include "StandardMultilayerPBR_Common.azsli"
|
||||
|
||||
@@ -127,6 +126,181 @@ VSOutput ForwardPassVS(VSInput IN)
|
||||
return OUT;
|
||||
}
|
||||
|
||||
//! Collects all the raw Standard material inputs for a single layer. See ProcessStandardMaterialInputs().
|
||||
struct StandardMaterialInputs
|
||||
{
|
||||
COMMON_SRG_INPUTS_BASE_COLOR()
|
||||
COMMON_SRG_INPUTS_ROUGHNESS()
|
||||
COMMON_SRG_INPUTS_METALLIC()
|
||||
COMMON_SRG_INPUTS_SPECULAR_F0()
|
||||
COMMON_SRG_INPUTS_NORMAL()
|
||||
COMMON_SRG_INPUTS_CLEAR_COAT()
|
||||
COMMON_SRG_INPUTS_OCCLUSION()
|
||||
COMMON_SRG_INPUTS_EMISSIVE()
|
||||
// Note parallax is omitted here because that requires special handling.
|
||||
|
||||
bool m_normal_useTexture;
|
||||
bool m_baseColor_useTexture;
|
||||
bool m_metallic_useTexture;
|
||||
bool m_specularF0_useTexture;
|
||||
bool m_roughness_useTexture;
|
||||
bool m_emissiveEnabled;
|
||||
bool m_emissive_useTexture;
|
||||
bool m_diffuseOcclusion_useTexture;
|
||||
bool m_specularOcclusion_useTexture;
|
||||
bool m_clearCoatEnabled;
|
||||
bool m_clearCoat_factor_useTexture;
|
||||
bool m_clearCoat_roughness_useTexture;
|
||||
bool m_clearCoat_normal_useTexture;
|
||||
|
||||
TextureBlendMode m_baseColorTextureBlendMode;
|
||||
|
||||
float2 m_vertexUv[UvSetCount];
|
||||
float3x3 m_uvMatrix;
|
||||
float m_normal;
|
||||
float3 m_tangents[UvSetCount];
|
||||
float3 m_bitangents[UvSetCount];
|
||||
|
||||
sampler m_sampler;
|
||||
|
||||
bool m_isFrontFace;
|
||||
};
|
||||
|
||||
//! Holds the final processed material inputs, after all flags have been checked, textures have been sampled, factors have been applied, etc.
|
||||
//! This data is ready to be copied into a Surface and/or LightingData struct for the lighting system to consume.
|
||||
class ProcessedMaterialInputs
|
||||
{
|
||||
float3 m_normalTS; //!< Normal in tangent-space
|
||||
float3 m_baseColor;
|
||||
float3 m_specularF0Factor;
|
||||
float m_metallic;
|
||||
float m_roughness;
|
||||
float3 m_emissiveLighting;
|
||||
float m_diffuseAmbientOcclusion;
|
||||
float m_specularOcclusion;
|
||||
ClearCoatSurfaceData m_clearCoat;
|
||||
|
||||
void InitializeToZero()
|
||||
{
|
||||
m_normalTS = float3(0,0,0);
|
||||
m_baseColor = float3(0,0,0);
|
||||
m_specularF0Factor = float3(0,0,0);
|
||||
m_metallic = 0.0f;
|
||||
m_roughness = 0.0f;
|
||||
m_emissiveLighting = float3(0,0,0);
|
||||
m_diffuseAmbientOcclusion = 0;
|
||||
m_specularOcclusion = 0;
|
||||
m_clearCoat.InitializeToZero();
|
||||
}
|
||||
};
|
||||
|
||||
//! Processes the set of Standard material inputs for a single layer.
|
||||
//! The FILL_STANDARD_MATERIAL_INPUTS() macro below can be used to fill the StandardMaterialInputs struct.
|
||||
ProcessedMaterialInputs ProcessStandardMaterialInputs(StandardMaterialInputs inputs)
|
||||
{
|
||||
ProcessedMaterialInputs result;
|
||||
|
||||
float2 transformedUv[UvSetCount];
|
||||
transformedUv[0] = mul(inputs.m_uvMatrix, float3(inputs.m_vertexUv[0], 1.0)).xy;
|
||||
transformedUv[1] = inputs.m_vertexUv[1];
|
||||
|
||||
float3x3 normalUvMatrix = inputs.m_normalMapUvIndex == 0 ? inputs.m_uvMatrix : CreateIdentity3x3();
|
||||
result.m_normalTS = GetNormalInputTS(inputs.m_normalMap, inputs.m_sampler, transformedUv[inputs.m_normalMapUvIndex], inputs.m_flipNormalX, inputs.m_flipNormalY, normalUvMatrix, inputs.m_normal_useTexture, inputs.m_normalFactor);
|
||||
|
||||
float3 sampledBaseColor = GetBaseColorInput(inputs.m_baseColorMap, inputs.m_sampler, transformedUv[inputs.m_baseColorMapUvIndex], inputs.m_baseColor.rgb, inputs.m_baseColor_useTexture);
|
||||
result.m_baseColor = BlendBaseColor(sampledBaseColor, inputs.m_baseColor.rgb, inputs.m_baseColorFactor, inputs.m_baseColorTextureBlendMode, inputs.m_baseColor_useTexture);
|
||||
result.m_specularF0Factor = GetSpecularInput(inputs.m_specularF0Map, inputs.m_sampler, transformedUv[inputs.m_specularF0MapUvIndex], inputs.m_specularF0Factor, inputs.m_specularF0_useTexture);
|
||||
result.m_metallic = GetMetallicInput(inputs.m_metallicMap, inputs.m_sampler, transformedUv[inputs.m_metallicMapUvIndex], inputs.m_metallicFactor, inputs.m_metallic_useTexture);
|
||||
result.m_roughness = GetRoughnessInput(inputs.m_roughnessMap, MaterialSrg::m_sampler, transformedUv[inputs.m_roughnessMapUvIndex], inputs.m_roughnessFactor, inputs.m_roughnessLowerBound, inputs.m_roughnessUpperBound, inputs.m_roughness_useTexture);
|
||||
|
||||
result.m_emissiveLighting = GetEmissiveInput(inputs.m_emissiveMap, inputs.m_sampler, transformedUv[inputs.m_emissiveMapUvIndex], inputs.m_emissiveIntensity, inputs.m_emissiveColor.rgb, inputs.m_emissiveEnabled, inputs.m_emissive_useTexture);
|
||||
result.m_diffuseAmbientOcclusion = GetOcclusionInput(inputs.m_diffuseOcclusionMap, inputs.m_sampler, transformedUv[inputs.m_diffuseOcclusionMapUvIndex], inputs.m_diffuseOcclusionFactor, inputs.m_diffuseOcclusion_useTexture);
|
||||
result.m_specularOcclusion = GetOcclusionInput(inputs.m_specularOcclusionMap, MaterialSrg::m_sampler, transformedUv[inputs.m_specularOcclusionMapUvIndex], inputs.m_specularOcclusionFactor, inputs.m_specularOcclusion_useTexture);
|
||||
|
||||
result.m_clearCoat.InitializeToZero();
|
||||
if(inputs.m_clearCoatEnabled)
|
||||
{
|
||||
float3x3 clearCoatUvMatrix = inputs.m_clearCoatNormalMapUvIndex == 0 ? inputs.m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(inputs.m_clearCoatInfluenceMap, transformedUv[inputs.m_clearCoatInfluenceMapUvIndex], inputs.m_clearCoatFactor, inputs.m_clearCoat_factor_useTexture,
|
||||
inputs.m_clearCoatRoughnessMap, transformedUv[inputs.m_clearCoatRoughnessMapUvIndex], inputs.m_clearCoatRoughness, inputs.m_clearCoat_roughness_useTexture,
|
||||
inputs.m_clearCoatNormalMap, transformedUv[inputs.m_clearCoatNormalMapUvIndex], inputs.m_normal, inputs.m_clearCoat_normal_useTexture, inputs.m_clearCoatNormalStrength,
|
||||
clearCoatUvMatrix, inputs.m_tangents[inputs.m_clearCoatNormalMapUvIndex], inputs.m_bitangents[inputs.m_clearCoatNormalMapUvIndex],
|
||||
inputs.m_sampler, inputs.m_isFrontFace,
|
||||
result.m_clearCoat.factor, result.m_clearCoat.roughness, result.m_clearCoat.normal);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Fills a StandardMaterialInputs struct with data from the MaterialSrg, shader options, and local vertex data.
|
||||
#define FILL_STANDARD_MATERIAL_INPUTS(inputs, srgLayerPrefix, optionsLayerPrefix, blendWeight) \
|
||||
inputs.m_sampler = MaterialSrg::m_sampler; \
|
||||
inputs.m_vertexUv = IN.m_uv; \
|
||||
inputs.m_uvMatrix = srgLayerPrefix##m_uvMatrix; \
|
||||
inputs.m_normal = IN.m_normal; \
|
||||
inputs.m_tangents = tangents; \
|
||||
inputs.m_bitangents = bitangents; \
|
||||
inputs.m_isFrontFace = isFrontFace; \
|
||||
\
|
||||
inputs.m_normalMapUvIndex = srgLayerPrefix##m_normalMapUvIndex; \
|
||||
inputs.m_normalMap = srgLayerPrefix##m_normalMap; \
|
||||
inputs.m_flipNormalX = srgLayerPrefix##m_flipNormalX; \
|
||||
inputs.m_flipNormalY = srgLayerPrefix##m_flipNormalY; \
|
||||
inputs.m_normal_useTexture = optionsLayerPrefix##o_normal_useTexture; \
|
||||
inputs.m_normalFactor = srgLayerPrefix##m_normalFactor * blendWeight; \
|
||||
inputs.m_baseColorMap = srgLayerPrefix##m_baseColorMap; \
|
||||
inputs.m_baseColorMapUvIndex = srgLayerPrefix##m_baseColorMapUvIndex; \
|
||||
inputs.m_baseColor = srgLayerPrefix##m_baseColor; \
|
||||
inputs.m_baseColor_useTexture = optionsLayerPrefix##o_baseColor_useTexture; \
|
||||
inputs.m_baseColorFactor = srgLayerPrefix##m_baseColorFactor; \
|
||||
inputs.m_baseColorTextureBlendMode = optionsLayerPrefix##o_baseColorTextureBlendMode; \
|
||||
inputs.m_metallicMap = srgLayerPrefix##m_metallicMap; \
|
||||
inputs.m_metallicMapUvIndex = srgLayerPrefix##m_metallicMapUvIndex; \
|
||||
inputs.m_metallicFactor = srgLayerPrefix##m_metallicFactor; \
|
||||
inputs.m_metallic_useTexture = optionsLayerPrefix##o_metallic_useTexture; \
|
||||
inputs.m_specularF0Map = srgLayerPrefix##m_specularF0Map; \
|
||||
inputs.m_specularF0MapUvIndex = srgLayerPrefix##m_specularF0MapUvIndex; \
|
||||
inputs.m_specularF0Factor = srgLayerPrefix##m_specularF0Factor; \
|
||||
inputs.m_specularF0_useTexture = optionsLayerPrefix##o_specularF0_useTexture; \
|
||||
inputs.m_roughnessMap = srgLayerPrefix##m_roughnessMap; \
|
||||
inputs.m_roughnessMapUvIndex = srgLayerPrefix##m_roughnessMapUvIndex; \
|
||||
inputs.m_roughnessFactor = srgLayerPrefix##m_roughnessFactor; \
|
||||
inputs.m_roughnessLowerBound = srgLayerPrefix##m_roughnessLowerBound; \
|
||||
inputs.m_roughnessUpperBound = srgLayerPrefix##m_roughnessUpperBound; \
|
||||
inputs.m_roughness_useTexture = optionsLayerPrefix##o_roughness_useTexture; \
|
||||
\
|
||||
inputs.m_emissiveMap = srgLayerPrefix##m_emissiveMap; \
|
||||
inputs.m_emissiveMapUvIndex = srgLayerPrefix##m_emissiveMapUvIndex; \
|
||||
inputs.m_emissiveIntensity = srgLayerPrefix##m_emissiveIntensity; \
|
||||
inputs.m_emissiveColor = srgLayerPrefix##m_emissiveColor; \
|
||||
inputs.m_emissiveEnabled = optionsLayerPrefix##o_emissiveEnabled; \
|
||||
inputs.m_emissive_useTexture = optionsLayerPrefix##o_emissive_useTexture; \
|
||||
\
|
||||
inputs.m_diffuseOcclusionMap = srgLayerPrefix##m_diffuseOcclusionMap; \
|
||||
inputs.m_diffuseOcclusionMapUvIndex = srgLayerPrefix##m_diffuseOcclusionMapUvIndex; \
|
||||
inputs.m_diffuseOcclusionFactor = srgLayerPrefix##m_diffuseOcclusionFactor; \
|
||||
inputs.m_diffuseOcclusion_useTexture = optionsLayerPrefix##o_diffuseOcclusion_useTexture; \
|
||||
\
|
||||
inputs.m_specularOcclusionMap = srgLayerPrefix##m_specularOcclusionMap; \
|
||||
inputs.m_specularOcclusionMapUvIndex = srgLayerPrefix##m_specularOcclusionMapUvIndex; \
|
||||
inputs.m_specularOcclusionFactor = srgLayerPrefix##m_specularOcclusionFactor; \
|
||||
inputs.m_specularOcclusion_useTexture = optionsLayerPrefix##o_specularOcclusion_useTexture; \
|
||||
\
|
||||
inputs.m_clearCoatEnabled = o_clearCoat_feature_enabled && optionsLayerPrefix##o_clearCoat_enabled; \
|
||||
inputs.m_clearCoatInfluenceMap = srgLayerPrefix##m_clearCoatInfluenceMap; \
|
||||
inputs.m_clearCoatInfluenceMapUvIndex = srgLayerPrefix##m_clearCoatInfluenceMapUvIndex; \
|
||||
inputs.m_clearCoatFactor = srgLayerPrefix##m_clearCoatFactor; \
|
||||
inputs.m_clearCoat_factor_useTexture = optionsLayerPrefix##o_clearCoat_factor_useTexture; \
|
||||
inputs.m_clearCoatRoughnessMap = srgLayerPrefix##m_clearCoatRoughnessMap; \
|
||||
inputs.m_clearCoatRoughnessMapUvIndex = srgLayerPrefix##m_clearCoatRoughnessMapUvIndex; \
|
||||
inputs.m_clearCoatRoughness = srgLayerPrefix##m_clearCoatRoughness; \
|
||||
inputs.m_clearCoat_roughness_useTexture = optionsLayerPrefix##o_clearCoat_roughness_useTexture; \
|
||||
inputs.m_clearCoatNormalMap = srgLayerPrefix##m_clearCoatNormalMap; \
|
||||
inputs.m_clearCoatNormalMapUvIndex = srgLayerPrefix##m_clearCoatNormalMapUvIndex; \
|
||||
inputs.m_clearCoat_normal_useTexture = optionsLayerPrefix##o_clearCoat_normal_useTexture; \
|
||||
inputs.m_clearCoatNormalStrength = srgLayerPrefix##m_clearCoatNormalStrength;
|
||||
|
||||
|
||||
// ---------- Pixel Shader ----------
|
||||
|
||||
@@ -174,7 +348,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
|
||||
bool displacementIsClipped = false;
|
||||
|
||||
// Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scatteirng is enabled
|
||||
if(ShouldHandleParallax())
|
||||
{
|
||||
float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
@@ -197,108 +370,70 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
}
|
||||
}
|
||||
|
||||
Surface surface;
|
||||
surface.position = IN.m_worldPosition;
|
||||
|
||||
// ------- Setup the per-layer UV transforms -------
|
||||
|
||||
float2 uvLayer1[UvSetCount];
|
||||
float2 uvLayer2[UvSetCount];
|
||||
float2 uvLayer3[UvSetCount];
|
||||
|
||||
// Only UV0 will be applied transforms from each layer.
|
||||
uvLayer1[0] = mul(MaterialSrg::m_layer1_m_uvMatrix, float3(IN.m_uv[0], 1.0)).xy;
|
||||
uvLayer2[0] = mul(MaterialSrg::m_layer2_m_uvMatrix, float3(IN.m_uv[0], 1.0)).xy;
|
||||
uvLayer3[0] = mul(MaterialSrg::m_layer3_m_uvMatrix, float3(IN.m_uv[0], 1.0)).xy;
|
||||
uvLayer1[1] = IN.m_uv[1];
|
||||
uvLayer2[1] = IN.m_uv[1];
|
||||
uvLayer3[1] = IN.m_uv[1];
|
||||
|
||||
// ------- Calculate Layer Blend Mask Values -------
|
||||
|
||||
// Now that any parallax has been calculated, we calculate the blend factors for any layers that are impacted by the parallax.
|
||||
float3 blendWeights = GetBlendWeights(IN.m_uv[MaterialSrg::m_blendMaskUvIndex]);
|
||||
|
||||
// ------- Normal -------
|
||||
// ------- Layer 1 (base layer) -----------
|
||||
|
||||
ProcessedMaterialInputs lightingInputLayer1;
|
||||
{
|
||||
StandardMaterialInputs inputs;
|
||||
FILL_STANDARD_MATERIAL_INPUTS(inputs, MaterialSrg::m_layer1_, o_layer1_, blendWeights.r)
|
||||
lightingInputLayer1 = ProcessStandardMaterialInputs(inputs);
|
||||
}
|
||||
|
||||
float3 layer1_normalFactor = MaterialSrg::m_layer1_m_normalFactor * blendWeights.r;
|
||||
float3 layer2_normalFactor = MaterialSrg::m_layer2_m_normalFactor * blendWeights.g;
|
||||
float3 layer3_normalFactor = MaterialSrg::m_layer3_m_normalFactor * blendWeights.b;
|
||||
float3x3 layer1_uvMatrix = MaterialSrg::m_layer1_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer1_m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 layer2_uvMatrix = MaterialSrg::m_layer2_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer2_m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 layer3_uvMatrix = MaterialSrg::m_layer3_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer3_m_uvMatrix : CreateIdentity3x3();
|
||||
float3 layer1_normalTS = GetNormalInputTS(MaterialSrg::m_layer1_m_normalMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_normalMapUvIndex], MaterialSrg::m_layer1_m_flipNormalX, MaterialSrg::m_layer1_m_flipNormalY, layer1_uvMatrix, o_layer1_o_normal_useTexture, layer1_normalFactor);
|
||||
float3 layer2_normalTS = GetNormalInputTS(MaterialSrg::m_layer2_m_normalMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_normalMapUvIndex], MaterialSrg::m_layer2_m_flipNormalX, MaterialSrg::m_layer2_m_flipNormalY, layer2_uvMatrix, o_layer2_o_normal_useTexture, layer2_normalFactor);
|
||||
float3 layer3_normalTS = GetNormalInputTS(MaterialSrg::m_layer3_m_normalMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_normalMapUvIndex], MaterialSrg::m_layer3_m_flipNormalX, MaterialSrg::m_layer3_m_flipNormalY, layer3_uvMatrix, o_layer3_o_normal_useTexture, layer3_normalFactor);
|
||||
// ----------- Layer 2 -----------
|
||||
|
||||
ProcessedMaterialInputs lightingInputLayer2;
|
||||
{
|
||||
StandardMaterialInputs inputs;
|
||||
FILL_STANDARD_MATERIAL_INPUTS(inputs, MaterialSrg::m_layer2_, o_layer2_, blendWeights.g)
|
||||
lightingInputLayer2 = ProcessStandardMaterialInputs(inputs);
|
||||
}
|
||||
|
||||
float3 normalTS = ReorientTangentSpaceNormal(layer1_normalTS, layer2_normalTS);
|
||||
normalTS = ReorientTangentSpaceNormal(normalTS, layer3_normalTS);
|
||||
// ----------- Layer 3 -----------
|
||||
|
||||
ProcessedMaterialInputs lightingInputLayer3;
|
||||
{
|
||||
StandardMaterialInputs inputs;
|
||||
FILL_STANDARD_MATERIAL_INPUTS(inputs, MaterialSrg::m_layer3_, o_layer3_, blendWeights.b)
|
||||
lightingInputLayer3 = ProcessStandardMaterialInputs(inputs);
|
||||
}
|
||||
|
||||
// ------- Combine all layers ---------
|
||||
|
||||
Surface surface;
|
||||
surface.position = IN.m_worldPosition;
|
||||
surface.transmission.InitializeToZero();
|
||||
|
||||
// ------- Combine Normals ---------
|
||||
|
||||
float3 normalTS = lightingInputLayer1.m_normalTS;
|
||||
normalTS = ReorientTangentSpaceNormal(normalTS, lightingInputLayer2.m_normalTS);
|
||||
normalTS = ReorientTangentSpaceNormal(normalTS, lightingInputLayer3.m_normalTS);
|
||||
// [GFX TODO][ATOM-14591]: This will only work if the normal maps all use the same UV stream. We would need to add support for having them in different UV streams.
|
||||
surface.normal = normalize(TangentSpaceToWorld(normalTS, IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex]));
|
||||
|
||||
// ------- Base Color -------
|
||||
|
||||
float2 layer1_baseColorUv = uvLayer1[MaterialSrg::m_layer1_m_baseColorMapUvIndex];
|
||||
float2 layer2_baseColorUv = uvLayer2[MaterialSrg::m_layer2_m_baseColorMapUvIndex];
|
||||
float2 layer3_baseColorUv = uvLayer3[MaterialSrg::m_layer3_m_baseColorMapUvIndex];
|
||||
|
||||
// ------- Combine Albedo, roughness, specular, roughness ---------
|
||||
|
||||
float3 layer1_sampledColor = GetBaseColorInput(MaterialSrg::m_layer1_m_baseColorMap, MaterialSrg::m_sampler, layer1_baseColorUv, MaterialSrg::m_layer1_m_baseColor.rgb, o_layer1_o_baseColor_useTexture);
|
||||
float3 layer2_sampledColor = GetBaseColorInput(MaterialSrg::m_layer2_m_baseColorMap, MaterialSrg::m_sampler, layer2_baseColorUv, MaterialSrg::m_layer2_m_baseColor.rgb, o_layer2_o_baseColor_useTexture);
|
||||
float3 layer3_sampledColor = GetBaseColorInput(MaterialSrg::m_layer3_m_baseColorMap, MaterialSrg::m_sampler, layer3_baseColorUv, MaterialSrg::m_layer3_m_baseColor.rgb, o_layer3_o_baseColor_useTexture);
|
||||
float3 layer1_baseColor = BlendBaseColor(layer1_sampledColor, MaterialSrg::m_layer1_m_baseColor.rgb, MaterialSrg::m_layer1_m_baseColorFactor, o_layer1_o_baseColorTextureBlendMode, o_layer1_o_baseColor_useTexture);
|
||||
float3 layer2_baseColor = BlendBaseColor(layer2_sampledColor, MaterialSrg::m_layer2_m_baseColor.rgb, MaterialSrg::m_layer2_m_baseColorFactor, o_layer2_o_baseColorTextureBlendMode, o_layer2_o_baseColor_useTexture);
|
||||
float3 layer3_baseColor = BlendBaseColor(layer3_sampledColor, MaterialSrg::m_layer3_m_baseColor.rgb, MaterialSrg::m_layer3_m_baseColorFactor, o_layer3_o_baseColorTextureBlendMode, o_layer3_o_baseColor_useTexture);
|
||||
float3 baseColor = BlendLayers(layer1_baseColor, layer2_baseColor, layer3_baseColor, blendWeights);
|
||||
float3 baseColor = BlendLayers(lightingInputLayer1.m_baseColor, lightingInputLayer2.m_baseColor, lightingInputLayer3.m_baseColor, blendWeights);
|
||||
float3 specularF0Factor = BlendLayers(lightingInputLayer1.m_specularF0Factor, lightingInputLayer2.m_specularF0Factor, lightingInputLayer3.m_specularF0Factor, blendWeights);
|
||||
float3 metallic = BlendLayers(lightingInputLayer1.m_metallic, lightingInputLayer2.m_metallic, lightingInputLayer3.m_metallic, blendWeights);
|
||||
|
||||
if(o_parallax_highlightClipping && displacementIsClipped)
|
||||
{
|
||||
ApplyParallaxClippingHighlight(baseColor);
|
||||
}
|
||||
|
||||
// ------- Metallic -------
|
||||
|
||||
float metallic = 0;
|
||||
if(!o_enableSubsurfaceScattering) // If subsurface scattering is enabled skip texture lookup for metallic, as this quantity won't be used anyway
|
||||
{
|
||||
float layer1_metallic = GetMetallicInput(MaterialSrg::m_layer1_m_metallicMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_metallicMapUvIndex], MaterialSrg::m_layer1_m_metallicFactor, o_layer1_o_metallic_useTexture);
|
||||
float layer2_metallic = GetMetallicInput(MaterialSrg::m_layer2_m_metallicMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_metallicMapUvIndex], MaterialSrg::m_layer2_m_metallicFactor, o_layer2_o_metallic_useTexture);
|
||||
float layer3_metallic = GetMetallicInput(MaterialSrg::m_layer3_m_metallicMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_metallicMapUvIndex], MaterialSrg::m_layer3_m_metallicFactor, o_layer3_o_metallic_useTexture);
|
||||
metallic = BlendLayers(layer1_metallic, layer2_metallic, layer3_metallic, blendWeights);
|
||||
}
|
||||
|
||||
// ------- Specular -------
|
||||
|
||||
float layer1_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer1_m_specularF0Map, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularF0MapUvIndex], MaterialSrg::m_layer1_m_specularF0Factor, o_layer1_o_specularF0_useTexture);
|
||||
float layer2_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer2_m_specularF0Map, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularF0MapUvIndex], MaterialSrg::m_layer2_m_specularF0Factor, o_layer2_o_specularF0_useTexture);
|
||||
float layer3_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer3_m_specularF0Map, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularF0MapUvIndex], MaterialSrg::m_layer3_m_specularF0Factor, o_layer3_o_specularF0_useTexture);
|
||||
float specularF0Factor = BlendLayers(layer1_specularF0Factor, layer2_specularF0Factor, layer3_specularF0Factor, blendWeights);
|
||||
|
||||
surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
|
||||
|
||||
// ------- Roughness -------
|
||||
|
||||
float layer1_roughness = GetRoughnessInput(MaterialSrg::m_layer1_m_roughnessMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_roughnessMapUvIndex], MaterialSrg::m_layer1_m_roughnessFactor, MaterialSrg::m_layer1_m_roughnessLowerBound, MaterialSrg::m_layer1_m_roughnessUpperBound, o_layer1_o_roughness_useTexture);
|
||||
float layer2_roughness = GetRoughnessInput(MaterialSrg::m_layer2_m_roughnessMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_roughnessMapUvIndex], MaterialSrg::m_layer2_m_roughnessFactor, MaterialSrg::m_layer2_m_roughnessLowerBound, MaterialSrg::m_layer2_m_roughnessUpperBound, o_layer2_o_roughness_useTexture);
|
||||
float layer3_roughness = GetRoughnessInput(MaterialSrg::m_layer3_m_roughnessMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_roughnessMapUvIndex], MaterialSrg::m_layer3_m_roughnessFactor, MaterialSrg::m_layer3_m_roughnessLowerBound, MaterialSrg::m_layer3_m_roughnessUpperBound, o_layer3_o_roughness_useTexture);
|
||||
surface.roughnessLinear = BlendLayers(layer1_roughness, layer2_roughness, layer3_roughness, blendWeights);
|
||||
|
||||
surface.roughnessLinear = BlendLayers(lightingInputLayer1.m_roughness, lightingInputLayer2.m_roughness, lightingInputLayer3.m_roughness, blendWeights);
|
||||
surface.CalculateRoughnessA();
|
||||
|
||||
// ------- Subsurface -------
|
||||
|
||||
float2 subsurfaceUv = IN.m_uv[MaterialSrg::m_subsurfaceScatteringInfluenceMapUvIndex];
|
||||
float surfaceScatteringFactor = GetSubsurfaceInput(MaterialSrg::m_subsurfaceScatteringInfluenceMap, MaterialSrg::m_sampler, subsurfaceUv, MaterialSrg::m_subsurfaceScatteringFactor);
|
||||
|
||||
// ------- Transmission -------
|
||||
|
||||
float2 transmissionUv = IN.m_uv[MaterialSrg::m_transmissionThicknessMapUvIndex];
|
||||
float4 transmissionTintThickness = GeTransmissionInput(MaterialSrg::m_transmissionThicknessMap, MaterialSrg::m_sampler, transmissionUv, MaterialSrg::m_transmissionTintThickness);
|
||||
surface.transmission.tint = transmissionTintThickness.rgb;
|
||||
surface.transmission.thickness = transmissionTintThickness.w;
|
||||
surface.transmission.transmissionParams = MaterialSrg::m_transmissionParams;
|
||||
|
||||
// ------- Lighting Data -------
|
||||
|
||||
// ------- Init and Combine Lighting Data -------
|
||||
|
||||
LightingData lightingData;
|
||||
|
||||
// Light iterator
|
||||
@@ -307,88 +442,22 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
|
||||
// Directional light shadow coordinates
|
||||
lightingData.shadowCoords = IN.m_shadowCoords;
|
||||
|
||||
// ------- Emissive -------
|
||||
|
||||
float3 layer1_emissive = GetEmissiveInput(MaterialSrg::m_layer1_m_emissiveMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_emissiveMapUvIndex], MaterialSrg::m_layer1_m_emissiveIntensity, MaterialSrg::m_layer1_m_emissiveColor.rgb, o_layer1_o_emissiveEnabled, o_layer1_o_emissive_useTexture);
|
||||
float3 layer2_emissive = GetEmissiveInput(MaterialSrg::m_layer2_m_emissiveMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_emissiveMapUvIndex], MaterialSrg::m_layer2_m_emissiveIntensity, MaterialSrg::m_layer2_m_emissiveColor.rgb, o_layer2_o_emissiveEnabled, o_layer2_o_emissive_useTexture);
|
||||
float3 layer3_emissive = GetEmissiveInput(MaterialSrg::m_layer3_m_emissiveMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_emissiveMapUvIndex], MaterialSrg::m_layer3_m_emissiveIntensity, MaterialSrg::m_layer3_m_emissiveColor.rgb, o_layer3_o_emissiveEnabled, o_layer3_o_emissive_useTexture);
|
||||
lightingData.emissiveLighting = BlendLayers(layer1_emissive, layer2_emissive, layer3_emissive, blendWeights);
|
||||
lightingData.emissiveLighting = BlendLayers(lightingInputLayer1.m_emissiveLighting, lightingInputLayer2.m_emissiveLighting, lightingInputLayer3.m_emissiveLighting, blendWeights);
|
||||
lightingData.specularOcclusion = BlendLayers(lightingInputLayer1.m_specularOcclusion, lightingInputLayer2.m_specularOcclusion, lightingInputLayer3.m_specularOcclusion, blendWeights);
|
||||
lightingData.diffuseAmbientOcclusion = BlendLayers(lightingInputLayer1.m_diffuseAmbientOcclusion, lightingInputLayer2.m_diffuseAmbientOcclusion, lightingInputLayer3.m_diffuseAmbientOcclusion, blendWeights);
|
||||
|
||||
// ------- Occlusion -------
|
||||
|
||||
float layer1_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer1_m_diffuseOcclusionFactor, o_layer1_o_diffuseOcclusion_useTexture);
|
||||
float layer2_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer2_m_diffuseOcclusionFactor, o_layer2_o_diffuseOcclusion_useTexture);
|
||||
float layer3_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer3_m_diffuseOcclusionFactor, o_layer3_o_diffuseOcclusion_useTexture);
|
||||
lightingData.diffuseAmbientOcclusion = BlendLayers(layer1_diffuseAmbientOcclusion, layer2_diffuseAmbientOcclusion, layer3_diffuseAmbientOcclusion, blendWeights);
|
||||
lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation);
|
||||
|
||||
float layer1_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer1_m_specularOcclusionFactor, o_layer1_o_specularOcclusion_useTexture);
|
||||
float layer2_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer2_m_specularOcclusionFactor, o_layer2_o_specularOcclusion_useTexture);
|
||||
float layer3_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer3_m_specularOcclusionFactor, o_layer3_o_specularOcclusion_useTexture);
|
||||
lightingData.specularOcclusion = BlendLayers(layer1_specularOcclusion, layer2_specularOcclusion, layer3_specularOcclusion, blendWeights);
|
||||
|
||||
// ------- Clearcoat -------
|
||||
// ------- Combine Clearcoat -------
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
// --- Layer 1 ---
|
||||
|
||||
float layer1_clearCoatFactor = 0.0f;
|
||||
float layer1_clearCoatRoughness = 0.0f;
|
||||
float3 layer1_clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
if(o_layer1_o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 layer1_uvMatrix = MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_layer1_m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(MaterialSrg::m_layer1_m_clearCoatInfluenceMap, uvLayer1[MaterialSrg::m_layer1_m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_layer1_m_clearCoatFactor, o_layer1_o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_layer1_m_clearCoatRoughnessMap, uvLayer1[MaterialSrg::m_layer1_m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_layer1_m_clearCoatRoughness, o_layer1_o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_layer1_m_clearCoatNormalMap, uvLayer1[MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex], IN.m_normal, o_layer1_o_clearCoat_normal_useTexture, MaterialSrg::m_layer1_m_clearCoatNormalStrength,
|
||||
layer1_uvMatrix, tangents[MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
layer1_clearCoatFactor, layer1_clearCoatRoughness, layer1_clearCoatNormal);
|
||||
}
|
||||
|
||||
// --- Layer 2 ---
|
||||
|
||||
float layer2_clearCoatFactor = 0.0f;
|
||||
float layer2_clearCoatRoughness = 0.0f;
|
||||
float3 layer2_clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
if(o_layer2_o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 layer2_uvMatrix = MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_layer2_m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(MaterialSrg::m_layer2_m_clearCoatInfluenceMap, uvLayer2[MaterialSrg::m_layer2_m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_layer2_m_clearCoatFactor, o_layer2_o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_layer2_m_clearCoatRoughnessMap, uvLayer2[MaterialSrg::m_layer2_m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_layer2_m_clearCoatRoughness, o_layer2_o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_layer2_m_clearCoatNormalMap, uvLayer2[MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex], IN.m_normal, o_layer2_o_clearCoat_normal_useTexture, MaterialSrg::m_layer2_m_clearCoatNormalStrength,
|
||||
layer2_uvMatrix, tangents[MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
layer2_clearCoatFactor, layer2_clearCoatRoughness, layer2_clearCoatNormal);
|
||||
}
|
||||
|
||||
// --- Layer 3 ---
|
||||
|
||||
float layer3_clearCoatFactor = 0.0f;
|
||||
float layer3_clearCoatRoughness = 0.0f;
|
||||
float3 layer3_clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
if(o_layer3_o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 layer3_uvMatrix = MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_layer3_m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(MaterialSrg::m_layer3_m_clearCoatInfluenceMap, uvLayer3[MaterialSrg::m_layer3_m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_layer3_m_clearCoatFactor, o_layer3_o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_layer3_m_clearCoatRoughnessMap, uvLayer3[MaterialSrg::m_layer3_m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_layer3_m_clearCoatRoughness, o_layer3_o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_layer3_m_clearCoatNormalMap, uvLayer3[MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex], IN.m_normal, o_layer3_o_clearCoat_normal_useTexture, MaterialSrg::m_layer3_m_clearCoatNormalStrength,
|
||||
layer3_uvMatrix, tangents[MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
layer3_clearCoatFactor, layer3_clearCoatRoughness, layer3_clearCoatNormal);
|
||||
}
|
||||
|
||||
// --- Blend Layers ---
|
||||
|
||||
surface.clearCoat.factor = BlendLayers(layer1_clearCoatFactor, layer2_clearCoatFactor, layer3_clearCoatFactor, blendWeights);
|
||||
surface.clearCoat.roughness = BlendLayers(layer1_clearCoatRoughness, layer2_clearCoatRoughness, layer3_clearCoatRoughness, blendWeights);
|
||||
surface.clearCoat.factor = BlendLayers(lightingInputLayer1.m_clearCoat.factor, lightingInputLayer2.m_clearCoat.factor, lightingInputLayer3.m_clearCoat.factor, blendWeights);
|
||||
surface.clearCoat.roughness = BlendLayers(lightingInputLayer1.m_clearCoat.roughness, lightingInputLayer2.m_clearCoat.roughness, lightingInputLayer3.m_clearCoat.roughness, blendWeights);
|
||||
|
||||
// [GFX TODO][ATOM-14592] This is not the right way to blend the normals. We need to use ReorientTangentSpaceNormal(), and that requires GetClearCoatInputs() to return the normal in TS instead of WS.
|
||||
surface.clearCoat.normal = BlendLayers(layer1_clearCoatNormal, layer2_clearCoatNormal, layer3_clearCoatNormal, blendWeights);
|
||||
surface.clearCoat.normal = BlendLayers(lightingInputLayer1.m_clearCoat.normal, lightingInputLayer2.m_clearCoat.normal, lightingInputLayer3.m_clearCoat.normal, blendWeights);
|
||||
surface.clearCoat.normal = normalize(surface.clearCoat.normal);
|
||||
|
||||
// manipulate base layer f0 if clear coat is enabled
|
||||
@@ -408,11 +477,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
// Clear coat layer has fixed IOR = 1.5 and transparent => F0 = (1.5 - 1)^2 / (1.5 + 1)^2 = 0.04
|
||||
lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
// ------- Multiscatter -------
|
||||
|
||||
lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation);
|
||||
|
||||
|
||||
// ------- Lighting Calculation -------
|
||||
|
||||
// Apply Decals
|
||||
@@ -425,17 +490,14 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
ApplyIBL(surface, lightingData);
|
||||
|
||||
// Finalize Lighting
|
||||
lightingData.FinalizeLighting(surface.transmission.tint);
|
||||
lightingData.FinalizeLighting(0);
|
||||
|
||||
|
||||
const float alpha = 1.0;
|
||||
|
||||
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
|
||||
|
||||
// Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961
|
||||
uint factorAndQuality = dot(round(float2(saturate(surfaceScatteringFactor), MaterialSrg::m_subsurfaceScatteringQuality) * 255), float2(256, 1));
|
||||
lightingOutput.m_diffuseColor.w = factorAndQuality * (o_enableSubsurfaceScattering ? 1.0 : -1.0);
|
||||
|
||||
lightingOutput.m_diffuseColor.w = -1; // Disable subsurface scattering
|
||||
|
||||
return lightingOutput;
|
||||
}
|
||||
|
||||
+14
@@ -32,6 +32,8 @@ class Surface
|
||||
float roughnessA; //!< Actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations
|
||||
float roughnessA2; //!< Alpha roughness ^ 2 (i.e. roughnessA * roughnessA), used in GGX, cached here for perfromance
|
||||
|
||||
void InitializeToZero();
|
||||
|
||||
//! Applies specular anti-aliasing to roughnessA2
|
||||
void ApplySpecularAA();
|
||||
|
||||
@@ -43,6 +45,18 @@ class Surface
|
||||
|
||||
};
|
||||
|
||||
void Surface::InitializeToZero()
|
||||
{
|
||||
clearCoat.InitializeToZero();
|
||||
transmission.InitializeToZero();
|
||||
position = float3(0,0,0);
|
||||
normal = float3(0,0,0);
|
||||
albedo = float3(0,0,0);
|
||||
specularF0 = float3(0,0,0);
|
||||
roughnessLinear = 0.0f;
|
||||
roughnessA = 0.0f;
|
||||
roughnessA2 = 0.0f;
|
||||
}
|
||||
|
||||
// Specular Anti-Aliasing technique from this paper:
|
||||
// http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
|
||||
|
||||
Reference in New Issue
Block a user