Merge pull request #6443 from aws-lumberyard-dev/Atom/antonmic/BasePBR

Atom/antonmic/base pbr
monroegm-disable-blank-issue-2
antonmic 4 years ago committed by GitHub
commit 3d2f9528f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,6 @@
{ {
"description": "", "description": "",
"materialType": "Materials\\Types\\StandardPBR.materialtype", "materialType": "Materials\\Types\\BasePBR.materialtype",
"parentMaterial": "", "parentMaterial": "",
"materialTypeVersion": 3, "materialTypeVersion": 3,
"properties": { "properties": {

@ -1,6 +1,6 @@
{ {
"description": "", "description": "",
"materialType": "Materials\\Types\\StandardPBR.materialtype", "materialType": "Materials\\Types\\BasePBR.materialtype",
"parentMaterial": "", "parentMaterial": "",
"materialTypeVersion": 3, "materialTypeVersion": 3,
"properties": { "properties": {

@ -1,6 +1,6 @@
{ {
"description": "", "description": "",
"materialType": "Materials/Types/StandardPBR.materialtype", "materialType": "Materials/Types/BasePBR.materialtype",
"parentMaterial": "", "parentMaterial": "",
"materialTypeVersion": 3, "materialTypeVersion": 3,
"properties": { "properties": {

@ -0,0 +1,605 @@
{
"description": "Material Type with properties used to define Base PBR, a metallic-roughness Physically-Based Rendering (PBR) material shading model.",
"version": 0,
"propertyLayout": {
"groups": [
{
"name": "baseColor",
"displayName": "Base Color",
"description": "Properties for configuring the surface reflected color for dielectrics or reflectance values for metals."
},
{
"name": "metallic",
"displayName": "Metallic",
"description": "Properties for configuring whether the surface is metallic or not."
},
{
"name": "roughness",
"displayName": "Roughness",
"description": "Properties for configuring how rough the surface appears."
},
{
"name": "specularF0",
"displayName": "Specular Reflectance f0",
"description": "The constant f0 represents the specular reflectance at normal incidence (Fresnel 0 Angle). Used to adjust reflectance of non-metal surfaces."
},
{
"name": "normal",
"displayName": "Normal",
"description": "Properties related to configuring surface normal."
},
{
"name": "uv",
"displayName": "UVs",
"description": "Properties for configuring UV transforms."
},
{
// Note: this property group is used in the DiffuseGlobalIllumination pass, it is not read by the BasePBR shader
"name": "irradiance",
"displayName": "Irradiance",
"description": "Properties for configuring the irradiance used in global illumination."
},
{
"name": "general",
"displayName": "General Settings",
"description": "General settings."
}
],
"properties": {
"general": [
{
"name": "doubleSided",
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"name": "applySpecularAA",
"displayName": "Apply Specular AA",
"description": "Whether to apply specular anti-aliasing in the shader.",
"type": "Bool",
"defaultValue": false,
"connection": {
"type": "ShaderOption",
"name": "o_applySpecularAA"
}
},
{
"name": "enableShadows",
"displayName": "Enable Shadows",
"description": "Whether to use the shadow maps.",
"type": "Bool",
"defaultValue": true,
"connection": {
"type": "ShaderOption",
"name": "o_enableShadows"
}
},
{
"name": "enableDirectionalLights",
"displayName": "Enable Directional Lights",
"description": "Whether to use directional lights.",
"type": "Bool",
"defaultValue": true,
"connection": {
"type": "ShaderOption",
"name": "o_enableDirectionalLights"
}
},
{
"name": "enablePunctualLights",
"displayName": "Enable Punctual Lights",
"description": "Whether to use punctual lights.",
"type": "Bool",
"defaultValue": true,
"connection": {
"type": "ShaderOption",
"name": "o_enablePunctualLights"
}
},
{
"name": "enableAreaLights",
"displayName": "Enable Area Lights",
"description": "Whether to use area lights.",
"type": "Bool",
"defaultValue": true,
"connection": {
"type": "ShaderOption",
"name": "o_enableAreaLights"
}
},
{
"name": "enableIBL",
"displayName": "Enable IBL",
"description": "Whether to use Image Based Lighting (IBL).",
"type": "Bool",
"defaultValue": true,
"connection": {
"type": "ShaderOption",
"name": "o_enableIBL"
}
},
{
"name": "forwardPassIBLSpecular",
"displayName": "Forward Pass IBL Specular",
"description": "Whether to apply IBL specular in the forward pass.",
"type": "Bool",
"defaultValue": false,
"connection": {
"type": "ShaderOption",
"name": "o_materialUseForwardPassIBLSpecular"
}
}
],
"baseColor": [
{
"name": "color",
"displayName": "Color",
"description": "Color is displayed as sRGB but the values are stored as linear color.",
"type": "Color",
"defaultValue": [ 1.0, 1.0, 1.0 ],
"connection": {
"type": "ShaderInput",
"name": "m_baseColor"
}
},
{
"name": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the base color values. Zero (0.0) is black, white (1.0) is full color.",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 1.0,
"connection": {
"type": "ShaderInput",
"name": "m_baseColorFactor"
}
},
{
"name": "textureMap",
"displayName": "Texture",
"description": "Base color texture map",
"type": "Image",
"connection": {
"type": "ShaderInput",
"name": "m_baseColorMap"
}
},
{
"name": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture.",
"type": "Bool",
"defaultValue": true
},
{
"name": "textureMapUv",
"displayName": "UV",
"description": "Base color map UV set",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"name": "m_baseColorMapUvIndex"
}
},
{
"name": "textureBlendMode",
"displayName": "Texture Blend Mode",
"description": "Selects the equation to use when combining Color, Factor, and Texture.",
"type": "Enum",
"enumValues": [ "Multiply", "LinearLight", "Lerp", "Overlay" ],
"defaultValue": "Multiply",
"connection": {
"type": "ShaderOption",
"name": "o_baseColorTextureBlendMode"
}
}
],
"metallic": [
{
"name": "factor",
"displayName": "Factor",
"description": "This value is linear, black is non-metal and white means raw metal.",
"type": "Float",
"defaultValue": 0.0,
"min": 0.0,
"max": 1.0,
"connection": {
"type": "ShaderInput",
"name": "m_metallicFactor"
}
},
{
"name": "textureMap",
"displayName": "Texture",
"description": "",
"type": "Image",
"connection": {
"type": "ShaderInput",
"name": "m_metallicMap"
}
},
{
"name": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
{
"name": "textureMapUv",
"displayName": "UV",
"description": "Metallic map UV set",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"name": "m_metallicMapUvIndex"
}
}
],
"roughness": [
{
"name": "textureMap",
"displayName": "Texture",
"description": "Texture for defining surface roughness.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"name": "m_roughnessMap"
}
},
{
"name": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
{
"name": "textureMapUv",
"displayName": "UV",
"description": "Roughness map UV set",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"name": "m_roughnessMapUvIndex"
}
},
{
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
"name": "lowerBound",
"displayName": "Lower Bound",
"description": "The roughness value that corresponds to black in the texture.",
"type": "Float",
"defaultValue": 0.0,
"min": 0.0,
"max": 1.0,
"connection": {
"type": "ShaderInput",
"name": "m_roughnessLowerBound"
}
},
{
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
"name": "upperBound",
"displayName": "Upper Bound",
"description": "The roughness value that corresponds to white in the texture.",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 1.0,
"connection": {
"type": "ShaderInput",
"name": "m_roughnessUpperBound"
}
},
{
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
"name": "factor",
"displayName": "Factor",
"description": "Controls the roughness value",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 1.0,
"connection": {
"type": "ShaderInput",
"name": "m_roughnessFactor"
}
}
],
"specularF0": [
{
"name": "factor",
"displayName": "Factor",
"description": "The default IOR is 1.5, which gives you 0.04 (4% of light reflected at 0 degree angle for dielectric materials). F0 values lie in the range 0-0.08, so that is why the default F0 slider is set on 0.5.",
"type": "Float",
"defaultValue": 0.5,
"min": 0.0,
"max": 1.0,
"connection": {
"type": "ShaderInput",
"name": "m_specularF0Factor"
}
},
{
"name": "textureMap",
"displayName": "Texture",
"description": "Texture for defining surface reflectance.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"name": "m_specularF0Map"
}
},
{
"name": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture, or just default to the Factor value.",
"type": "Bool",
"defaultValue": true
},
{
"name": "textureMapUv",
"displayName": "UV",
"description": "Specular reflection map UV set",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"name": "m_specularF0MapUvIndex"
}
},
// Consider moving this to the "general" group to be consistent with StandardMultilayerPBR
{
"name": "enableMultiScatterCompensation",
"displayName": "Multiscattering Compensation",
"description": "Whether to enable multiple scattering compensation.",
"type": "Bool",
"connection": {
"type": "ShaderOption",
"name": "o_specularF0_enableMultiScatterCompensation"
}
}
],
"normal": [
{
"name": "textureMap",
"displayName": "Texture",
"description": "Texture for defining surface normal direction.",
"type": "Image",
"connection": {
"type": "ShaderInput",
"name": "m_normalMap"
}
},
{
"name": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture, or just rely on vertex normals.",
"type": "Bool",
"defaultValue": true
},
{
"name": "textureMapUv",
"displayName": "UV",
"description": "Normal map UV set",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"name": "m_normalMapUvIndex"
}
},
{
"name": "flipX",
"displayName": "Flip X Channel",
"description": "Flip tangent direction for this normal map.",
"type": "Bool",
"defaultValue": false,
"connection": {
"type": "ShaderInput",
"name": "m_flipNormalX"
}
},
{
"name": "flipY",
"displayName": "Flip Y Channel",
"description": "Flip bitangent direction for this normal map.",
"type": "Bool",
"defaultValue": false,
"connection": {
"type": "ShaderInput",
"name": "m_flipNormalY"
}
},
{
"name": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the values",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"softMax": 2.0,
"connection": {
"type": "ShaderInput",
"name": "m_normalFactor"
}
}
],
"uv": [
{
"name": "center",
"displayName": "Center",
"description": "Center point for scaling and rotation transformations.",
"type": "vector2",
"vectorLabels": [ "U", "V" ],
"defaultValue": [ 0.5, 0.5 ]
},
{
"name": "tileU",
"displayName": "Tile U",
"description": "Scales texture coordinates in U.",
"type": "float",
"defaultValue": 1.0,
"step": 0.1
},
{
"name": "tileV",
"displayName": "Tile V",
"description": "Scales texture coordinates in V.",
"type": "float",
"defaultValue": 1.0,
"step": 0.1
},
{
"name": "offsetU",
"displayName": "Offset U",
"description": "Offsets texture coordinates in the U direction.",
"type": "float",
"defaultValue": 0.0,
"min": -1.0,
"max": 1.0
},
{
"name": "offsetV",
"displayName": "Offset V",
"description": "Offsets texture coordinates in the V direction.",
"type": "float",
"defaultValue": 0.0,
"min": -1.0,
"max": 1.0
},
{
"name": "rotateDegrees",
"displayName": "Rotate",
"description": "Rotates the texture coordinates (degrees).",
"type": "float",
"defaultValue": 0.0,
"min": -180.0,
"max": 180.0,
"step": 1.0
},
{
"name": "scale",
"displayName": "Scale",
"description": "Scales texture coordinates in both U and V.",
"type": "float",
"defaultValue": 1.0,
"step": 0.1
}
],
"irradiance": [
// Note: this property group is used in the DiffuseGlobalIllumination pass and not by the main forward shader
{
"name": "color",
"displayName": "Color",
"description": "Color is displayed as sRGB but the values are stored as linear color.",
"type": "Color",
"defaultValue": [ 1.0, 1.0, 1.0 ]
},
{
"name": "factor",
"displayName": "Factor",
"description": "Strength factor for scaling the irradiance color values. Zero (0.0) is black, white (1.0) is full color.",
"type": "Float",
"defaultValue": 1.0,
"min": 0.0,
"max": 1.0
}
]
}
},
"shaders": [
{
"file": "./BasePBR_ForwardPass.shader",
"tag": "ForwardPass_EDS"
},
{
"file": "./BasePBR_LowEndForward.shader",
"tag": "LowEndForward_EDS"
},
{
"file": "Shaders/Shadow/Shadowmap.shader",
"tag": "Shadowmap"
},
{
"file": "Shaders/Depth/DepthPass.shader",
"tag": "DepthPass"
},
{
"file": "Shaders/MotionVector/MeshMotionVector.shader",
"tag": "MeshMotionVector"
}
],
"functors": [
{
// Maps 2D scale, offset, and rotate properties into a float3x3 transform matrix.
"type": "Transform2D",
"args": {
"transformOrder": [ "Rotate", "Translate", "Scale" ],
"centerProperty": "uv.center",
"scaleProperty": "uv.scale",
"scaleXProperty": "uv.tileU",
"scaleYProperty": "uv.tileV",
"translateXProperty": "uv.offsetU",
"translateYProperty": "uv.offsetV",
"rotateDegreesProperty": "uv.rotateDegrees",
"float3x3ShaderInput": "m_uvMatrix",
"float3x3InverseShaderInput": "m_uvMatrixInverse"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "baseColor.textureMap",
"useTextureProperty": "baseColor.useTexture",
"dependentProperties": ["baseColor.textureMapUv", "baseColor.textureBlendMode"],
"shaderOption": "o_baseColor_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "specularF0.textureMap",
"useTextureProperty": "specularF0.useTexture",
"dependentProperties": ["specularF0.textureMapUv"],
"shaderOption": "o_specularF0_useTexture"
}
},
{
"type": "UseTexture",
"args": {
"textureProperty": "normal.textureMap",
"useTextureProperty": "normal.useTexture",
"dependentProperties": ["normal.textureMapUv", "normal.factor", "normal.flipX", "normal.flipY"],
"shaderOption": "o_normal_useTexture"
}
},
{
"type": "Lua",
"args": {
"file": "StandardPBR_Roughness.lua"
}
},
{
"type": "Lua",
"args": {
"file": "StandardPBR_Metallic.lua"
}
}
],
"uvNameMap": {
"UV0": "Tiled",
"UV1": "Unwrapped"
}
}

@ -0,0 +1,59 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/Features/SrgSemantics.azsli>
#include <viewsrg.srgi>
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
#include <Atom/Features/PBR/LightingOptions.azsli>
#include <Atom/Features/PBR/AlphaUtils.azsli>
#include "MaterialInputs/BaseColorInput.azsli"
#include "MaterialInputs/RoughnessInput.azsli"
#include "MaterialInputs/MetallicInput.azsli"
#include "MaterialInputs/SpecularInput.azsli"
#include "MaterialInputs/NormalInput.azsli"
#include "MaterialInputs/UvSetCount.azsli"
ShaderResourceGroup MaterialSrg : SRG_PerMaterial
{
// Auto-generate material SRG fields for common inputs
COMMON_SRG_INPUTS_BASE_COLOR()
COMMON_SRG_INPUTS_ROUGHNESS()
COMMON_SRG_INPUTS_METALLIC()
COMMON_SRG_INPUTS_SPECULAR_F0()
COMMON_SRG_INPUTS_NORMAL()
float3x3 m_uvMatrix;
float4 m_pad1; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
float3x3 m_uvMatrixInverse;
float4 m_pad2; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
Sampler m_sampler
{
AddressU = Wrap;
AddressV = Wrap;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
MaxAnisotropy = 16;
};
Texture2D m_brdfMap;
Sampler m_samplerBrdf
{
AddressU = Clamp;
AddressV = Clamp;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};
}

@ -0,0 +1,199 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "Atom/Features/ShaderQualityOptions.azsli"
#include "BasePBR_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>
// Custom Surface & Lighting
#include <Atom/Features/PBR/Lighting/BaseLighting.azsli>
// Decals
#include <Atom/Features/PBR/Decals.azsli>
// ---------- Material Parameters ----------
COMMON_OPTIONS_BASE_COLOR()
COMMON_OPTIONS_ROUGHNESS()
COMMON_OPTIONS_METALLIC()
COMMON_OPTIONS_SPECULAR_F0()
COMMON_OPTIONS_NORMAL()
// ---------- Vertex Shader ----------
struct VSInput
{
// Base fields (required by the template azsli file)...
float3 m_position : POSITION;
float3 m_normal : NORMAL;
float4 m_tangent : TANGENT;
float3 m_bitangent : BITANGENT;
// Extended fields (only referenced in this azsl file)...
float2 m_uv0 : UV0;
float2 m_uv1 : UV1;
};
struct VSOutput
{
// Base fields (required by the template azsli file)...
// "centroid" is needed for SV_Depth to compile
linear centroid float4 m_position : SV_Position;
float3 m_normal: NORMAL;
float3 m_tangent : TANGENT;
float3 m_bitangent : BITANGENT;
float3 m_worldPosition : UV0;
float3 m_shadowCoords[ViewSrg::MaxCascadeCount] : UV3;
// Extended fields (only referenced in this azsl file)...
float2 m_uv[UvSetCount] : UV1;
};
#include <Atom/Features/Vertex/VertexHelper.azsli>
VSOutput BasePbr_ForwardPassVS(VSInput IN)
{
VSOutput OUT;
float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz;
// By design, only UV0 is allowed to apply transforms.
OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy;
OUT.m_uv[1] = IN.m_uv1;
// No parallax in BaseBPR, so do shadow coordinate calculations in vertex shader
bool skipShadowCoords = false;
VertexHelper(IN, OUT, worldPosition, skipShadowCoords);
return OUT;
}
// ---------- Pixel Shader ----------
PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace)
{
const float3 vertexNormal = normalize(IN.m_normal);
// ------- Tangents & Bitangets -------
float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz };
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz };
if (o_normal_useTexture)
{
PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents);
}
Surface surface;
surface.position = IN.m_worldPosition.xyz;
// ------- Normal -------
float2 normalUv = IN.m_uv[MaterialSrg::m_normalMapUvIndex];
float3x3 uvMatrix = MaterialSrg::m_normalMapUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3(); // By design, only UV0 is allowed to apply transforms.
surface.vertexNormal = vertexNormal;
surface.normal = GetNormalInputWS(MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, isFrontFace, IN.m_normal,
tangents[MaterialSrg::m_normalMapUvIndex], bitangents[MaterialSrg::m_normalMapUvIndex], uvMatrix, o_normal_useTexture, MaterialSrg::m_normalFactor);
// ------- Base Color -------
float2 baseColorUv = IN.m_uv[MaterialSrg::m_baseColorMapUvIndex];
float3 sampledColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor.rgb, o_baseColor_useTexture);
float3 baseColor = BlendBaseColor(sampledColor, MaterialSrg::m_baseColor.rgb, MaterialSrg::m_baseColorFactor, o_baseColorTextureBlendMode, o_baseColor_useTexture);
// ------- Metallic -------
float2 metallicUv = IN.m_uv[MaterialSrg::m_metallicMapUvIndex];
float metallic = GetMetallicInput(MaterialSrg::m_metallicMap, MaterialSrg::m_sampler, metallicUv, MaterialSrg::m_metallicFactor, o_metallic_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);
surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
// ------- Roughness -------
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);
surface.CalculateRoughnessA();
// ------- 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;
// Diffuse and Specular response (used in IBL calculations)
lightingData.specularResponse = FresnelSchlickWithRoughness(lightingData.NdotV, surface.specularF0, surface.roughnessLinear);
lightingData.diffuseResponse = float3(1.0, 1.0, 1.0) - lightingData.specularResponse;
// ------- Multiscatter -------
lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation);
// ------- Lighting Calculation -------
// Apply Decals
ApplyDecals(lightingData.tileIterator, surface);
// Apply Direct Lighting
ApplyDirectLighting(surface, lightingData);
// Apply Image Based Lighting (IBL)
ApplyIBL(surface, lightingData);
// Finalize Lighting
lightingData.FinalizeLighting();
float alpha = 1.0f;
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
// Disable subsurface scattering
lightingOutput.m_diffuseColor.w = -1;
return lightingOutput;
}
ForwardPassOutput BasePbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFace)
{
ForwardPassOutput OUT;
PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace);
#ifdef UNIFIED_FORWARD_OUTPUT
OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb;
OUT.m_color.a = lightingOutput.m_diffuseColor.a;
#else
OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
OUT.m_specularColor = lightingOutput.m_specularColor;
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
#endif
return OUT;
}

