Updated EnhancedPBR and touched up some includes
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Features/SrgSemantics.azsli>
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
|
||||
#include "MaterialInputs/BaseColorInput.azsli"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include "./EnhancedPBR_Common.azsli"
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
|
||||
@@ -10,11 +10,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <viewsrg.srgi>
|
||||
#include "EnhancedPBR_Common.azsli"
|
||||
|
||||
// SRGs
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/PBR/ForwardPassSrg.azsli>
|
||||
|
||||
// Pass Output
|
||||
#include <Atom/Features/PBR/ForwardPassOutput.azsli>
|
||||
|
||||
// Utility
|
||||
#include <Atom/Features/ColorManagement/TransformColor.azsli>
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
|
||||
// Custom Surface & Lighting
|
||||
#include <Atom/Features/PBR/Lighting/EnhancedLighting.azsli>
|
||||
|
||||
// Decals
|
||||
#include <Atom/Features/PBR/Decals.azsli>
|
||||
|
||||
|
||||
// ---------- Material Parameters ----------
|
||||
|
||||
@@ -39,6 +53,8 @@ COMMON_OPTIONS_DETAIL_MAPS()
|
||||
#include "MaterialInputs/TransmissionInput.azsli"
|
||||
|
||||
|
||||
// ---------- Vertex Shader ----------
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
// Base fields (required by the template azsli file)...
|
||||
@@ -67,8 +83,6 @@ struct VSOutput
|
||||
float2 m_detailUv[UvSetCount] : UV3;
|
||||
};
|
||||
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include <Atom/Features/PBR/LightingModel.azsli>
|
||||
#include <Atom/Features/Vertex/VertexHelper.azsli>
|
||||
|
||||
VSOutput EnhancedPbr_ForwardPassVS(VSInput IN)
|
||||
@@ -94,6 +108,9 @@ VSOutput EnhancedPbr_ForwardPassVS(VSInput IN)
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Pixel Shader ----------
|
||||
|
||||
PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth)
|
||||
{
|
||||
// ------- Tangents & Bitangets -------
|
||||
@@ -144,6 +161,9 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
}
|
||||
}
|
||||
|
||||
Surface surface;
|
||||
surface.position = IN.m_worldPosition;
|
||||
|
||||
// ------- Alpha & Clip -------
|
||||
|
||||
float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex];
|
||||
@@ -172,7 +192,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms.
|
||||
float detailLayerNormalFactor = MaterialSrg::m_detail_normal_factor * detailLayerBlendFactor;
|
||||
|
||||
float3 normal = GetDetailedNormalInputWS(
|
||||
surface.normal = GetDetailedNormalInputWS(
|
||||
isFrontFace, IN.m_normal,
|
||||
tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_normalFactor, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, uvMatrix, o_normal_useTexture,
|
||||
tangents[MaterialSrg::m_detail_allMapsUvIndex], bitangents[MaterialSrg::m_detail_allMapsUvIndex], MaterialSrg::m_detail_normal_texture, MaterialSrg::m_sampler, detailUv, detailLayerNormalFactor, MaterialSrg::m_detail_normal_flipX, MaterialSrg::m_detail_normal_flipY, MaterialSrg::m_detailUvMatrix, o_detail_normal_useTexture);
|
||||
@@ -196,26 +216,20 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_useTexture);
|
||||
}
|
||||
|
||||
// ------- Roughness -------
|
||||
|
||||
float2 roughnessUv = IN.m_uv[MaterialSrg::m_roughnessMapUvIndex];
|
||||
float roughness = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor,
|
||||
MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture);
|
||||
|
||||
// ------- Specular -------
|
||||
|
||||
float2 specularUv = IN.m_uv[MaterialSrg::m_specularF0MapUvIndex];
|
||||
float specularF0Factor = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture);
|
||||
float specularF0 = GetSpecularInput(MaterialSrg::m_specularF0Map, MaterialSrg::m_sampler, specularUv, MaterialSrg::m_specularF0Factor, o_specularF0_useTexture);
|
||||
|
||||
// ------- Emissive -------
|
||||
surface.SetAlbedoAndSpecularF0(baseColor, specularF0, metallic);
|
||||
|
||||
float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex];
|
||||
float3 emissive = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture);
|
||||
// ------- Roughness -------
|
||||
|
||||
// ------- Occlusion -------
|
||||
float2 roughnessUv = IN.m_uv[MaterialSrg::m_roughnessMapUvIndex];
|
||||
surface.roughnessLinear = GetRoughnessInput(MaterialSrg::m_roughnessMap, MaterialSrg::m_sampler, roughnessUv, MaterialSrg::m_roughnessFactor,
|
||||
MaterialSrg::m_roughnessLowerBound, MaterialSrg::m_roughnessUpperBound, o_roughness_useTexture);
|
||||
|
||||
float2 occlusionUv = IN.m_uv[MaterialSrg::m_ambientOcclusionMapUvIndex];
|
||||
float occlusion = GetOcclusionInput(MaterialSrg::m_ambientOcclusionMap, MaterialSrg::m_sampler, occlusionUv, MaterialSrg::m_ambientOcclusionFactor, o_ambientOcclusion_useTexture);
|
||||
surface.CalculateRoughnessA();
|
||||
|
||||
// ------- Subsurface -------
|
||||
|
||||
@@ -226,33 +240,100 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
|
||||
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;
|
||||
|
||||
// ------- Anisotropy -------
|
||||
|
||||
if (o_enableAnisotropy)
|
||||
{
|
||||
// Convert the angle from [0..1] = [0 .. 180 degrees] to radians [0 .. PI]
|
||||
const float anisotropyAngle = MaterialSrg::m_anisotropicAngle * PI;
|
||||
const float anisotropyFactor = MaterialSrg::m_anisotropicFactor;
|
||||
surface.anisotropy.Init(surface.normal, tangents[0], bitangents[0], anisotropyAngle, anisotropyFactor, surface.roughnessA);
|
||||
}
|
||||
|
||||
// ------- Lighting Data -------
|
||||
|
||||
LightingData lightingData;
|
||||
|
||||
// Light iterator
|
||||
lightingData.tileIterator.Init(IN.m_position, PassSrg::m_lightListRemapped, PassSrg::m_tileLightData);
|
||||
lightingData.Init(surface.position, surface.normal, surface.roughnessLinear);
|
||||
|
||||
// Directional light shadow coordinates
|
||||
lightingData.shadowCoords = IN.m_shadowCoords;
|
||||
|
||||
|
||||
// ------- Emissive -------
|
||||
|
||||
float2 emissiveUv = IN.m_uv[MaterialSrg::m_emissiveMapUvIndex];
|
||||
lightingData.emissiveLighting = GetEmissiveInput(MaterialSrg::m_emissiveMap, MaterialSrg::m_sampler, emissiveUv, MaterialSrg::m_emissiveIntensity, MaterialSrg::m_emissiveColor.rgb, o_emissiveEnabled, o_emissive_useTexture);
|
||||
|
||||
// ------- Occlusion -------
|
||||
|
||||
float2 occlusionUv = IN.m_uv[MaterialSrg::m_ambientOcclusionMapUvIndex];
|
||||
lightingData.occlusion = GetOcclusionInput(MaterialSrg::m_ambientOcclusionMap, MaterialSrg::m_sampler, occlusionUv, MaterialSrg::m_ambientOcclusionFactor, o_ambientOcclusion_useTexture);
|
||||
|
||||
// ------- Clearcoat -------
|
||||
|
||||
float clearCoatFactor = 0.0;
|
||||
float clearCoatRoughness = 0.0;
|
||||
float3 clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
// TODO: Clean up the double uses of these clear coat flags
|
||||
if(o_clearCoat_enabled && o_clearCoat_feature_enabled)
|
||||
// [GFX TODO][ATOM-14603]: Clean up the double uses of these clear coat flags
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, IN.m_uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_clearCoatRoughnessMap, IN.m_uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_clearCoatNormalMap, IN.m_uv[MaterialSrg::m_clearCoatNormalMapUvIndex], IN.m_normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength,
|
||||
uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
clearCoatFactor, clearCoatRoughness, clearCoatNormal);
|
||||
if(o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 uvMatrix = MaterialSrg::m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
GetClearCoatInputs(MaterialSrg::m_clearCoatInfluenceMap, IN.m_uv[MaterialSrg::m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_clearCoatFactor, o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_clearCoatRoughnessMap, IN.m_uv[MaterialSrg::m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_clearCoatRoughness, o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_clearCoatNormalMap, IN.m_uv[MaterialSrg::m_clearCoatNormalMapUvIndex], IN.m_normal, o_clearCoat_normal_useTexture, MaterialSrg::m_clearCoatNormalStrength,
|
||||
uvMatrix, tangents[MaterialSrg::m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
surface.clearCoat.factor, surface.clearCoat.roughness, surface.clearCoat.normal);
|
||||
}
|
||||
|
||||
// manipulate base layer f0 if clear coat is enabled
|
||||
// modify base layer's normal incidence reflectance
|
||||
// for the derivation of the following equation please refer to:
|
||||
// https://google.github.io/filament/Filament.md.html#materialsystem/clearcoatmodel/baselayermodification
|
||||
float3 f0 = (1.0 - 5.0 * sqrt(surface.specularF0)) / (5.0 - sqrt(surface.specularF0));
|
||||
surface.specularF0 = lerp(surface.specularF0, f0 * f0, surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
// Diffuse and Specular response (used in IBL calculations)
|
||||
lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear);
|
||||
lightingData.diffuseResponse = 1.0 - lightingData.specularResponse;
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
// 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 -------
|
||||
|
||||
// Convert the angle from [0..1] = [0 .. 180 degrees] to radians [0 .. PI]
|
||||
const float2 anisotropy = float2(MaterialSrg::m_anisotropicAngle * PI, MaterialSrg::m_anisotropicFactor);
|
||||
// Apply Decals
|
||||
ApplyDecals(lightingData.tileIterator, surface);
|
||||
|
||||
PbrLightingOutput lightingOutput = PbrLighting(IN,
|
||||
baseColor, metallic, roughness, specularF0Factor,
|
||||
normal, IN.m_tangent, IN.m_bitangent, anisotropy,
|
||||
emissive, occlusion, transmissionTintThickness, MaterialSrg::m_transmissionParams, clearCoatFactor, clearCoatRoughness, clearCoatNormal, alpha, o_opacity_mode);
|
||||
// Apply Direct Lighting
|
||||
ApplyDirectLighting(surface, lightingData);
|
||||
|
||||
// Apply Image Based Lighting (IBL)
|
||||
ApplyIBL(surface, lightingData);
|
||||
|
||||
// Finalize Lighting
|
||||
lightingData.FinalizeLighting(surface.transmission.tint);
|
||||
|
||||
if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent)
|
||||
{
|
||||
alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
|
||||
}
|
||||
|
||||
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
|
||||
|
||||
// ------- Opacity -------
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
#include <scenesrg.srgi>
|
||||
#include <viewsrg.srgi>
|
||||
#include "EnhancedPBR_Common.azsli"
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <viewsrg.srgi>
|
||||
#include "Skin_Common.azsli"
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/PBR/ForwardPassSrg.azsli>
|
||||
#include <Atom/Features/PBR/ForwardPassOutput.azsli>
|
||||
#include <Atom/Features/ColorManagement/TransformColor.azsli>
|
||||
|
||||
|
||||
+19
-1
@@ -10,10 +10,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// SRGs
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/PBR/ForwardPassSrg.azsli>
|
||||
|
||||
// Pass Output
|
||||
#include <Atom/Features/PBR/ForwardPassOutput.azsli>
|
||||
|
||||
// Utility
|
||||
#include <Atom/Features/ColorManagement/TransformColor.azsli>
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
|
||||
// Custom Surface & Lighting
|
||||
#include <Atom/Features/PBR/Lighting/StandardLighting.azsli>
|
||||
|
||||
// Decals
|
||||
#include <Atom/Features/PBR/Decals.azsli>
|
||||
|
||||
// ---------- Material Parameters ----------
|
||||
|
||||
@@ -47,6 +60,9 @@ DEFINE_LAYER_OPTIONS(o_layer3_)
|
||||
#include "MaterialInputs/TransmissionInput.azsli"
|
||||
#include "StandardMultilayerPBR_Common.azsli"
|
||||
|
||||
|
||||
// ---------- Vertex Shader ----------
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
// Base fields (required by the template azsli file)...
|
||||
@@ -83,7 +99,6 @@ struct VSOutput
|
||||
float3 m_blendMask : UV7;
|
||||
};
|
||||
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include <Atom/Features/PBR/LightingModel.azsli>
|
||||
#include <Atom/Features/Vertex/VertexHelper.azsli>
|
||||
|
||||
@@ -115,6 +130,9 @@ VSOutput ForwardPassVS(VSInput IN)
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Pixel Shader ----------
|
||||
|
||||
PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth)
|
||||
{
|
||||
depth = IN.m_position.z;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Features/SrgSemantics.azsli>
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
|
||||
#include "MaterialInputs/BaseColorInput.azsli"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include "./StandardPBR_Common.azsli"
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
|
||||
@@ -10,11 +10,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <viewsrg.srgi>
|
||||
#include "StandardPBR_Common.azsli"
|
||||
|
||||
// SRGs
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/PBR/ForwardPassSrg.azsli>
|
||||
|
||||
// Pass Output
|
||||
#include <Atom/Features/PBR/ForwardPassOutput.azsli>
|
||||
|
||||
// Utility
|
||||
#include <Atom/Features/ColorManagement/TransformColor.azsli>
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
|
||||
// Custom Surface & Lighting
|
||||
#include <Atom/Features/PBR/Lighting/StandardLighting.azsli>
|
||||
|
||||
// Decals
|
||||
#include <Atom/Features/PBR/Decals.azsli>
|
||||
|
||||
|
||||
// ---------- Material Parameters ----------
|
||||
|
||||
@@ -38,6 +52,8 @@ COMMON_OPTIONS_PARALLAX()
|
||||
#include "MaterialInputs/TransmissionInput.azsli"
|
||||
|
||||
|
||||
// ---------- Vertex Shader ----------
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
// Base fields (required by the template azsli file)...
|
||||
@@ -66,8 +82,6 @@ struct VSOutput
|
||||
float2 m_uv[UvSetCount] : UV1;
|
||||
};
|
||||
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include <Atom/Features/PBR/LightingModel.azsli>
|
||||
#include <Atom/Features/Vertex/VertexHelper.azsli>
|
||||
|
||||
VSOutput StandardPbr_ForwardPassVS(VSInput IN)
|
||||
@@ -85,6 +99,9 @@ VSOutput StandardPbr_ForwardPassVS(VSInput IN)
|
||||
return OUT;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Pixel Shader ----------
|
||||
|
||||
PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depth)
|
||||
{
|
||||
// ------- Tangents & Bitangets -------
|
||||
@@ -112,7 +129,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
{
|
||||
float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3();
|
||||
GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_depthFactor,
|
||||
GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], MaterialSrg::m_depthFactor,
|
||||
ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse,
|
||||
IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth);
|
||||
|
||||
@@ -130,7 +147,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
Surface surface;
|
||||
surface.position = IN.m_worldPosition.xyz;
|
||||
|
||||
|
||||
// ------- Alpha & Clip -------
|
||||
|
||||
float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex];
|
||||
@@ -250,9 +266,9 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
|
||||
lightingData.diffuseResponse *= 1.0 - (FresnelSchlickWithRoughness(lightingData.NdotV, float3(0.04, 0.04, 0.04), surface.clearCoat.roughness) * surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
// Multiscatter compensation factor
|
||||
lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation);
|
||||
// ------- Multiscatter -------
|
||||
|
||||
lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation);
|
||||
|
||||
// ------- Lighting Calculation -------
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
#include <scenesrg.srgi>
|
||||
#include <viewsrg.srgi>
|
||||
#include "StandardPBR_Common.azsli"
|
||||
#include <Atom/Features/PBR/AlphaUtils.azsli>
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// NOTE: The following must be included or defined before including this file:
|
||||
// - Surface - LightingData
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
#include <Atom/Features/PBR/LightingOptions.azsli>
|
||||
#include <Atom/Features/PBR/Surface.azsli>
|
||||
|
||||
// Analytical integation (approximation) of diffusion profile over radius, could be replaced by other pre integrated kernels
|
||||
// such as sum of Gaussian
|
||||
|
||||
@@ -12,23 +12,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// NOTE: The following must be included or defined before including this file:
|
||||
// - Surface
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
#include <Atom/Features/MatrixUtility.azsli>
|
||||
#include <Atom/Features/Decals/DecalTextureUtil.azsli>
|
||||
#include <Atom/Features/LightCulling/LightCullingTileIterator.azsli>
|
||||
#include <Atom/Features/PBR/Surface.azsli>
|
||||
|
||||
void ApplyDecal(uint currDecalIndex, inout Surface surface);
|
||||
|
||||
void ApplyDecals(inout LightCullingTileIterator tileIterator, inout Surface surface)
|
||||
{
|
||||
tileIterator.LoadAdvance();
|
||||
|
||||
while( !tileIterator.IsDone() )
|
||||
{
|
||||
uint currDecalIndex = tileIterator.GetValue();
|
||||
|
||||
while( !tileIterator.IsDone() )
|
||||
{
|
||||
uint currDecalIndex = tileIterator.GetValue();
|
||||
tileIterator.LoadAdvance();
|
||||
|
||||
ApplyDecal(currDecalIndex, surface);
|
||||
ApplyDecal(currDecalIndex, surface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +48,13 @@ float GetDecalAttenuation(float3 surfNormal, float3 decalUp, float decalAngleAtt
|
||||
|
||||
void ApplyDecal(uint currDecalIndex, inout Surface surface)
|
||||
{
|
||||
ViewSrg::Decal decal = ViewSrg::m_decals[currDecalIndex];
|
||||
ViewSrg::Decal decal = ViewSrg::m_decals[currDecalIndex];
|
||||
|
||||
float3x3 decalRot = MatrixFromQuaternion(decal.m_quaternion);
|
||||
|
||||
float3 localPos = surface.position - decal.m_position;
|
||||
float3 localPos = surface.position - decal.m_position;
|
||||
localPos = mul(localPos, decalRot);
|
||||
|
||||
|
||||
float3 decalUVW = localPos * rcp(decal.m_halfSize);
|
||||
if(decalUVW.x >= -1.0f && decalUVW.x <= 1.0f &&
|
||||
decalUVW.y >= -1.0f && decalUVW.y <= 1.0f &&
|
||||
@@ -70,25 +74,23 @@ void ApplyDecal(uint currDecalIndex, inout Surface surface)
|
||||
switch(textureArrayIndex)
|
||||
{
|
||||
case 0:
|
||||
baseMap = ViewSrg::m_decalTextureArray0.Sample(PassSrg::LinearSampler, decalUV);
|
||||
baseMap = ViewSrg::m_decalTextureArray0.Sample(PassSrg::LinearSampler, decalUV);
|
||||
break;
|
||||
case 1:
|
||||
baseMap = ViewSrg::m_decalTextureArray1.Sample(PassSrg::LinearSampler, decalUV);
|
||||
baseMap = ViewSrg::m_decalTextureArray1.Sample(PassSrg::LinearSampler, decalUV);
|
||||
break;
|
||||
case 2:
|
||||
baseMap = ViewSrg::m_decalTextureArray2.Sample(PassSrg::LinearSampler, decalUV);
|
||||
baseMap = ViewSrg::m_decalTextureArray2.Sample(PassSrg::LinearSampler, decalUV);
|
||||
break;
|
||||
case 3:
|
||||
baseMap = ViewSrg::m_decalTextureArray3.Sample(PassSrg::LinearSampler, decalUV);
|
||||
baseMap = ViewSrg::m_decalTextureArray3.Sample(PassSrg::LinearSampler, decalUV);
|
||||
break;
|
||||
case 4:
|
||||
baseMap = ViewSrg::m_decalTextureArray4.Sample(PassSrg::LinearSampler, decalUV);
|
||||
baseMap = ViewSrg::m_decalTextureArray4.Sample(PassSrg::LinearSampler, decalUV);
|
||||
break;
|
||||
}
|
||||
|
||||
float opacity = baseMap.a * decal.m_opacity * GetDecalAttenuation(surface.normal, decalRot[2], decal.m_angleAttenuation);
|
||||
surface.albedo = lerp(surface.albedo, baseMap.rgb, opacity);
|
||||
}
|
||||
float opacity = baseMap.a * decal.m_opacity * GetDecalAttenuation(surface.normal, decalRot[2], decal.m_angleAttenuation);
|
||||
surface.albedo = lerp(surface.albedo, baseMap.rgb, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Include options first
|
||||
#include <Atom/Features/PBR/LightingOptions.azsli>
|
||||
|
||||
// Then include custom surface and lighting data types
|
||||
#include <Atom/Features/PBR/Lighting/LightingData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/StandardSurface.azsli>
|
||||
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/Features/PBR/Microfacet/Brdf.azsli>
|
||||
|
||||
// Then define the Diffuse and Specular lighting functions
|
||||
float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight)
|
||||
{
|
||||
float3 diffuse;
|
||||
if(o_enableSubsurfaceScattering)
|
||||
{
|
||||
// Use diffuse brdf contains double Fresnel (enter/exit surface) terms if subsurface scattering is enabled
|
||||
diffuse = NormalizedDisneyDiffuse(surface.albedo, surface.normal, lightingData.dirToCamera, dirToLight, surface.roughnessLinear);
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
// Attenuate diffuse term by clear coat's fresnel term to account for energy loss
|
||||
float HdotV = saturate(dot(normalize(dirToLight + lightingData.dirToCamera), lightingData.dirToCamera));
|
||||
diffuse *= 1.0 - (FresnelSchlick(HdotV, 0.04) * surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
diffuse *= lightIntensity;
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
float3 GetSpecularLighting(Surface surface, LightingData lightingData, const float3 lightIntensity, const float3 dirToLight)
|
||||
{
|
||||
float3 specular;
|
||||
if (o_enableAnisotropy)
|
||||
{
|
||||
specular = AnisotropicGGX( lightingData.dirToCamera, dirToLight, surface.normal, surface.anisotropy.tangent, surface.anisotropy.bitangent, surface.anisotropy.anisotropyFactors,
|
||||
surface.specularF0, lightingData.NdotV, lightingData.multiScatterCompensation );
|
||||
}
|
||||
else
|
||||
{
|
||||
specular = SpecularGGX(lightingData.dirToCamera, dirToLight, surface.normal, surface.specularF0, lightingData.NdotV, surface.roughnessA2, lightingData.multiScatterCompensation);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
float3 halfVector = normalize(dirToLight + lightingData.dirToCamera);
|
||||
float NdotH = saturate(dot(surface.clearCoat.normal, halfVector));
|
||||
float NdotL = saturate(dot(surface.clearCoat.normal, dirToLight));
|
||||
float HdotL = saturate(dot(halfVector, dirToLight));
|
||||
|
||||
// HdotV = HdotL due to the definition of half vector
|
||||
float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoat.factor;
|
||||
float clearCoatRoughness = max(surface.clearCoat.roughness * surface.clearCoat.roughness, 0.0005f);
|
||||
float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF );
|
||||
|
||||
specular = specular * (1.0 - clearCoatF) * (1.0 - clearCoatF) + clearCoatSpecular;
|
||||
}
|
||||
|
||||
specular *= lightIntensity;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
|
||||
// Then include everything else
|
||||
#include <Atom/Features/PBR/Lights/Lights.azsli>
|
||||
#include <Atom/Features/PBR/Lights/Ibl.azsli>
|
||||
|
||||
|
||||
struct PbrLightingOutput
|
||||
{
|
||||
float4 m_diffuseColor;
|
||||
float4 m_specularColor;
|
||||
float4 m_albedo;
|
||||
float4 m_specularF0;
|
||||
float4 m_normal;
|
||||
float4 m_clearCoatNormal;
|
||||
float3 m_scatterDistance;
|
||||
};
|
||||
|
||||
|
||||
PbrLightingOutput GetPbrLightingOutput(Surface surface, LightingData lightingData, float alpha)
|
||||
{
|
||||
PbrLightingOutput lightingOutput;
|
||||
|
||||
lightingOutput.m_diffuseColor = float4(lightingData.diffuseLighting, alpha);
|
||||
lightingOutput.m_specularColor = float4(lightingData.specularLighting, 1.0);
|
||||
|
||||
// albedo, specularF0, roughness, and normals for later passes (specular IBL, Diffuse GI, SSR, AO, etc)
|
||||
lightingOutput.m_specularF0 = float4(surface.specularF0, surface.roughnessLinear);
|
||||
lightingOutput.m_albedo.rgb = surface.albedo * lightingData.diffuseResponse;
|
||||
lightingOutput.m_albedo.a = lightingData.occlusion;
|
||||
lightingOutput.m_normal.rgb = EncodeNormalSignedOctahedron(surface.normal);
|
||||
lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f;
|
||||
|
||||
// layout: (packedNormal.x, packedNormal.y, strength factor, clear coat roughness (not base material's roughness))
|
||||
lightingOutput.m_clearCoatNormal = float4(EncodeNormalSphereMap(surface.clearCoat.normal), o_clearCoat_feature_enabled ? surface.clearCoat.factor : 0.0, surface.clearCoat.roughness);
|
||||
|
||||
return lightingOutput;
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Include options first
|
||||
#include <Atom/Features/PBR/LightingOptions.azsli>
|
||||
|
||||
// Then include custom surface and lighting data types
|
||||
#include <Atom/Features/PBR/Lighting/LightingData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/StandardSurface.azsli>
|
||||
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/Features/PBR/Microfacet/Brdf.azsli>
|
||||
|
||||
// Then define the Diffuse and Specular lighting functions
|
||||
float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight)
|
||||
{
|
||||
float3 diffuse;
|
||||
if(o_enableSubsurfaceScattering)
|
||||
{
|
||||
// Use diffuse brdf contains double Fresnel (enter/exit surface) terms if subsurface scattering is enabled
|
||||
diffuse = NormalizedDisneyDiffuse(surface.albedo, surface.normal, lightingData.dirToCamera, dirToLight, surface.roughnessLinear);
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
// Attenuate diffuse term by clear coat's fresnel term to account for energy loss
|
||||
float HdotV = saturate(dot(normalize(dirToLight + lightingData.dirToCamera), lightingData.dirToCamera));
|
||||
diffuse *= 1.0 - (FresnelSchlick(HdotV, 0.04) * surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
diffuse *= lightIntensity;
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
float3 GetSpecularLighting(Surface surface, LightingData lightingData, const float3 lightIntensity, const float3 dirToLight)
|
||||
{
|
||||
float3 specular;
|
||||
if (o_enableAnisotropy)
|
||||
{
|
||||
specular = AnisotropicGGX( lightingData.dirToCamera, dirToLight, surface.normal, surface.anisotropy.tangent, surface.anisotropy.bitangent, surface.anisotropy.anisotropyFactors,
|
||||
surface.specularF0, lightingData.NdotV, lightingData.multiScatterCompensation );
|
||||
}
|
||||
else
|
||||
{
|
||||
specular = SpecularGGX(lightingData.dirToCamera, dirToLight, surface.normal, surface.specularF0, lightingData.NdotV, surface.roughnessA2, lightingData.multiScatterCompensation);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
float3 halfVector = normalize(dirToLight + lightingData.dirToCamera);
|
||||
float NdotH = saturate(dot(surface.clearCoat.normal, halfVector));
|
||||
float NdotL = saturate(dot(surface.clearCoat.normal, dirToLight));
|
||||
float HdotL = saturate(dot(halfVector, dirToLight));
|
||||
|
||||
// HdotV = HdotL due to the definition of half vector
|
||||
float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoat.factor;
|
||||
float clearCoatRoughness = max(surface.clearCoat.roughness * surface.clearCoat.roughness, 0.0005f);
|
||||
float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF );
|
||||
|
||||
specular = specular * (1.0 - clearCoatF) * (1.0 - clearCoatF) + clearCoatSpecular;
|
||||
}
|
||||
|
||||
specular *= lightIntensity;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
|
||||
// Then include everything else
|
||||
#include <Atom/Features/PBR/Lights/Lights.azsli>
|
||||
#include <Atom/Features/PBR/Lights/Ibl.azsli>
|
||||
|
||||
|
||||
struct PbrLightingOutput
|
||||
{
|
||||
float4 m_diffuseColor;
|
||||
float4 m_specularColor;
|
||||
float4 m_albedo;
|
||||
float4 m_specularF0;
|
||||
float4 m_normal;
|
||||
float4 m_clearCoatNormal;
|
||||
float3 m_scatterDistance;
|
||||
};
|
||||
|
||||
|
||||
PbrLightingOutput GetPbrLightingOutput(Surface surface, LightingData lightingData, float alpha)
|
||||
{
|
||||
PbrLightingOutput lightingOutput;
|
||||
|
||||
lightingOutput.m_diffuseColor = float4(lightingData.diffuseLighting, alpha);
|
||||
lightingOutput.m_specularColor = float4(lightingData.specularLighting, 1.0);
|
||||
|
||||
// albedo, specularF0, roughness, and normals for later passes (specular IBL, Diffuse GI, SSR, AO, etc)
|
||||
lightingOutput.m_specularF0 = float4(surface.specularF0, surface.roughnessLinear);
|
||||
lightingOutput.m_albedo.rgb = surface.albedo * lightingData.diffuseResponse;
|
||||
lightingOutput.m_albedo.a = lightingData.occlusion;
|
||||
lightingOutput.m_normal.rgb = EncodeNormalSignedOctahedron(surface.normal);
|
||||
lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f;
|
||||
|
||||
// layout: (packedNormal.x, packedNormal.y, strength factor, clear coat roughness (not base material's roughness))
|
||||
lightingOutput.m_clearCoatNormal = float4(EncodeNormalSphereMap(surface.clearCoat.normal), o_clearCoat_feature_enabled ? surface.clearCoat.factor : 0.0, surface.clearCoat.roughness);
|
||||
|
||||
return lightingOutput;
|
||||
}
|
||||
+62
-6
@@ -19,6 +19,68 @@
|
||||
#include <Atom/Features/PBR/Lighting/LightingData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/StandardSurface.azsli>
|
||||
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/Features/PBR/Microfacet/Brdf.azsli>
|
||||
|
||||
// Then define the Diffuse and Specular lighting functions
|
||||
float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight)
|
||||
{
|
||||
float3 diffuse;
|
||||
if(o_enableSubsurfaceScattering)
|
||||
{
|
||||
// Use diffuse brdf contains double Fresnel (enter/exit surface) terms if subsurface scattering is enabled
|
||||
diffuse = NormalizedDisneyDiffuse(surface.albedo, surface.normal, lightingData.dirToCamera, dirToLight, surface.roughnessLinear);
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
// Attenuate diffuse term by clear coat's fresnel term to account for energy loss
|
||||
float HdotV = saturate(dot(normalize(dirToLight + lightingData.dirToCamera), lightingData.dirToCamera));
|
||||
diffuse *= 1.0 - (FresnelSchlick(HdotV, 0.04) * surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
diffuse *= lightIntensity;
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
float3 GetSpecularLighting(Surface surface, LightingData lightingData, const float3 lightIntensity, const float3 dirToLight)
|
||||
{
|
||||
float3 specular;
|
||||
if (o_enableAnisotropy)
|
||||
{
|
||||
specular = AnisotropicGGX( lightingData.dirToCamera, dirToLight, surface.normal, surface.anisotropy.tangent, surface.anisotropy.bitangent, surface.anisotropy.anisotropyFactors,
|
||||
surface.specularF0, lightingData.NdotV, lightingData.multiScatterCompensation );
|
||||
}
|
||||
else
|
||||
{
|
||||
specular = SpecularGGX(lightingData.dirToCamera, dirToLight, surface.normal, surface.specularF0, lightingData.NdotV, surface.roughnessA2, lightingData.multiScatterCompensation);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
float3 halfVector = normalize(dirToLight + lightingData.dirToCamera);
|
||||
float NdotH = saturate(dot(surface.clearCoat.normal, halfVector));
|
||||
float NdotL = saturate(dot(surface.clearCoat.normal, dirToLight));
|
||||
float HdotL = saturate(dot(halfVector, dirToLight));
|
||||
|
||||
// HdotV = HdotL due to the definition of half vector
|
||||
float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoat.factor;
|
||||
float clearCoatRoughness = max(surface.clearCoat.roughness * surface.clearCoat.roughness, 0.0005f);
|
||||
float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF );
|
||||
|
||||
specular = specular * (1.0 - clearCoatF) * (1.0 - clearCoatF) + clearCoatSpecular;
|
||||
}
|
||||
|
||||
specular *= lightIntensity;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
|
||||
// Then include everything else
|
||||
#include <Atom/Features/PBR/Lights/Lights.azsli>
|
||||
#include <Atom/Features/PBR/Lights/Ibl.azsli>
|
||||
@@ -55,9 +117,3 @@ PbrLightingOutput GetPbrLightingOutput(Surface surface, LightingData lightingDat
|
||||
|
||||
return lightingOutput;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,30 +28,6 @@
|
||||
#include <Atom/Features/PBR/Lighting/StandardLighting.azsli>
|
||||
#include <Atom/Features/PBR/Decals.azsli>
|
||||
|
||||
// VSInput, VSOutput, ObjectSrg must be defined before including this file.
|
||||
|
||||
// DEPRECATED: Please use the VertexHelper(...) function in VertexHelper.azsli instead.
|
||||
//! @param skipShadowCoords can be useful for example when PixelDepthOffset is enable, because the pixel shader will have to run before the final world position is known
|
||||
void PbrVsHelper(in VSInput IN, inout VSOutput OUT, float3 worldPosition, bool skipShadowCoords = false)
|
||||
{
|
||||
OUT.m_worldPosition = worldPosition;
|
||||
OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(OUT.m_worldPosition, 1.0));
|
||||
|
||||
float4x4 objectToWorld = ObjectSrg::GetWorldMatrix();
|
||||
float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose();
|
||||
|
||||
ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent);
|
||||
|
||||
// directional light shadow
|
||||
const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight;
|
||||
if (o_enableShadows && !skipShadowCoords && shadowIndex < SceneSrg::m_directionalLightCount)
|
||||
{
|
||||
DirectionalLightShadow::GetShadowCoords(
|
||||
shadowIndex,
|
||||
worldPosition,
|
||||
OUT.m_shadowCoords);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DEPRECATED: Please use the functions in StandardLighting.azsli instead.
|
||||
|
||||
-62
@@ -16,71 +16,9 @@
|
||||
|
||||
#include <Atom/Features/PBR/BackLighting.azsli>
|
||||
#include <Atom/Features/PBR/Hammersley.azsli>
|
||||
#include <Atom/Features/PBR/LightingUtils.azsli>
|
||||
#include <Atom/Features/PBR/Surface.azsli>
|
||||
#include <Atom/Features/PBR/Microfacet/Brdf.azsli>
|
||||
|
||||
option bool o_area_light_validation = false;
|
||||
|
||||
float3 GetDiffuseLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight)
|
||||
{
|
||||
float3 diffuse;
|
||||
if(o_enableSubsurfaceScattering)
|
||||
{
|
||||
// Use diffuse brdf contains double Fresnel (enter/exit surface) terms if subsurface scattering is enabled
|
||||
diffuse = NormalizedDisneyDiffuse(surface.albedo, surface.normal, lightingData.dirToCamera, dirToLight, surface.roughnessLinear);
|
||||
}
|
||||
else
|
||||
{
|
||||
diffuse = DiffuseLambertian(surface.albedo, surface.normal, dirToLight);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
// Attenuate diffuse term by clear coat's fresnel term to account for energy loss
|
||||
float HdotV = saturate(dot(normalize(dirToLight + lightingData.dirToCamera), lightingData.dirToCamera));
|
||||
diffuse *= 1.0 - (FresnelSchlick(HdotV, 0.04) * surface.clearCoat.factor);
|
||||
}
|
||||
|
||||
diffuse *= lightIntensity;
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
float3 GetSpecularLighting(Surface surface, LightingData lightingData, const float3 lightIntensity, const float3 dirToLight)
|
||||
{
|
||||
float3 specular;
|
||||
if (o_enableAnisotropy)
|
||||
{
|
||||
//AnisotropicGGX( float3 dirToCamera, float3 dirToLight, float3 normal, float3 tangent, float3 bitangent, float2 anisotropyFactors,
|
||||
// float3 specularF0, float NdotV, float multiScatterCompensation )
|
||||
|
||||
specular = AnisotropicGGX( lightingData.dirToCamera, dirToLight, surface.normal, surface.anisotropy.tangent, surface.anisotropy.bitangent, surface.anisotropy.anisotropyFactors,
|
||||
surface.specularF0, lightingData.NdotV, lightingData.multiScatterCompensation );
|
||||
}
|
||||
else
|
||||
{
|
||||
specular = SpecularGGX(lightingData.dirToCamera, dirToLight, surface.normal, surface.specularF0, lightingData.NdotV, surface.roughnessA2, lightingData.multiScatterCompensation);
|
||||
}
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
float3 halfVector = normalize(dirToLight + lightingData.dirToCamera);
|
||||
float NdotH = saturate(dot(surface.clearCoat.normal, halfVector));
|
||||
float NdotL = saturate(dot(surface.clearCoat.normal, dirToLight));
|
||||
float HdotL = saturate(dot(halfVector, dirToLight));
|
||||
|
||||
// HdotV = HdotL due to the definition of half vector
|
||||
float3 clearCoatF = FresnelSchlick(HdotL, 0.04) * surface.clearCoat.factor;
|
||||
float clearCoatRoughness = max(surface.clearCoat.roughness * surface.clearCoat.roughness, 0.0005f);
|
||||
float3 clearCoatSpecular = ClearCoatGGX(NdotH, HdotL, NdotL, surface.clearCoat.normal, clearCoatRoughness, clearCoatF );
|
||||
|
||||
specular = specular * (1.0 - clearCoatF) * (1.0 - clearCoatF) + clearCoatSpecular;
|
||||
}
|
||||
|
||||
specular *= lightIntensity;
|
||||
|
||||
return specular;
|
||||
}
|
||||
|
||||
//! Adjust the intensity of specular light based on the radius of the light source and roughness of the surface to approximate energy conservation.
|
||||
float GetIntensityAdjustedByRadiusAndRoughness(float roughnessA, float radius, float distance2)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
* rather than transmit.
|
||||
**/
|
||||
|
||||
#include <Atom/Features/PBR/Surface.azsli>
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include "Ggx.azsli"
|
||||
#include "Fresnel.azsli"
|
||||
@@ -81,9 +80,6 @@ float3 DiffuseTitanfall(float roughnessA, float3 albedo, float3 normal, float3 d
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ------- Specular Lighting -------
|
||||
|
||||
//! Computes specular response from surfaces with microgeometry. The common form for microfacet
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// //! The surface struct should contain all the info for a pixel that can be
|
||||
// //! passed onto the rendering logic for shading.
|
||||
// //! Note that metallic workflow can be supported by first converting to these physical properties first.
|
||||
// struct Surface
|
||||
// {
|
||||
// float3 position;
|
||||
// float3 normal;
|
||||
// float3 tangentAniso; //! surface space tangent for anisotropic use
|
||||
// float3 bitangentAniso; //! surface space bitangent for anisotropic use
|
||||
// float2 anisotropyFactors; //! anisotory factors along the tangent and the bitangent directions
|
||||
// float3 albedo;
|
||||
// float3 specularF0; //!< actual fresnel f0 spectral value of the surface (as opposed to a "factor")
|
||||
// float3 multiScatterCompensation; //!< the constant scaling term to approximate multiscattering contribution in specular BRDF
|
||||
// float roughnessLinear; //!< perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use
|
||||
// float roughnessA; //!< actual roughness value ( a.k.a. "alpha roughness") to be used in microfacet calculations
|
||||
// float thickness; //!< pre baked local thickness, used for transmission
|
||||
// float4 transmissionParams; //!< parameters: thick mode->(attenuation coefficient, power, distortion, scale), thin mode: (float3 scatter distance, scale)
|
||||
// float clearCoatFactor; //!< clear coat strength factor
|
||||
// float clearCoatRoughness; //!< clear coat linear roughness (not base layer one)
|
||||
// float3 clearCoatNormal; //!< normal used for top layer clear coat
|
||||
// };
|
||||
//
|
||||
// //! Calculate and fill the data required for fast directional anisotropty surface response.
|
||||
// //! Assumption: the normal and roughnessA surface properties were filled and are valid
|
||||
// //! Notice that since the newly created surface tangent and bitangent will be rotated
|
||||
// //! according to the anisotropy direction and should not be used for other purposes uness
|
||||
// //! rotated back.
|
||||
// void CalculateSurfaceDirectionalAnisotropicData(
|
||||
// inout Surface surface, float2 anisotropyAngleAndFactor,
|
||||
// float3 vtxTangent, float3 vtxBitangent )
|
||||
// {
|
||||
// const float anisotropyAngle = anisotropyAngleAndFactor.x;
|
||||
// const float anisotropyFactor = anisotropyAngleAndFactor.y;
|
||||
//
|
||||
// surface.anisotropyFactors = max( 0.01,
|
||||
// float2( surface.roughnessA * (1.0 + anisotropyFactor),
|
||||
// surface.roughnessA * (1.0 - anisotropyFactor) )
|
||||
// );
|
||||
//
|
||||
// if (anisotropyAngle > 0.01)
|
||||
// {
|
||||
// // Base rotation according to anisotropic main direction
|
||||
// float aniSin, aniCos;
|
||||
// sincos(anisotropyAngle, aniSin, aniCos);
|
||||
//
|
||||
// // Rotate the vertex tangent to get new aligned to surface normal tangent
|
||||
// vtxTangent = aniCos * vtxTangent - aniSin * vtxBitangent;
|
||||
// }
|
||||
//
|
||||
// // Now create the new surface base according to the surface normal
|
||||
// // If rotation was required it was already applied to the tangent, hence to the bitangent
|
||||
// surface.bitangentAniso = normalize(cross(surface.normal, vtxTangent));
|
||||
// surface.tangentAniso = cross(surface.bitangentAniso, surface.normal);
|
||||
// }
|
||||
+3
@@ -63,6 +63,9 @@ void BasePbrSurfaceData::ApplySpecularAA()
|
||||
float kernelRoughnessA2 = min(2.0 * variance , varianceThresh );
|
||||
float filteredRoughnessA2 = saturate ( roughnessA2 + kernelRoughnessA2 );
|
||||
roughnessA2 = filteredRoughnessA2;
|
||||
|
||||
roughnessA = sqrt(roughnessA2);
|
||||
roughnessLinear = sqrt(roughnessA);
|
||||
}
|
||||
|
||||
void BasePbrSurfaceData::CalculateRoughnessA()
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Features/PBR/Surfaces/AnisotropicSurfaceData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/BasePbrSurfaceData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli>
|
||||
|
||||
class Surface //: BasePbrSurfaceData
|
||||
{
|
||||
//BasePbrSurfaceData pbr;
|
||||
AnisotropicSurfaceData anisotropy;
|
||||
ClearCoatSurfaceData clearCoat;
|
||||
TransmissionSurfaceData transmission;
|
||||
|
||||
// ------- BasePbrSurfaceData -------
|
||||
|
||||
float3 position; //!< Position in world-space
|
||||
float3 normal; //!< Normal in world-space
|
||||
float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value
|
||||
float3 specularF0; //!< Fresnel f0 spectral value of the surface
|
||||
float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use
|
||||
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
|
||||
|
||||
//! Applies specular anti-aliasing to roughnessA2
|
||||
void ApplySpecularAA();
|
||||
|
||||
//! Calculates roughnessA and roughnessA2 after roughness has been set
|
||||
void CalculateRoughnessA();
|
||||
|
||||
//! Sets albedo and specularF0 using metallic workflow
|
||||
void SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Specular Anti-Aliasing technique from this paper:
|
||||
// http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
|
||||
void Surface::ApplySpecularAA()
|
||||
{
|
||||
// Constants for formula below
|
||||
const float screenVariance = 0.25f;
|
||||
const float varianceThresh = 0.18f;
|
||||
|
||||
// Specular Anti-Aliasing
|
||||
float3 dndu = ddx_fine( normal );
|
||||
float3 dndv = ddy_fine( normal );
|
||||
float variance = screenVariance * (dot( dndu , dndu ) + dot( dndv , dndv ));
|
||||
float kernelRoughnessA2 = min(2.0 * variance , varianceThresh );
|
||||
float filteredRoughnessA2 = saturate ( roughnessA2 + kernelRoughnessA2 );
|
||||
roughnessA2 = filteredRoughnessA2;
|
||||
}
|
||||
|
||||
void Surface::CalculateRoughnessA()
|
||||
{
|
||||
// The roughness value in microfacet calculations (called "alpha" in the literature) does not give perceptually
|
||||
// linear results. Disney found that squaring the roughness value before using it in microfacet equations causes
|
||||
// the user-provided roughness parameter to be more perceptually linear. We keep both values available as some
|
||||
// equations need roughnessLinear (i.e. IBL sampling) while others need roughnessA (i.e. GGX equations).
|
||||
// See Burley's Disney PBR: https://pdfs.semanticscholar.org/eeee/3b125c09044d3e2f58ed0e4b1b66a677886d.pdf
|
||||
|
||||
roughnessA = max(roughnessLinear * roughnessLinear, MinRoughnessA);
|
||||
|
||||
roughnessA2 = roughnessA * roughnessA;
|
||||
if(o_applySpecularAA)
|
||||
{
|
||||
ApplySpecularAA();
|
||||
}
|
||||
}
|
||||
|
||||
void Surface::SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic)
|
||||
{
|
||||
float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * inSpecularF0;
|
||||
|
||||
// Compute albedo and specularF0 based on metalness
|
||||
albedo = lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic);
|
||||
specularF0 = lerp(dielectricSpecularF0, baseColor, metallic);
|
||||
}
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Features/PBR/Surfaces/AnisotropicSurfaceData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/BasePbrSurfaceData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/ClearCoatSurfaceData.azsli>
|
||||
#include <Atom/Features/PBR/Surfaces/TransmissionSurfaceData.azsli>
|
||||
|
||||
class Surface //: BasePbrSurfaceData
|
||||
{
|
||||
//BasePbrSurfaceData pbr;
|
||||
AnisotropicSurfaceData anisotropy;
|
||||
ClearCoatSurfaceData clearCoat;
|
||||
TransmissionSurfaceData transmission;
|
||||
|
||||
// ------- BasePbrSurfaceData -------
|
||||
|
||||
float3 position; //!< Position in world-space
|
||||
float3 normal; //!< Normal in world-space
|
||||
float3 albedo; //!< Albedo color of the non-metallic material, will be multiplied against the diffuse lighting value
|
||||
float3 specularF0; //!< Fresnel f0 spectral value of the surface
|
||||
float roughnessLinear; //!< Perceptually linear roughness value authored by artists. Must be remapped to roughnessA before use
|
||||
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
|
||||
|
||||
//! Applies specular anti-aliasing to roughnessA2
|
||||
void ApplySpecularAA();
|
||||
|
||||
//! Calculates roughnessA and roughnessA2 after roughness has been set
|
||||
void CalculateRoughnessA();
|
||||
|
||||
//! Sets albedo and specularF0 using metallic workflow
|
||||
void SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Specular Anti-Aliasing technique from this paper:
|
||||
// http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
|
||||
void Surface::ApplySpecularAA()
|
||||
{
|
||||
// Constants for formula below
|
||||
const float screenVariance = 0.25f;
|
||||
const float varianceThresh = 0.18f;
|
||||
|
||||
// Specular Anti-Aliasing
|
||||
float3 dndu = ddx_fine( normal );
|
||||
float3 dndv = ddy_fine( normal );
|
||||
float variance = screenVariance * (dot( dndu , dndu ) + dot( dndv , dndv ));
|
||||
float kernelRoughnessA2 = min(2.0 * variance , varianceThresh );
|
||||
float filteredRoughnessA2 = saturate ( roughnessA2 + kernelRoughnessA2 );
|
||||
roughnessA2 = filteredRoughnessA2;
|
||||
}
|
||||
|
||||
void Surface::CalculateRoughnessA()
|
||||
{
|
||||
// The roughness value in microfacet calculations (called "alpha" in the literature) does not give perceptually
|
||||
// linear results. Disney found that squaring the roughness value before using it in microfacet equations causes
|
||||
// the user-provided roughness parameter to be more perceptually linear. We keep both values available as some
|
||||
// equations need roughnessLinear (i.e. IBL sampling) while others need roughnessA (i.e. GGX equations).
|
||||
// See Burley's Disney PBR: https://pdfs.semanticscholar.org/eeee/3b125c09044d3e2f58ed0e4b1b66a677886d.pdf
|
||||
|
||||
roughnessA = max(roughnessLinear * roughnessLinear, MinRoughnessA);
|
||||
|
||||
roughnessA2 = roughnessA * roughnessA;
|
||||
if(o_applySpecularAA)
|
||||
{
|
||||
ApplySpecularAA();
|
||||
}
|
||||
}
|
||||
|
||||
void Surface::SetAlbedoAndSpecularF0(float3 baseColor, float inSpecularF0, float metallic)
|
||||
{
|
||||
float3 dielectricSpecularF0 = MaxDielectricSpecularF0 * inSpecularF0;
|
||||
|
||||
// Compute albedo and specularF0 based on metalness
|
||||
albedo = lerp(baseColor, float3(0.0f, 0.0f, 0.0f), metallic);
|
||||
specularF0 = lerp(dielectricSpecularF0, baseColor, metallic);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#pragma once
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// NOTE: VSInput, VSOutput, ObjectSrg must be defined before including this file.
|
||||
// NOTE: The following must be included or defined before including this file:
|
||||
// - VSInput - ObjectSrg
|
||||
// - VSOutput - PassSrg
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
// Options
|
||||
@@ -23,8 +25,6 @@
|
||||
#include <viewsrg.srgi>
|
||||
#include <scenesrg.srgi>
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/PBR/ForwardPassSrg.azsli>
|
||||
|
||||
// Math
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
@@ -33,7 +33,6 @@
|
||||
// Shadow Coords
|
||||
#include <Atom/Features/Shadow/DirectionalLightShadow.azsli>
|
||||
|
||||
|
||||
//! @param skipShadowCoords can be useful for example when PixelDepthOffset is enable, because the pixel shader will have to run before the final world position is known
|
||||
void VertexHelper(in VSInput IN, inout VSOutput OUT, float3 worldPosition, bool skipShadowCoords = false)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user