@ -0,0 +1,53 @@
{
"Source" : "./BasePBR_ForwardPass.azsl",
"DepthStencilState" :
{
"Depth" :
{
"Enable" : true,
"CompareFunc" : "GreaterEqual"
},
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
}
}
},
"CompilerHints" : {
"DisableOptimizations" : false
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "BasePbr_ForwardPassVS",
"type": "Vertex"
},
{
"name": "BasePbr_ForwardPassPS_EDS",
"type": "Fragment"
}
]
},
"DrawList" : "forward"
}

@ -0,0 +1,29 @@
{
"Shader" : "BasePBR_ForwardPass.shader",
"Variants": [
{
"StableId": 1,
"Options": {
"o_directional_shadow_filtering_method": "ShadowFilterMethod::None"
}
},
{
"StableId": 2,
"Options": {
"o_directional_shadow_filtering_method": "ShadowFilterMethod::Pcf"
}
},
{
"StableId": 3,
"Options": {
"o_directional_shadow_filtering_method": "ShadowFilterMethod::Esm"
}
},
{
"StableId": 4,
"Options": {
"o_directional_shadow_filtering_method": "ShadowFilterMethod::EsmPcf"
}
}
]
}

@ -0,0 +1,13 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
// NOTE: This file is a temporary workaround until .shader files can #define macros for their .azsl files
#define QUALITY_LOW_END 1
#include "BasePBR_ForwardPass.azsl"

@ -0,0 +1,59 @@
{
// Note: "LowEnd" shaders are for supporting the low end pipeline
// These shaders can be safely added to materials without incurring additional runtime draw
// items as draw items for shaders are only created if the scene has a pass with a matching
// DrawListTag. If your pipeline doesn't have a "lowEndForward" DrawListTag, no draw items
// for this shader will be created.
"Source" : "./BasePBR_LowEndForward.azsl",
"DepthStencilState" :
{
"Depth" :
{
"Enable" : true,
"CompareFunc" : "GreaterEqual"
},
"Stencil" :
{
"Enable" : true,
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
}
}
},
"CompilerHints" : {
"DisableOptimizations" : false
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "BasePbr_ForwardPassVS",
"type": "Vertex"
},
{
"name": "BasePbr_ForwardPassPS_EDS",
"type": "Fragment"
}
]
},
"DrawList" : "lowEndForward"
}

@ -428,7 +428,6 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
Surface surface; Surface surface;
surface.position = IN.m_worldPosition; surface.position = IN.m_worldPosition;
surface.transmission.InitializeToZero();
// ------- Combine Normals --------- // ------- Combine Normals ---------
@ -523,7 +522,7 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
ApplyIBL(surface, lightingData); ApplyIBL(surface, lightingData);
// Finalize Lighting // Finalize Lighting
lightingData.FinalizeLighting(0); lightingData.FinalizeLighting();
const float alpha = 1.0; const float alpha = 1.0;

@ -30,7 +30,6 @@
} }
}, },
"CompilerHints" : { "CompilerHints" : {
"DisableOptimizations" : false "DisableOptimizations" : false
}, },

@ -36,6 +36,9 @@ float ThinObjectFalloff(const float3 surfaceNormal, const float3 dirToLight)
float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight, float shadowRatio) float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightIntensity, float3 dirToLight, float shadowRatio)
{ {
float3 result = float3(0.0, 0.0, 0.0); float3 result = float3(0.0, 0.0, 0.0);
#if ENABLE_TRANSMISSION
float thickness = 0.0; float thickness = 0.0;
float4 transmissionParams = surface.transmission.transmissionParams; float4 transmissionParams = surface.transmission.transmissionParams;
@ -72,6 +75,8 @@ float3 GetBackLighting(Surface surface, LightingData lightingData, float3 lightI
break; break;
} }
#endif
return result; return result;
} }

@ -0,0 +1,83 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#define ENABLE_CLEAR_COAT 0
#define ENABLE_TRANSMISSION 0
#define ENABLE_AREA_LIGHT_VALIDATION 0
// 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 = DiffuseLambertian(surface.albedo, surface.normal, dirToLight, lightingData.diffuseResponse);
diffuse *= lightIntensity;
return diffuse;
}
float3 GetSpecularLighting(Surface surface, LightingData lightingData, const float3 lightIntensity, const float3 dirToLight)
{
float3 specular = SpecularGGX(lightingData.dirToCamera, dirToLight, surface.normal, surface.specularF0, lightingData.NdotV, surface.roughnessA2, lightingData.multiScatterCompensation);
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;
};
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 * lightingData.diffuseAmbientOcclusion;
lightingOutput.m_albedo.a = lightingData.specularOcclusion;
lightingOutput.m_normal.rgb = EncodeNormalSignedOctahedron(surface.normal);
lightingOutput.m_normal.a = o_specularF0_enableMultiScatterCompensation ? 1.0f : 0.0f;
return lightingOutput;
}
PbrLightingOutput DebugOutput(float3 color)
{
PbrLightingOutput output = (PbrLightingOutput)0;
float3 defaultNormal = float3(0.0f, 0.0f, 1.0f);
output.m_diffuseColor = float4(color.rgb, 1.0f);
output.m_normal.rgb = EncodeNormalSignedOctahedron(defaultNormal);
return output;
}

@ -56,10 +56,10 @@ class LightingData
void LightingData::Init(float3 positionWS, float3 normal, float roughnessLinear) void LightingData::Init(float3 positionWS, float3 normal, float roughnessLinear)
{ {
diffuseLighting = 0; diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = 0; specularLighting = float3(0.0, 0.0, 0.0);
translucentBackLighting = 0; translucentBackLighting = float3(0.0, 0.0, 0.0);
multiScatterCompensation = 1.0f; multiScatterCompensation = float3(1.0f, 1.0f, 1.0f);
emissiveLighting = float3(0.0f, 0.0f, 0.0f); emissiveLighting = float3(0.0f, 0.0f, 0.0f);
diffuseAmbientOcclusion = 1.0f; diffuseAmbientOcclusion = 1.0f;
specularOcclusion = 1.0f; specularOcclusion = 1.0f;
@ -88,8 +88,10 @@ void LightingData::FinalizeLighting(float3 transmissionTint)
FinalizeLighting(); FinalizeLighting();
// Transmitted light // Transmitted light
#if ENABLE_TRANSMISSION
if(o_transmission_mode != TransmissionMode::None) if(o_transmission_mode != TransmissionMode::None)
{ {
diffuseLighting += translucentBackLighting * transmissionTint; diffuseLighting += translucentBackLighting * transmissionTint;
} }
#endif
} }

@ -8,6 +8,8 @@
#pragma once #pragma once
#define ENABLE_TRANSMISSION 0
// Include options first // Include options first
#include <Atom/Features/PBR/LightingOptions.azsli> #include <Atom/Features/PBR/LightingOptions.azsli>

@ -8,6 +8,58 @@
#pragma once #pragma once
// --- Note: About this file ---
// This file uses #defines to completely strip out certain lighting features from shaders
// This enables us to avoid code duplication and write an uber-esque shader code and then
// be able to adjust the code for different use cases (for example basic materials can strip
// away transimission related code used for foliage). These are different from shader options
// in that shader options allow more user flexibility to adjust materials at runtime, whereas
// these #define options are for customizing and optimizing material types (like BasePBR)
// --- Light Defines ---
#ifndef ENABLE_AREA_LIGHT_VALIDATION
#define ENABLE_AREA_LIGHT_VALIDATION 1
#endif
#ifndef ENABLE_AREA_LIGHTS
#define ENABLE_AREA_LIGHTS 1
#endif
#ifndef ENABLE_SPHERE_LIGHTS
#define ENABLE_SPHERE_LIGHTS ENABLE_AREA_LIGHTS
#endif
#ifndef ENABLE_DISK_LIGHTS
#define ENABLE_DISK_LIGHTS ENABLE_AREA_LIGHTS
#endif
#ifndef ENABLE_CAPSULE_LIGHTS
#define ENABLE_CAPSULE_LIGHTS ENABLE_AREA_LIGHTS
#endif
#ifndef ENABLE_QUAD_LIGHTS
#define ENABLE_QUAD_LIGHTS ENABLE_AREA_LIGHTS
#endif
#ifndef ENABLE_POLYGON_LTC_LIGHTS
#define ENABLE_POLYGON_LTC_LIGHTS ENABLE_AREA_LIGHTS
#endif
// --- Material defines ---
#ifndef ENABLE_CLEAR_COAT
#define ENABLE_CLEAR_COAT 1
#endif
#ifndef ENABLE_TRANSMISSION
#define ENABLE_TRANSMISSION 1
#endif
// --- Shader Options ---
option bool o_specularF0_enableMultiScatterCompensation = true; option bool o_specularF0_enableMultiScatterCompensation = true;
option bool o_enableShadows = true; option bool o_enableShadows = true;
option bool o_enableDirectionalLights = true; option bool o_enableDirectionalLights = true;
@ -15,8 +67,14 @@ option bool o_enablePunctualLights = true;
option bool o_enableAreaLights = true; option bool o_enableAreaLights = true;
option bool o_enableIBL = true; option bool o_enableIBL = true;
option bool o_enableSubsurfaceScattering = false; option bool o_enableSubsurfaceScattering = false;
option bool o_clearCoat_feature_enabled = false;
option enum class TransmissionMode {None, ThickObject, ThinObject} o_transmission_mode;
option bool o_meshUseForwardPassIBLSpecular = false; option bool o_meshUseForwardPassIBLSpecular = false;
option bool o_materialUseForwardPassIBLSpecular = false; option bool o_materialUseForwardPassIBLSpecular = false;
option bool o_area_light_validation = false;
#if ENABLE_CLEAR_COAT
option bool o_clearCoat_feature_enabled = false;
#endif
#if ENABLE_TRANSMISSION
option enum class TransmissionMode {None, ThickObject, ThinObject} o_transmission_mode;
#endif

@ -224,14 +224,21 @@ void ApplyCapsuleLights(Surface surface, inout LightingData lightingData)
uint currLightIndex = lightingData.tileIterator.GetValue(); uint currLightIndex = lightingData.tileIterator.GetValue();
lightingData.tileIterator.LoadAdvance(); lightingData.tileIterator.LoadAdvance();
#if ENABLE_CAPSULE_LIGHTS
ViewSrg::CapsuleLight light = ViewSrg::m_capsuleLights[currLightIndex]; ViewSrg::CapsuleLight light = ViewSrg::m_capsuleLights[currLightIndex];
#if ENABLE_AREA_LIGHT_VALIDATION
if (o_area_light_validation) if (o_area_light_validation)
{ {
ValidateCapsuleLight(light, surface, lightingData); ValidateCapsuleLight(light, surface, lightingData);
} }
else else
#endif
{ {
ApplyCapsuleLight(light, surface, lightingData); ApplyCapsuleLight(light, surface, lightingData);
} }
#endif
} }
} }

@ -27,10 +27,12 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData)
surface.vertexNormal, surface.vertexNormal,
debugInfo); debugInfo);
#if ENABLE_TRANSMISSION
if (o_transmission_mode == TransmissionMode::ThickObject) if (o_transmission_mode == TransmissionMode::ThickObject)
{ {
backShadowRatio = DirectionalLightShadow::GetThickness(shadowIndex, lightingData.shadowCoords); backShadowRatio = DirectionalLightShadow::GetThickness(shadowIndex, lightingData.shadowCoords);
} }
#endif
} }
// Add the lighting contribution for each directional light // Add the lighting contribution for each directional light
@ -56,10 +58,12 @@ void ApplyDirectionalLights(Surface surface, inout LightingData lightingData)
currentLitRatio = (index == shadowIndex) ? litRatio : 1.; currentLitRatio = (index == shadowIndex) ? litRatio : 1.;
currentBackShadowRatio = 1.0 - currentLitRatio; currentBackShadowRatio = 1.0 - currentLitRatio;
#if ENABLE_TRANSMISSION
if (o_transmission_mode == TransmissionMode::ThickObject) if (o_transmission_mode == TransmissionMode::ThickObject)
{ {
currentBackShadowRatio = (index == shadowIndex) ? backShadowRatio : 0.; currentBackShadowRatio = (index == shadowIndex) ? backShadowRatio : 0.;
} }
#endif
} }
lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio; lightingData.diffuseLighting += GetDiffuseLighting(surface, lightingData, light.m_rgbIntensityLux, dirToLight) * currentLitRatio;

@ -90,12 +90,14 @@ void ApplyDiskLight(ViewSrg::DiskLight light, Surface surface, inout LightingDat
// Use backShadowRatio to carry thickness from shadow map for thick mode // Use backShadowRatio to carry thickness from shadow map for thick mode
backShadowRatio = 1.0 - litRatio; backShadowRatio = 1.0 - litRatio;
#if ENABLE_TRANSMISSION
if (o_transmission_mode == TransmissionMode::ThickObject) if (o_transmission_mode == TransmissionMode::ThickObject)
{ {
backShadowRatio = ProjectedShadow::GetThickness( backShadowRatio = ProjectedShadow::GetThickness(
light.m_shadowIndex, light.m_shadowIndex,
surface.position); surface.position);
} }
#endif
} }
if (useConeAngle && dotWithDirection < light.m_cosInnerConeAngle) // in penumbra if (useConeAngle && dotWithDirection < light.m_cosInnerConeAngle) // in penumbra
@ -209,15 +211,21 @@ void ApplyDiskLights(Surface surface, inout LightingData lightingData)
uint currLightIndex = lightingData.tileIterator.GetValue(); uint currLightIndex = lightingData.tileIterator.GetValue();
lightingData.tileIterator.LoadAdvance(); lightingData.tileIterator.LoadAdvance();
#if ENABLE_DISK_LIGHTS
ViewSrg::DiskLight light = ViewSrg::m_diskLights[currLightIndex]; ViewSrg::DiskLight light = ViewSrg::m_diskLights[currLightIndex];
#if ENABLE_AREA_LIGHT_VALIDATION
if (o_area_light_validation) if (o_area_light_validation)
{ {
ValidateDiskLight(light, surface, lightingData); ValidateDiskLight(light, surface, lightingData);
} }
else else
#endif
{ {
ApplyDiskLight(light, surface, lightingData); ApplyDiskLight(light, surface, lightingData);
} }
#endif
} }
} }

@ -98,6 +98,7 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
float3 iblSpecular = GetIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.dirToCamera, lightingData.brdf); float3 iblSpecular = GetIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.dirToCamera, lightingData.brdf);
iblSpecular *= lightingData.multiScatterCompensation; iblSpecular *= lightingData.multiScatterCompensation;
#if ENABLE_CLEAR_COAT
if (o_clearCoat_feature_enabled && surface.clearCoat.factor > 0.0f) if (o_clearCoat_feature_enabled && surface.clearCoat.factor > 0.0f)
{ {
float clearCoatNdotV = saturate(dot(surface.clearCoat.normal, lightingData.dirToCamera)); float clearCoatNdotV = saturate(dot(surface.clearCoat.normal, lightingData.dirToCamera));
@ -115,6 +116,7 @@ void ApplyIBL(Surface surface, inout LightingData lightingData)
float3 clearCoatResponse = FresnelSchlickWithRoughness(clearCoatNdotV, clearCoatSpecularF0, surface.clearCoat.roughness) * surface.clearCoat.factor; float3 clearCoatResponse = FresnelSchlickWithRoughness(clearCoatNdotV, clearCoatSpecularF0, surface.clearCoat.roughness) * surface.clearCoat.factor;
iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular; iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular;
} }
#endif
float exposure = ObjectSrg::m_reflectionProbeData.m_useReflectionProbe ? pow(2.0, ObjectSrg::m_reflectionProbeData.m_exposure) : globalIblExposure; float exposure = ObjectSrg::m_reflectionProbeData.m_useReflectionProbe ? pow(2.0, ObjectSrg::m_reflectionProbeData.m_exposure) : globalIblExposure;
lightingData.specularLighting += (iblSpecular * exposure); lightingData.specularLighting += (iblSpecular * exposure);

@ -13,9 +13,6 @@
#include <Atom/Features/PBR/BackLighting.azsli> #include <Atom/Features/PBR/BackLighting.azsli>
#include <Atom/Features/PBR/Hammersley.azsli> #include <Atom/Features/PBR/Hammersley.azsli>
option bool o_area_light_validation = false;
//! Adjust the intensity of specular light based on the radius of the light source and roughness of the surface to approximate energy conservation. //! 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) float GetIntensityAdjustedByRadiusAndRoughness(float roughnessA, float radius, float distance2)
{ {

@ -403,6 +403,7 @@ void LtcQuadEvaluate(
float2 schlick = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoords).xy; float2 schlick = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoords).xy;
float3 specularRgb = specular * (schlick.x * surface.specularF0 + (1.0 - surface.specularF0) * schlick.y); float3 specularRgb = specular * (schlick.x * surface.specularF0 + (1.0 - surface.specularF0) * schlick.y);
#if ENABLE_CLEAR_COAT
if(o_clearCoat_feature_enabled) if(o_clearCoat_feature_enabled)
{ {
int vertexCountCc = LtcQuadTransformAndClip(surface.clearCoat.normal, lightingData.dirToCamera, p, polygon); int vertexCountCc = LtcQuadTransformAndClip(surface.clearCoat.normal, lightingData.dirToCamera, p, polygon);
@ -422,6 +423,7 @@ void LtcQuadEvaluate(
specularRgb = (specularRgb * (1.0 - F)) + (clearCoatSpecular * F); specularRgb = (specularRgb * (1.0 - F)) + (clearCoatSpecular * F);
} }
} }
#endif
diffuseOut = diffuse; diffuseOut = diffuse;
specularOut = specularRgb; specularOut = specularRgb;
@ -620,6 +622,7 @@ void LtcPolygonEvaluate(
float2 schlick = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoords).xy; float2 schlick = ltcAmpMatrix.Sample(PassSrg::LinearSampler, ltcCoords).xy;
float3 specularRgb = specular * ((schlick.x * surface.specularF0) + (1.0 - surface.specularF0) * schlick.y); float3 specularRgb = specular * ((schlick.x * surface.specularF0) + (1.0 - surface.specularF0) * schlick.y);
#if ENABLE_CLEAR_COAT
if(o_clearCoat_feature_enabled) if(o_clearCoat_feature_enabled)
{ {
// Rotate ltc matrix // Rotate ltc matrix
@ -660,6 +663,7 @@ void LtcPolygonEvaluate(
specularRgb = (specularRgb * (1.0 - F)) + (specularCc * F); specularRgb = (specularRgb * (1.0 - F)) + (specularCc * F);
} }
} }
#endif
diffuseOut = diffuse; diffuseOut = diffuse;
specularRgbOut = specularRgb; specularRgbOut = specularRgb;

@ -99,12 +99,14 @@ void ApplyPointLight(ViewSrg::PointLight light, Surface surface, inout LightingD
// Use backShadowRatio to carry thickness from shadow map for thick mode // Use backShadowRatio to carry thickness from shadow map for thick mode
backShadowRatio = 1.0 - litRatio; backShadowRatio = 1.0 - litRatio;
#if ENABLE_TRANSMISSION
if (o_transmission_mode == TransmissionMode::ThickObject) if (o_transmission_mode == TransmissionMode::ThickObject)
{ {
backShadowRatio = ProjectedShadow::GetThickness( backShadowRatio = ProjectedShadow::GetThickness(
shadowIndex, shadowIndex,
surface.position); surface.position);
} }
#endif
} }
// Diffuse contribution // Diffuse contribution
@ -177,15 +179,21 @@ void ApplyPointLights(Surface surface, inout LightingData lightingData)
uint currLightIndex = lightingData.tileIterator.GetValue(); uint currLightIndex = lightingData.tileIterator.GetValue();
lightingData.tileIterator.LoadAdvance(); lightingData.tileIterator.LoadAdvance();
#if ENABLE_SPHERE_LIGHTS
ViewSrg::PointLight light = ViewSrg::m_pointLights[currLightIndex]; ViewSrg::PointLight light = ViewSrg::m_pointLights[currLightIndex];
#if ENABLE_AREA_LIGHT_VALIDATION
if (o_area_light_validation) if (o_area_light_validation)
{ {
ValidatePointLight(light, surface, lightingData); ValidatePointLight(light, surface, lightingData);
} }
else else
#endif
{ {
ApplyPointLight(light, surface, lightingData); ApplyPointLight(light, surface, lightingData);
} }
#endif
} }
} }

@ -68,10 +68,12 @@ void ApplyPoylgonLight(ViewSrg::PolygonLight light, Surface surface, inout Light
void ApplyPolygonLights(Surface surface, inout LightingData lightingData) void ApplyPolygonLights(Surface surface, inout LightingData lightingData)
{ {
#if ENABLE_POLYGON_LTC_LIGHTS
for (uint currLightIndex = 0; currLightIndex < ViewSrg::m_polygonLightCount; ++currLightIndex) for (uint currLightIndex = 0; currLightIndex < ViewSrg::m_polygonLightCount; ++currLightIndex)
{ {
ViewSrg::PolygonLight light = ViewSrg::m_polygonLights[currLightIndex]; ViewSrg::PolygonLight light = ViewSrg::m_polygonLights[currLightIndex];
ApplyPoylgonLight(light, surface, lightingData); ApplyPoylgonLight(light, surface, lightingData);
} }
#endif
} }

@ -246,15 +246,21 @@ void ApplyQuadLights(Surface surface, inout LightingData lightingData)
uint currLightIndex = lightingData.tileIterator.GetValue(); uint currLightIndex = lightingData.tileIterator.GetValue();
lightingData.tileIterator.LoadAdvance(); lightingData.tileIterator.LoadAdvance();
#if ENABLE_QUAD_LIGHTS
ViewSrg::QuadLight light = ViewSrg::m_quadLights[currLightIndex]; ViewSrg::QuadLight light = ViewSrg::m_quadLights[currLightIndex];
#if ENABLE_AREA_LIGHT_VALIDATION
if (o_area_light_validation) if (o_area_light_validation)
{ {
ValidateQuadLight(light, surface, lightingData); ValidateQuadLight(light, surface, lightingData);
} }
else else
#endif
{ {
ApplyQuadLight(light, surface, lightingData); ApplyQuadLight(light, surface, lightingData);
} }
#endif
} }
} }

@ -8,6 +8,8 @@
#pragma once #pragma once
#if ENABLE_CLEAR_COAT
class ClearCoatSurfaceData class ClearCoatSurfaceData
{ {
float factor; //!< clear coat strength factor float factor; //!< clear coat strength factor
@ -23,3 +25,5 @@ void ClearCoatSurfaceData::InitializeToZero()
roughness = 0.0f; roughness = 0.0f;
normal = float3(0.0f, 0.0f, 0.0f); normal = float3(0.0f, 0.0f, 0.0f);
} }
#endif

@ -15,8 +15,10 @@
class Surface class Surface
{ {
#if ENABLE_CLEAR_COAT
ClearCoatSurfaceData clearCoat; ClearCoatSurfaceData clearCoat;
TransmissionSurfaceData transmission; // This is not actually used for Standard PBR, but must be present for common lighting code to compile #endif
// ------- BasePbrSurfaceData ------- // ------- BasePbrSurfaceData -------
@ -37,7 +39,6 @@ class Surface
//! Sets albedo and specularF0 using metallic workflow //! Sets albedo and specularF0 using metallic workflow
void SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic); void SetAlbedoAndSpecularF0(float3 baseColor, float specularF0Factor, float metallic);
}; };
// Specular Anti-Aliasing technique from this paper: // Specular Anti-Aliasing technique from this paper:

@ -8,6 +8,8 @@
#pragma once #pragma once
#if ENABLE_TRANSMISSION
class TransmissionSurfaceData class TransmissionSurfaceData
{ {
float3 tint; float3 tint;
@ -23,3 +25,5 @@ void TransmissionSurfaceData::InitializeToZero()
thickness = 0.0f; thickness = 0.0f;
transmissionParams = float4(0.0f, 0.0f, 0.0f, 0.0f); transmissionParams = float4(0.0f, 0.0f, 0.0f, 0.0f);
} }
#endif

@ -13,10 +13,23 @@
#ifdef QUALITY_LOW_END #ifdef QUALITY_LOW_END
// Unifies the forward output into a single lighting buffer instead of splitting it into a GBuffer // Unifies the forward output into a single lighting buffer instead of splitting it into a GBuffer
#ifndef UNIFIED_FORWARD_OUTPUT
#define UNIFIED_FORWARD_OUTPUT 1 #define UNIFIED_FORWARD_OUTPUT 1
#endif
// Forces IBL lighting to be executed in the forward pass instead of subsequent refleciton passes // Forces IBL lighting to be executed in the forward pass instead of subsequent refleciton passes
#ifndef FORCE_IBL_IN_FORWARD_PASS
#define FORCE_IBL_IN_FORWARD_PASS 1 #define FORCE_IBL_IN_FORWARD_PASS 1
#endif
#endif // Forces removal of area light validation code
#ifndef ENABLE_AREA_LIGHT_VALIDATION
#define ENABLE_AREA_LIGHT_VALIDATION 0
#endif
// Uncomment to disable all area light calcuation
// #ifndef ENABLE_AREA_LIGHTS
// #define ENABLE_AREA_LIGHTS 0
// #endif
#endif

@ -10,6 +10,12 @@ set(FILES
Materials/Special/ShadowCatcher.azsl Materials/Special/ShadowCatcher.azsl
Materials/Special/ShadowCatcher.materialtype Materials/Special/ShadowCatcher.materialtype
Materials/Special/ShadowCatcher.shader Materials/Special/ShadowCatcher.shader
Materials/Types/BasePBR.materialtype
Materials/Types/BasePBR_Common.azsli
Materials/Types/BasePBR_ForwardPass.azsl
Materials/Types/BasePBR_ForwardPass.shader
Materials/Types/BasePBR_LowEndForward.azsl
Materials/Types/BasePBR_LowEndForward.shader
Materials/Types/EnhancedPBR.materialtype Materials/Types/EnhancedPBR.materialtype
Materials/Types/EnhancedPBR_Common.azsli Materials/Types/EnhancedPBR_Common.azsli
Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl Materials/Types/EnhancedPBR_DepthPass_WithPS.azsl
@ -258,6 +264,7 @@ set(FILES
ShaderLib/Atom/Features/PBR/Hammersley.azsli ShaderLib/Atom/Features/PBR/Hammersley.azsli
ShaderLib/Atom/Features/PBR/LightingOptions.azsli ShaderLib/Atom/Features/PBR/LightingOptions.azsli
ShaderLib/Atom/Features/PBR/LightingUtils.azsli ShaderLib/Atom/Features/PBR/LightingUtils.azsli
ShaderLib/Atom/Features/PBR/Lighting/BaseLighting.azsli
ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli
ShaderLib/Atom/Features/PBR/Lighting/EnhancedLighting.azsli ShaderLib/Atom/Features/PBR/Lighting/EnhancedLighting.azsli
ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli ShaderLib/Atom/Features/PBR/Lighting/LightingData.azsli

@ -179,9 +179,8 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN)
const float specularF0Factor = 0.5f; const float specularF0Factor = 0.5f;
surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic); surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
// Clear Coat, Transmission // Clear Coat
surface.clearCoat.InitializeToZero(); surface.clearCoat.InitializeToZero();
surface.transmission.InitializeToZero();
// ------- LightingData ------- // ------- LightingData -------
@ -213,7 +212,7 @@ ForwardPassOutput AutoBrick_ForwardPassPS(VSOutput IN)
ApplyIBL(surface, lightingData); ApplyIBL(surface, lightingData);
// Finalize Lighting // Finalize Lighting
lightingData.FinalizeLighting(surface.transmission.tint); lightingData.FinalizeLighting();
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);

@ -71,9 +71,8 @@ ForwardPassOutput MinimalPBR_MainPassPS(VSOutput IN)
const float specularF0Factor = 0.5f; const float specularF0Factor = 0.5f;
surface.SetAlbedoAndSpecularF0(MinimalPBRSrg::m_baseColor, specularF0Factor, MinimalPBRSrg::m_metallic); surface.SetAlbedoAndSpecularF0(MinimalPBRSrg::m_baseColor, specularF0Factor, MinimalPBRSrg::m_metallic);
// Clear Coat, Transmission // Clear Coat
surface.clearCoat.InitializeToZero(); surface.clearCoat.InitializeToZero();
surface.transmission.InitializeToZero();
// ------- LightingData ------- // ------- LightingData -------
@ -104,7 +103,7 @@ ForwardPassOutput MinimalPBR_MainPassPS(VSOutput IN)
ApplyIBL(surface, lightingData); ApplyIBL(surface, lightingData);
// Finalize Lighting // Finalize Lighting
lightingData.FinalizeLighting(surface.transmission.tint); lightingData.FinalizeLighting();
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);

@ -177,9 +177,8 @@ ForwardPassOutput TerrainPBR_MainPassPS(VSOutput IN)
surface.CalculateRoughnessA(); surface.CalculateRoughnessA();
} }
// Clear Coat, Transmission (Not used for terrain) // Clear Coat
surface.clearCoat.InitializeToZero(); surface.clearCoat.InitializeToZero();
surface.transmission.InitializeToZero();
// ------- LightingData ------- // ------- LightingData -------
@ -211,7 +210,7 @@ ForwardPassOutput TerrainPBR_MainPassPS(VSOutput IN)
ApplyIBL(surface, lightingData); ApplyIBL(surface, lightingData);
// Finalize Lighting // Finalize Lighting
lightingData.FinalizeLighting(surface.transmission.tint); lightingData.FinalizeLighting();
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);

Loading…
Cancel
Save