Removed .orig files that I accidentally added.
This commit is contained in:
-3126
File diff suppressed because it is too large
Load Diff
-401
@@ -1,401 +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
|
||||
|
||||
#include <Atom/Features/SrgSemantics.azsli>
|
||||
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
|
||||
#include <Atom/Features/PBR/LightingOptions.azsli>
|
||||
|
||||
#include "MaterialInputs/BaseColorInput.azsli"
|
||||
#include "MaterialInputs/RoughnessInput.azsli"
|
||||
#include "MaterialInputs/MetallicInput.azsli"
|
||||
#include "MaterialInputs/SpecularInput.azsli"
|
||||
#include "MaterialInputs/NormalInput.azsli"
|
||||
#include "MaterialInputs/ClearCoatInput.azsli"
|
||||
#include "MaterialInputs/OcclusionInput.azsli"
|
||||
#include "MaterialInputs/EmissiveInput.azsli"
|
||||
#include "MaterialInputs/ParallaxInput.azsli"
|
||||
#include "MaterialInputs/UvSetCount.azsli"
|
||||
|
||||
// ------ ShaderResourceGroup ----------------------------------------
|
||||
|
||||
#define DEFINE_LAYER_SRG_INPUTS(prefix) \
|
||||
COMMON_SRG_INPUTS_BASE_COLOR(prefix) \
|
||||
COMMON_SRG_INPUTS_ROUGHNESS(prefix) \
|
||||
COMMON_SRG_INPUTS_METALLIC(prefix) \
|
||||
COMMON_SRG_INPUTS_SPECULAR_F0(prefix) \
|
||||
COMMON_SRG_INPUTS_NORMAL(prefix) \
|
||||
COMMON_SRG_INPUTS_CLEAR_COAT(prefix) \
|
||||
COMMON_SRG_INPUTS_OCCLUSION(prefix) \
|
||||
COMMON_SRG_INPUTS_EMISSIVE(prefix) \
|
||||
COMMON_SRG_INPUTS_PARALLAX(prefix)
|
||||
|
||||
ShaderResourceGroup MaterialSrg : SRG_PerMaterial
|
||||
{
|
||||
Texture2D m_blendMaskTexture;
|
||||
uint m_blendMaskUvIndex;
|
||||
|
||||
// Auto-generate material SRG fields for common inputs for each layer
|
||||
DEFINE_LAYER_SRG_INPUTS(m_layer1_)
|
||||
DEFINE_LAYER_SRG_INPUTS(m_layer2_)
|
||||
DEFINE_LAYER_SRG_INPUTS(m_layer3_)
|
||||
|
||||
float3x3 m_layer1_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_layer2_m_uvMatrix;
|
||||
float4 m_pad2; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
|
||||
|
||||
float3x3 m_layer3_m_uvMatrix;
|
||||
float4 m_pad3; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
|
||||
|
||||
uint m_parallaxUvIndex;
|
||||
|
||||
// These are used to limit the heightmap intersection search range to the narrowest band possible, to give the best quality result.
|
||||
float m_displacementMin; // The lowest displacement value possible from all layers combined (negative values are below the surface)
|
||||
float m_displacementMax; // The highest displacement value possible from all layers combined (negative values are below the surface)
|
||||
|
||||
float3x3 m_uvMatrix;
|
||||
float4 m_pad4; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
|
||||
float3x3 m_uvMatrixInverse;
|
||||
float4 m_pad5; // [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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// ------ Shader Options ----------------------------------------
|
||||
|
||||
<<<<<<< HEAD
|
||||
option bool o_layer2_enabled;
|
||||
option bool o_layer3_enabled;
|
||||
|
||||
enum class DebugDrawMode { None, BlendSource, DepthMaps };
|
||||
=======
|
||||
enum class DebugDrawMode { None, BlendWeights, DisplacementMaps };
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
option DebugDrawMode o_debugDrawMode;
|
||||
|
||||
enum class LayerBlendSource { BlendMask, VertexColors, Displacement, Fallback };
|
||||
option LayerBlendSource o_layerBlendSource;
|
||||
|
||||
// Indicates whether the vertex input struct's "m_optional_blendMask" is bound. If false, it is not safe to read from m_optional_blendMask.
|
||||
// This option gets set automatically by the system at runtime; there is a soft naming convention that associates it with m_optional_blendMask.
|
||||
// (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention).
|
||||
// [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream.
|
||||
option bool o_blendMask_isBound;
|
||||
|
||||
// ------ Blend Utilities ----------------------------------------
|
||||
|
||||
<<<<<<< HEAD
|
||||
// This is mainly used to pass extra data to the GetDepth callback function during the parallax depth search.
|
||||
// But since we have it, we use it in some other functions as well rather than passing it around.
|
||||
static float3 s_blendMaskFromVertexStream;
|
||||
|
||||
//! Returns the BlendMaskSource that will actually be used when rendering (not necessarily the same BlendMaskSource specified by the user)
|
||||
BlendMaskSource GetFinalBlendMaskSource()
|
||||
=======
|
||||
//! Returns the LayerBlendSource that will actually be used when rendering (not necessarily the same LayerBlendSource specified by the user)
|
||||
LayerBlendSource GetFinalLayerBlendSource()
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
{
|
||||
if(o_layerBlendSource == LayerBlendSource::BlendMask)
|
||||
{
|
||||
return LayerBlendSource::BlendMask;
|
||||
}
|
||||
else if(o_layerBlendSource == LayerBlendSource::VertexColors)
|
||||
{
|
||||
if(o_blendMask_isBound)
|
||||
{
|
||||
return LayerBlendSource::VertexColors;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LayerBlendSource::BlendMask;
|
||||
}
|
||||
}
|
||||
else if(o_layerBlendSource == LayerBlendSource::Displacement)
|
||||
{
|
||||
return LayerBlendSource::Displacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LayerBlendSource::Fallback;
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
//! Return the raw blend source values directly from the blend mask or vertex colors, depending on the available data and configuration.
|
||||
//! layer1 is an implicit base layer
|
||||
//! layer2 is weighted by r
|
||||
//! layer3 is weighted by g
|
||||
//! b is reserved for perhaps a dedicated puddle layer
|
||||
float3 GetBlendSourceValues(float2 uv)
|
||||
{
|
||||
float3 blendSourceValues = float3(0,0,0);
|
||||
|
||||
if(o_layer2_enabled || o_layer3_enabled)
|
||||
{
|
||||
switch(GetFinalBlendMaskSource())
|
||||
{
|
||||
case BlendMaskSource::TextureMap:
|
||||
blendSourceValues = MaterialSrg::m_blendMaskTexture.Sample(MaterialSrg::m_sampler, uv).rgb;
|
||||
break;
|
||||
case BlendMaskSource::VertexColors:
|
||||
blendSourceValues = s_blendMaskFromVertexStream;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!o_layer2_enabled)
|
||||
{
|
||||
blendSourceValues.r = 0.0;
|
||||
}
|
||||
|
||||
if(!o_layer3_enabled)
|
||||
{
|
||||
blendSourceValues.g = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
return blendSourceValues;
|
||||
}
|
||||
|
||||
//! Return the final blend mask values to be used for rendering, based on the available data and configuration.
|
||||
//! @return The blend weights for each layer.
|
||||
//! Even though layer1 not explicitly specified in the blend source data, it is explicitly included with the returned values.
|
||||
//! layer1 = r
|
||||
//! layer2 = g
|
||||
//! layer3 = b
|
||||
float3 GetBlendWeights(float2 uv)
|
||||
{
|
||||
float3 blendWeights;
|
||||
|
||||
if(o_layer2_enabled || o_layer3_enabled)
|
||||
{
|
||||
float3 blendSourceValues = GetBlendSourceValues(uv);
|
||||
|
||||
// Calculate blend weights such that multiplying and adding them with layer data is equivalent
|
||||
// to lerping between each layer.
|
||||
// final = lerp(final, layer1, blendWeights.r)
|
||||
// final = lerp(final, layer2, blendWeights.g)
|
||||
// final = lerp(final, layer3, blendWeights.b)
|
||||
|
||||
blendWeights.b = blendSourceValues.g;
|
||||
blendWeights.g = (1.0 - blendSourceValues.g) * blendSourceValues.r;
|
||||
blendWeights.r = (1.0 - blendSourceValues.g) * (1.0 - blendSourceValues.r);
|
||||
}
|
||||
else
|
||||
{
|
||||
blendWeights = float3(1,0,0);
|
||||
}
|
||||
|
||||
return blendWeights;
|
||||
}
|
||||
|
||||
float BlendLayers(float layer1, float layer2, float layer3, float3 blendWeights)
|
||||
{
|
||||
return dot(float3(layer1, layer2, layer3), blendWeights);
|
||||
}
|
||||
float2 BlendLayers(float2 layer1, float2 layer2, float2 layer3, float3 blendWeights)
|
||||
{
|
||||
return layer1 * blendWeights.r + layer2 * blendWeights.g + layer3 * blendWeights.b;
|
||||
}
|
||||
float3 BlendLayers(float3 layer1, float3 layer2, float3 layer3, float3 blendWeights)
|
||||
{
|
||||
return layer1 * blendWeights.r + layer2 * blendWeights.g + layer3 * blendWeights.b;
|
||||
=======
|
||||
//! Returns blend weights given the depth values for each layer
|
||||
float3 GetBlendWeightsFromLayerDepthValues(float3 layerDepthValues)
|
||||
{
|
||||
float highestPoint = min(layerDepthValues.x, min(layerDepthValues.y, layerDepthValues.z));
|
||||
float3 blendWeights = float3(layerDepthValues.x <= highestPoint ? 1.0 : 0.0,
|
||||
layerDepthValues.y <= highestPoint ? 1.0 : 0.0,
|
||||
layerDepthValues.z <= highestPoint ? 1.0 : 0.0);
|
||||
return blendWeights;
|
||||
}
|
||||
|
||||
float3 GetLayerDepthValues(float2 uv, float2 uv_ddx, float2 uv_ddy);
|
||||
|
||||
//! Return the final blend mask values to be used for rendering, based on the available data and configuration.
|
||||
//! @param vertexBlendWeights - the blend weights that came from the vertex input, relevant for LayerBlendSource::VertexColors
|
||||
//! @param layerDepthValues - the per-layer depth values as provided by GetLayerDepthValues()
|
||||
float3 GetBlendWeights(float2 uv, float3 vertexBlendWeights, float3 layerDepthValues)
|
||||
{
|
||||
float3 blendWeightValues;
|
||||
|
||||
switch(GetFinalLayerBlendSource())
|
||||
{
|
||||
case LayerBlendSource::BlendMask:
|
||||
blendWeightValues = MaterialSrg::m_blendMaskTexture.Sample(MaterialSrg::m_sampler, uv).rgb;
|
||||
break;
|
||||
case LayerBlendSource::VertexColors:
|
||||
blendWeightValues = vertexBlendWeights;
|
||||
break;
|
||||
case LayerBlendSource::Displacement:
|
||||
blendWeightValues = GetBlendWeightsFromLayerDepthValues(layerDepthValues);
|
||||
break;
|
||||
case LayerBlendSource::Fallback:
|
||||
blendWeightValues = float3(1,1,1);
|
||||
break;
|
||||
}
|
||||
|
||||
blendWeightValues = blendWeightValues / (blendWeightValues.r + blendWeightValues.g + blendWeightValues.b);
|
||||
|
||||
return blendWeightValues;
|
||||
}
|
||||
|
||||
//! Return the final blend mask values to be used for rendering, based on the available data and configuration.
|
||||
//! Note this will sample the displacement maps in the case of LayerBlendSource::Displacement. If you have already
|
||||
//! called GetLayerDepthValues(), use the GetBlendWeights() overlad that takes layerDepthValues instead.
|
||||
float3 GetBlendWeights(float2 uv, float3 vertexBlendWeights)
|
||||
{
|
||||
float3 layerDepthValues = float3(0,0,0);
|
||||
|
||||
if(GetFinalLayerBlendSource() == LayerBlendSource::Displacement)
|
||||
{
|
||||
layerDepthValues = GetLayerDepthValues(uv, ddx_fine(uv), ddy_fine(uv));
|
||||
}
|
||||
|
||||
return GetBlendWeights(uv, vertexBlendWeights, layerDepthValues);
|
||||
}
|
||||
|
||||
float BlendLayers(float layer1, float layer2, float layer3, float3 blendWeightValues)
|
||||
{
|
||||
return dot(float3(layer1, layer2, layer3), blendWeightValues);
|
||||
}
|
||||
float2 BlendLayers(float2 layer1, float2 layer2, float2 layer3, float3 blendWeightValues)
|
||||
{
|
||||
return layer1 * blendWeightValues.r + layer2 * blendWeightValues.g + layer3 * blendWeightValues.b;
|
||||
}
|
||||
float3 BlendLayers(float3 layer1, float3 layer2, float3 layer3, float3 blendWeightValues)
|
||||
{
|
||||
return layer1 * blendWeightValues.r + layer2 * blendWeightValues.g + layer3 * blendWeightValues.b;
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
}
|
||||
|
||||
// ------ Parallax Utilities ----------------------------------------
|
||||
|
||||
bool ShouldHandleParallax()
|
||||
{
|
||||
// Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scattering is enabled.
|
||||
// Also, all the debug draw modes avoid parallax (they early-return before parallax code actually) so you can see exactly where the various maps appear on the surface UV space.
|
||||
return !o_enableSubsurfaceScattering && o_parallax_feature_enabled && o_debugDrawMode == DebugDrawMode::None;
|
||||
}
|
||||
|
||||
bool ShouldHandleParallaxInDepthShaders()
|
||||
{
|
||||
// The depth pass shaders need to calculate parallax when the result could affect the depth buffer (or when
|
||||
// parallax could affect texel clipping but we don't have alpha/clipping support in multilayer PBR).
|
||||
return ShouldHandleParallax() && o_parallax_enablePixelDepthOffset;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Callback function for ParallaxMapping.azsli
|
||||
DepthResult GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy)
|
||||
=======
|
||||
// These static values are used to pass extra data to the GetDepth callback function during the parallax depth search.
|
||||
static float3 s_blendWeightsFromVertexStream;
|
||||
|
||||
//! Setup static variables that are needed by the GetDepth callback function
|
||||
//! @param vertexBlendWeights - the blend weights from the vertex input stream.
|
||||
void GetDepth_Setup(float3 vertexBlendWeights)
|
||||
{
|
||||
s_blendWeightsFromVertexStream = vertexBlendWeights;
|
||||
}
|
||||
|
||||
//! Returns the depth values for each layer
|
||||
float3 GetLayerDepthValues(float2 uv, float2 uv_ddx, float2 uv_ddy)
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
{
|
||||
float3 layerDepthValues = float3(0,0,0);
|
||||
|
||||
if(o_layer1_o_useDepthMap)
|
||||
{
|
||||
float2 layerUv = uv;
|
||||
if(MaterialSrg::m_parallaxUvIndex == 0)
|
||||
{
|
||||
layerUv = mul(MaterialSrg::m_layer1_m_uvMatrix, float3(uv, 1.0)).xy;
|
||||
}
|
||||
|
||||
layerDepthValues.r = SampleDepthOrHeightMap(MaterialSrg::m_layer1_m_depthInverted, MaterialSrg::m_layer1_m_depthMap, MaterialSrg::m_sampler, layerUv, uv_ddx, uv_ddy).m_depth;
|
||||
layerDepthValues.r *= MaterialSrg::m_layer1_m_depthFactor;
|
||||
layerDepthValues.r -= MaterialSrg::m_layer1_m_depthOffset;
|
||||
}
|
||||
|
||||
if(o_layer2_enabled && o_layer2_o_useDepthMap)
|
||||
{
|
||||
float2 layerUv = uv;
|
||||
if(MaterialSrg::m_parallaxUvIndex == 0)
|
||||
{
|
||||
layerUv = mul(MaterialSrg::m_layer2_m_uvMatrix, float3(uv, 1.0)).xy;
|
||||
}
|
||||
|
||||
layerDepthValues.g = SampleDepthOrHeightMap(MaterialSrg::m_layer2_m_depthInverted, MaterialSrg::m_layer2_m_depthMap, MaterialSrg::m_sampler, layerUv, uv_ddx, uv_ddy).m_depth;
|
||||
layerDepthValues.g *= MaterialSrg::m_layer2_m_depthFactor;
|
||||
layerDepthValues.g -= MaterialSrg::m_layer2_m_depthOffset;
|
||||
}
|
||||
|
||||
if(o_layer3_enabled && o_layer3_o_useDepthMap)
|
||||
{
|
||||
float2 layerUv = uv;
|
||||
if(MaterialSrg::m_parallaxUvIndex == 0)
|
||||
{
|
||||
layerUv = mul(MaterialSrg::m_layer3_m_uvMatrix, float3(uv, 1.0)).xy;
|
||||
}
|
||||
|
||||
layerDepthValues.b = SampleDepthOrHeightMap(MaterialSrg::m_layer3_m_depthInverted, MaterialSrg::m_layer3_m_depthMap, MaterialSrg::m_sampler, layerUv, uv_ddx, uv_ddy).m_depth;
|
||||
layerDepthValues.b *= MaterialSrg::m_layer3_m_depthFactor;
|
||||
layerDepthValues.b -= MaterialSrg::m_layer3_m_depthOffset;
|
||||
}
|
||||
|
||||
return layerDepthValues;
|
||||
}
|
||||
|
||||
//! Callback function for ParallaxMapping.azsli
|
||||
DepthResult GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy)
|
||||
{
|
||||
float3 layerDepthValues = GetLayerDepthValues(uv, uv_ddx, uv_ddy);
|
||||
|
||||
// Note, when the blend source is LayerBlendSource::VertexColors, parallax will not be able to blend correctly between layers. It will end up using the same blend mask values
|
||||
// for every UV position when searching for the intersection. This leads to smearing artifacts at the transition point, but these won't be so noticeable as long as
|
||||
// you have a small depth factor relative to the size of the blend transition.
|
||||
<<<<<<< HEAD
|
||||
float3 blendWeights = GetBlendWeights(uv);
|
||||
|
||||
float depth = BlendLayers(layerDepthValues.r, layerDepthValues.g, layerDepthValues.b, blendWeights);
|
||||
=======
|
||||
float3 blendWeightValues = GetBlendWeights(uv, s_blendWeightsFromVertexStream, layerDepthValues);
|
||||
|
||||
float depth = BlendLayers(layerDepthValues.r, layerDepthValues.g, layerDepthValues.b, blendWeightValues);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
return DepthResultAbsolute(depth);
|
||||
}
|
||||
-132
@@ -1,132 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/ParallaxMapping.azsli>
|
||||
#include <Atom/Features/MatrixUtility.azsli>
|
||||
|
||||
#include "MaterialInputs/ParallaxInput.azsli"
|
||||
|
||||
|
||||
#include "MaterialInputs/ParallaxInput.azsli"
|
||||
COMMON_OPTIONS_PARALLAX(o_layer1_)
|
||||
COMMON_OPTIONS_PARALLAX(o_layer2_)
|
||||
COMMON_OPTIONS_PARALLAX(o_layer3_)
|
||||
|
||||
#include "./StandardMultilayerPBR_Common.azsli"
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float3 m_position : POSITION;
|
||||
float2 m_uv0 : UV0;
|
||||
float2 m_uv1 : UV1;
|
||||
|
||||
// only used for parallax depth calculation
|
||||
float3 m_normal : NORMAL;
|
||||
float4 m_tangent : TANGENT;
|
||||
float3 m_bitangent : BITANGENT;
|
||||
|
||||
// This gets set automatically by the system at runtime only if it's available.
|
||||
// There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available.
|
||||
// (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention).
|
||||
// [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream.
|
||||
float4 m_optional_blendMask : COLOR0;
|
||||
};
|
||||
|
||||
struct VSDepthOutput
|
||||
{
|
||||
float4 m_position : SV_Position;
|
||||
float2 m_uv[UvSetCount] : UV1;
|
||||
|
||||
// only used for parallax depth calculation
|
||||
float3 m_normal : NORMAL;
|
||||
float3 m_tangent : TANGENT;
|
||||
float3 m_bitangent : BITANGENT;
|
||||
float3 m_worldPosition : UV0;
|
||||
float3 m_blendWeights : UV3;
|
||||
};
|
||||
|
||||
VSDepthOutput MainVS(VSInput IN)
|
||||
{
|
||||
VSDepthOutput OUT;
|
||||
|
||||
float4x4 objectToWorld = ObjectSrg::GetWorldMatrix();
|
||||
float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0));
|
||||
|
||||
OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition);
|
||||
|
||||
// By design, only UV0 is allowed to apply transforms.
|
||||
// Note there are additional UV transforms that happen for each layer, but we defer that step to the pixel shader to avoid bloating the vertex output buffer.
|
||||
OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy;
|
||||
OUT.m_uv[1] = IN.m_uv1;
|
||||
|
||||
if(ShouldHandleParallaxInDepthShaders())
|
||||
{
|
||||
OUT.m_worldPosition = worldPosition.xyz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if(o_blendMask_isBound)
|
||||
{
|
||||
OUT.m_blendWeights = IN.m_optional_blendMask.rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
OUT.m_blendWeights = float3(1,1,1);
|
||||
}
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
struct PSDepthOutput
|
||||
{
|
||||
float m_depth : SV_Depth;
|
||||
};
|
||||
|
||||
PSDepthOutput MainPS(VSDepthOutput IN, bool isFrontFace : SV_IsFrontFace)
|
||||
{
|
||||
PSDepthOutput OUT;
|
||||
|
||||
OUT.m_depth = IN.m_position.z;
|
||||
|
||||
if(ShouldHandleParallaxInDepthShaders())
|
||||
{
|
||||
// We support two UV streams, but only a single stream of tangent/bitangent. So for UV[1+] we generated the tangent/bitangent in screen-space.
|
||||
float3 tangents[UvSetCount] = { IN.m_tangent.xyz, float3(0, 0, 0) };
|
||||
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, float3(0, 0, 0) };
|
||||
PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents, 1);
|
||||
|
||||
<<<<<<< HEAD
|
||||
s_blendMaskFromVertexStream = IN.m_blendMask;
|
||||
=======
|
||||
GetDepth_Setup(IN.m_blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
|
||||
float depth;
|
||||
|
||||
float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3();
|
||||
|
||||
float parallaxOverallOffset = MaterialSrg::m_displacementMax;
|
||||
float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin;
|
||||
GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset,
|
||||
ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse,
|
||||
IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depth);
|
||||
|
||||
OUT.m_depth = depth;
|
||||
}
|
||||
|
||||
return OUT;
|
||||
}
|
||||
@@ -130,3 +130,4 @@ function ProcessEditor(context)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
-710
@@ -1,710 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
// 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 ----------
|
||||
|
||||
#include "MaterialInputs/BaseColorInput.azsli"
|
||||
#include "MaterialInputs/RoughnessInput.azsli"
|
||||
#include "MaterialInputs/MetallicInput.azsli"
|
||||
#include "MaterialInputs/SpecularInput.azsli"
|
||||
#include "MaterialInputs/NormalInput.azsli"
|
||||
#include "MaterialInputs/ClearCoatInput.azsli"
|
||||
#include "MaterialInputs/OcclusionInput.azsli"
|
||||
#include "MaterialInputs/EmissiveInput.azsli"
|
||||
#include "MaterialInputs/ParallaxInput.azsli"
|
||||
|
||||
#define DEFINE_LAYER_OPTIONS(prefix) \
|
||||
COMMON_OPTIONS_BASE_COLOR(prefix) \
|
||||
COMMON_OPTIONS_ROUGHNESS(prefix) \
|
||||
COMMON_OPTIONS_METALLIC(prefix) \
|
||||
COMMON_OPTIONS_SPECULAR_F0(prefix) \
|
||||
COMMON_OPTIONS_NORMAL(prefix) \
|
||||
COMMON_OPTIONS_CLEAR_COAT(prefix) \
|
||||
COMMON_OPTIONS_OCCLUSION(prefix) \
|
||||
COMMON_OPTIONS_EMISSIVE(prefix) \
|
||||
COMMON_OPTIONS_PARALLAX(prefix)
|
||||
|
||||
DEFINE_LAYER_OPTIONS(o_layer1_)
|
||||
DEFINE_LAYER_OPTIONS(o_layer2_)
|
||||
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)...
|
||||
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;
|
||||
|
||||
// This gets set automatically by the system at runtime only if it's available.
|
||||
// There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available.
|
||||
// (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention).
|
||||
// [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream.
|
||||
float4 m_optional_blendMask : COLOR0;
|
||||
};
|
||||
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
// Base fields (required by the template azsli file)...
|
||||
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;
|
||||
|
||||
float3 m_blendWeights : UV7;
|
||||
};
|
||||
|
||||
#include <Atom/Features/Vertex/VertexHelper.azsli>
|
||||
|
||||
VSOutput 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.
|
||||
// Note there are additional UV transforms that happen for each layer, but we defer that step to the pixel shader to avoid bloating the vertex output buffer.
|
||||
OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy;
|
||||
OUT.m_uv[1] = IN.m_uv1;
|
||||
|
||||
if(o_blendMask_isBound)
|
||||
{
|
||||
OUT.m_blendWeights = IN.m_optional_blendMask.rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
OUT.m_blendWeights = float3(1,1,1);
|
||||
}
|
||||
|
||||
// Shadow coords will be calculated in the pixel shader in this case
|
||||
bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset;
|
||||
VertexHelper(IN, OUT, worldPosition, skipShadowCoords);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
//! Collects all the raw Standard material inputs for a single layer. See ProcessStandardMaterialInputs().
|
||||
struct StandardMaterialInputs
|
||||
{
|
||||
COMMON_SRG_INPUTS_BASE_COLOR()
|
||||
COMMON_SRG_INPUTS_ROUGHNESS()
|
||||
COMMON_SRG_INPUTS_METALLIC()
|
||||
COMMON_SRG_INPUTS_SPECULAR_F0()
|
||||
COMMON_SRG_INPUTS_NORMAL()
|
||||
COMMON_SRG_INPUTS_CLEAR_COAT()
|
||||
COMMON_SRG_INPUTS_OCCLUSION()
|
||||
COMMON_SRG_INPUTS_EMISSIVE()
|
||||
// Note parallax is omitted here because that requires special handling.
|
||||
|
||||
bool m_normal_useTexture;
|
||||
bool m_baseColor_useTexture;
|
||||
bool m_metallic_useTexture;
|
||||
bool m_specularF0_useTexture;
|
||||
bool m_roughness_useTexture;
|
||||
bool m_emissiveEnabled;
|
||||
bool m_emissive_useTexture;
|
||||
bool m_diffuseOcclusion_useTexture;
|
||||
bool m_specularOcclusion_useTexture;
|
||||
bool m_clearCoatEnabled;
|
||||
bool m_clearCoat_factor_useTexture;
|
||||
bool m_clearCoat_roughness_useTexture;
|
||||
bool m_clearCoat_normal_useTexture;
|
||||
|
||||
TextureBlendMode m_baseColorTextureBlendMode;
|
||||
|
||||
float2 m_vertexUv[UvSetCount];
|
||||
float3x3 m_uvMatrix;
|
||||
float m_normal;
|
||||
float3 m_tangents[UvSetCount];
|
||||
float3 m_bitangents[UvSetCount];
|
||||
|
||||
sampler m_sampler;
|
||||
|
||||
bool m_isFrontFace;
|
||||
};
|
||||
|
||||
//! Holds the final processed material inputs, after all flags have been checked, textures have been sampled, factors have been applied, etc.
|
||||
//! This data is ready to be copied into a Surface and/or LightingData struct for the lighting system to consume.
|
||||
class ProcessedMaterialInputs
|
||||
{
|
||||
float3 m_normalTS; //!< Normal in tangent-space
|
||||
float3 m_baseColor;
|
||||
float3 m_specularF0Factor;
|
||||
float m_metallic;
|
||||
float m_roughness;
|
||||
float3 m_emissiveLighting;
|
||||
float m_diffuseAmbientOcclusion;
|
||||
float m_specularOcclusion;
|
||||
ClearCoatSurfaceData m_clearCoat;
|
||||
|
||||
void InitializeToZero()
|
||||
{
|
||||
m_normalTS = float3(0,0,0);
|
||||
m_baseColor = float3(0,0,0);
|
||||
m_specularF0Factor = float3(0,0,0);
|
||||
m_metallic = 0.0f;
|
||||
m_roughness = 0.0f;
|
||||
m_emissiveLighting = float3(0,0,0);
|
||||
m_diffuseAmbientOcclusion = 0;
|
||||
m_specularOcclusion = 0;
|
||||
m_clearCoat.InitializeToZero();
|
||||
}
|
||||
};
|
||||
|
||||
//! Processes the set of Standard material inputs for a single layer.
|
||||
//! The FILL_STANDARD_MATERIAL_INPUTS() macro below can be used to fill the StandardMaterialInputs struct.
|
||||
ProcessedMaterialInputs ProcessStandardMaterialInputs(StandardMaterialInputs inputs)
|
||||
{
|
||||
ProcessedMaterialInputs result;
|
||||
|
||||
float2 transformedUv[UvSetCount];
|
||||
transformedUv[0] = mul(inputs.m_uvMatrix, float3(inputs.m_vertexUv[0], 1.0)).xy;
|
||||
transformedUv[1] = inputs.m_vertexUv[1];
|
||||
|
||||
float3x3 normalUvMatrix = inputs.m_normalMapUvIndex == 0 ? inputs.m_uvMatrix : CreateIdentity3x3();
|
||||
result.m_normalTS = GetNormalInputTS(inputs.m_normalMap, inputs.m_sampler, transformedUv[inputs.m_normalMapUvIndex], inputs.m_flipNormalX, inputs.m_flipNormalY, normalUvMatrix, inputs.m_normal_useTexture, inputs.m_normalFactor);
|
||||
|
||||
float3 sampledBaseColor = GetBaseColorInput(inputs.m_baseColorMap, inputs.m_sampler, transformedUv[inputs.m_baseColorMapUvIndex], inputs.m_baseColor.rgb, inputs.m_baseColor_useTexture);
|
||||
result.m_baseColor = BlendBaseColor(sampledBaseColor, inputs.m_baseColor.rgb, inputs.m_baseColorFactor, inputs.m_baseColorTextureBlendMode, inputs.m_baseColor_useTexture);
|
||||
result.m_specularF0Factor = GetSpecularInput(inputs.m_specularF0Map, inputs.m_sampler, transformedUv[inputs.m_specularF0MapUvIndex], inputs.m_specularF0Factor, inputs.m_specularF0_useTexture);
|
||||
result.m_metallic = GetMetallicInput(inputs.m_metallicMap, inputs.m_sampler, transformedUv[inputs.m_metallicMapUvIndex], inputs.m_metallicFactor, inputs.m_metallic_useTexture);
|
||||
result.m_roughness = GetRoughnessInput(inputs.m_roughnessMap, MaterialSrg::m_sampler, transformedUv[inputs.m_roughnessMapUvIndex], inputs.m_roughnessFactor, inputs.m_roughnessLowerBound, inputs.m_roughnessUpperBound, inputs.m_roughness_useTexture);
|
||||
|
||||
result.m_emissiveLighting = GetEmissiveInput(inputs.m_emissiveMap, inputs.m_sampler, transformedUv[inputs.m_emissiveMapUvIndex], inputs.m_emissiveIntensity, inputs.m_emissiveColor.rgb, inputs.m_emissiveEnabled, inputs.m_emissive_useTexture);
|
||||
result.m_diffuseAmbientOcclusion = GetOcclusionInput(inputs.m_diffuseOcclusionMap, inputs.m_sampler, transformedUv[inputs.m_diffuseOcclusionMapUvIndex], inputs.m_diffuseOcclusionFactor, inputs.m_diffuseOcclusion_useTexture);
|
||||
result.m_specularOcclusion = GetOcclusionInput(inputs.m_specularOcclusionMap, MaterialSrg::m_sampler, transformedUv[inputs.m_specularOcclusionMapUvIndex], inputs.m_specularOcclusionFactor, inputs.m_specularOcclusion_useTexture);
|
||||
|
||||
result.m_clearCoat.InitializeToZero();
|
||||
if(inputs.m_clearCoatEnabled)
|
||||
{
|
||||
float3x3 clearCoatUvMatrix = inputs.m_clearCoatNormalMapUvIndex == 0 ? inputs.m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(inputs.m_clearCoatInfluenceMap, transformedUv[inputs.m_clearCoatInfluenceMapUvIndex], inputs.m_clearCoatFactor, inputs.m_clearCoat_factor_useTexture,
|
||||
inputs.m_clearCoatRoughnessMap, transformedUv[inputs.m_clearCoatRoughnessMapUvIndex], inputs.m_clearCoatRoughness, inputs.m_clearCoat_roughness_useTexture,
|
||||
inputs.m_clearCoatNormalMap, transformedUv[inputs.m_clearCoatNormalMapUvIndex], inputs.m_normal, inputs.m_clearCoat_normal_useTexture, inputs.m_clearCoatNormalStrength,
|
||||
clearCoatUvMatrix, inputs.m_tangents[inputs.m_clearCoatNormalMapUvIndex], inputs.m_bitangents[inputs.m_clearCoatNormalMapUvIndex],
|
||||
inputs.m_sampler, inputs.m_isFrontFace,
|
||||
result.m_clearCoat.factor, result.m_clearCoat.roughness, result.m_clearCoat.normal);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Fills a StandardMaterialInputs struct with data from the MaterialSrg, shader options, and local vertex data.
|
||||
#define FILL_STANDARD_MATERIAL_INPUTS(inputs, srgLayerPrefix, optionsLayerPrefix, blendWeight) \
|
||||
inputs.m_sampler = MaterialSrg::m_sampler; \
|
||||
inputs.m_vertexUv = IN.m_uv; \
|
||||
inputs.m_uvMatrix = srgLayerPrefix##m_uvMatrix; \
|
||||
inputs.m_normal = IN.m_normal; \
|
||||
inputs.m_tangents = tangents; \
|
||||
inputs.m_bitangents = bitangents; \
|
||||
inputs.m_isFrontFace = isFrontFace; \
|
||||
\
|
||||
inputs.m_normalMapUvIndex = srgLayerPrefix##m_normalMapUvIndex; \
|
||||
inputs.m_normalMap = srgLayerPrefix##m_normalMap; \
|
||||
inputs.m_flipNormalX = srgLayerPrefix##m_flipNormalX; \
|
||||
inputs.m_flipNormalY = srgLayerPrefix##m_flipNormalY; \
|
||||
inputs.m_normal_useTexture = optionsLayerPrefix##o_normal_useTexture; \
|
||||
inputs.m_normalFactor = srgLayerPrefix##m_normalFactor * blendWeight; \
|
||||
inputs.m_baseColorMap = srgLayerPrefix##m_baseColorMap; \
|
||||
inputs.m_baseColorMapUvIndex = srgLayerPrefix##m_baseColorMapUvIndex; \
|
||||
inputs.m_baseColor = srgLayerPrefix##m_baseColor; \
|
||||
inputs.m_baseColor_useTexture = optionsLayerPrefix##o_baseColor_useTexture; \
|
||||
inputs.m_baseColorFactor = srgLayerPrefix##m_baseColorFactor; \
|
||||
inputs.m_baseColorTextureBlendMode = optionsLayerPrefix##o_baseColorTextureBlendMode; \
|
||||
inputs.m_metallicMap = srgLayerPrefix##m_metallicMap; \
|
||||
inputs.m_metallicMapUvIndex = srgLayerPrefix##m_metallicMapUvIndex; \
|
||||
inputs.m_metallicFactor = srgLayerPrefix##m_metallicFactor; \
|
||||
inputs.m_metallic_useTexture = optionsLayerPrefix##o_metallic_useTexture; \
|
||||
inputs.m_specularF0Map = srgLayerPrefix##m_specularF0Map; \
|
||||
inputs.m_specularF0MapUvIndex = srgLayerPrefix##m_specularF0MapUvIndex; \
|
||||
inputs.m_specularF0Factor = srgLayerPrefix##m_specularF0Factor; \
|
||||
inputs.m_specularF0_useTexture = optionsLayerPrefix##o_specularF0_useTexture; \
|
||||
inputs.m_roughnessMap = srgLayerPrefix##m_roughnessMap; \
|
||||
inputs.m_roughnessMapUvIndex = srgLayerPrefix##m_roughnessMapUvIndex; \
|
||||
inputs.m_roughnessFactor = srgLayerPrefix##m_roughnessFactor; \
|
||||
inputs.m_roughnessLowerBound = srgLayerPrefix##m_roughnessLowerBound; \
|
||||
inputs.m_roughnessUpperBound = srgLayerPrefix##m_roughnessUpperBound; \
|
||||
inputs.m_roughness_useTexture = optionsLayerPrefix##o_roughness_useTexture; \
|
||||
\
|
||||
inputs.m_emissiveMap = srgLayerPrefix##m_emissiveMap; \
|
||||
inputs.m_emissiveMapUvIndex = srgLayerPrefix##m_emissiveMapUvIndex; \
|
||||
inputs.m_emissiveIntensity = srgLayerPrefix##m_emissiveIntensity; \
|
||||
inputs.m_emissiveColor = srgLayerPrefix##m_emissiveColor; \
|
||||
inputs.m_emissiveEnabled = optionsLayerPrefix##o_emissiveEnabled; \
|
||||
inputs.m_emissive_useTexture = optionsLayerPrefix##o_emissive_useTexture; \
|
||||
\
|
||||
inputs.m_diffuseOcclusionMap = srgLayerPrefix##m_diffuseOcclusionMap; \
|
||||
inputs.m_diffuseOcclusionMapUvIndex = srgLayerPrefix##m_diffuseOcclusionMapUvIndex; \
|
||||
inputs.m_diffuseOcclusionFactor = srgLayerPrefix##m_diffuseOcclusionFactor; \
|
||||
inputs.m_diffuseOcclusion_useTexture = optionsLayerPrefix##o_diffuseOcclusion_useTexture; \
|
||||
\
|
||||
inputs.m_specularOcclusionMap = srgLayerPrefix##m_specularOcclusionMap; \
|
||||
inputs.m_specularOcclusionMapUvIndex = srgLayerPrefix##m_specularOcclusionMapUvIndex; \
|
||||
inputs.m_specularOcclusionFactor = srgLayerPrefix##m_specularOcclusionFactor; \
|
||||
inputs.m_specularOcclusion_useTexture = optionsLayerPrefix##o_specularOcclusion_useTexture; \
|
||||
\
|
||||
inputs.m_clearCoatEnabled = o_clearCoat_feature_enabled && optionsLayerPrefix##o_clearCoat_enabled; \
|
||||
inputs.m_clearCoatInfluenceMap = srgLayerPrefix##m_clearCoatInfluenceMap; \
|
||||
inputs.m_clearCoatInfluenceMapUvIndex = srgLayerPrefix##m_clearCoatInfluenceMapUvIndex; \
|
||||
inputs.m_clearCoatFactor = srgLayerPrefix##m_clearCoatFactor; \
|
||||
inputs.m_clearCoat_factor_useTexture = optionsLayerPrefix##o_clearCoat_factor_useTexture; \
|
||||
inputs.m_clearCoatRoughnessMap = srgLayerPrefix##m_clearCoatRoughnessMap; \
|
||||
inputs.m_clearCoatRoughnessMapUvIndex = srgLayerPrefix##m_clearCoatRoughnessMapUvIndex; \
|
||||
inputs.m_clearCoatRoughness = srgLayerPrefix##m_clearCoatRoughness; \
|
||||
inputs.m_clearCoat_roughness_useTexture = optionsLayerPrefix##o_clearCoat_roughness_useTexture; \
|
||||
inputs.m_clearCoatNormalMap = srgLayerPrefix##m_clearCoatNormalMap; \
|
||||
inputs.m_clearCoatNormalMapUvIndex = srgLayerPrefix##m_clearCoatNormalMapUvIndex; \
|
||||
inputs.m_clearCoat_normal_useTexture = optionsLayerPrefix##o_clearCoat_normal_useTexture; \
|
||||
inputs.m_clearCoatNormalStrength = srgLayerPrefix##m_clearCoatNormalStrength;
|
||||
|
||||
|
||||
// ---------- Pixel Shader ----------
|
||||
|
||||
PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float depthNDC)
|
||||
{
|
||||
depthNDC = IN.m_position.z;
|
||||
|
||||
s_blendMaskFromVertexStream = IN.m_blendMask;
|
||||
|
||||
// ------- Tangents & Bitangets -------
|
||||
|
||||
// We support two UV streams, but only a single stream of tangent/bitangent. So for UV[1+] we generated the tangent/bitangent in screen-space.
|
||||
float3 tangents[UvSetCount] = { IN.m_tangent.xyz, float3(0, 0, 0) };
|
||||
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, float3(0, 0, 0) };
|
||||
|
||||
if ((o_parallax_feature_enabled && !o_enableSubsurfaceScattering && MaterialSrg::m_parallaxUvIndex != 0)
|
||||
|| (o_layer1_o_normal_useTexture && MaterialSrg::m_layer1_m_normalMapUvIndex != 0)
|
||||
|| (o_layer2_o_normal_useTexture && MaterialSrg::m_layer2_m_normalMapUvIndex != 0)
|
||||
|| (o_layer3_o_normal_useTexture && MaterialSrg::m_layer3_m_normalMapUvIndex != 0)
|
||||
|| (o_layer1_o_clearCoat_normal_useTexture && MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex != 0)
|
||||
|| (o_layer2_o_clearCoat_normal_useTexture && MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex != 0)
|
||||
|| (o_layer3_o_clearCoat_normal_useTexture && MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex != 0)
|
||||
)
|
||||
{
|
||||
// Generate the tangent/bitangent for UV[1+]
|
||||
const int startIndex = 1;
|
||||
PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents, startIndex);
|
||||
}
|
||||
|
||||
// ------- Debug Modes -------
|
||||
|
||||
<<<<<<< HEAD
|
||||
if(o_debugDrawMode == DebugDrawMode::BlendSource)
|
||||
{
|
||||
float3 blendSource = GetBlendSourceValues(IN.m_uv[MaterialSrg::m_blendMaskUvIndex]);
|
||||
return DebugOutput(blendSource);
|
||||
=======
|
||||
if(o_debugDrawMode == DebugDrawMode::BlendWeights)
|
||||
{
|
||||
float3 blendWeights = GetBlendWeights(IN.m_uv[MaterialSrg::m_blendMaskUvIndex], IN.m_blendWeights);
|
||||
return DebugOutput(blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
}
|
||||
|
||||
if(o_debugDrawMode == DebugDrawMode::DisplacementMaps)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
GetDepth_Setup(IN.m_blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
float depth = GetNormalizedDepth(-MaterialSrg::m_displacementMax, -MaterialSrg::m_displacementMin, IN.m_uv[MaterialSrg::m_parallaxUvIndex], float2(0,0), float2(0,0));
|
||||
return DebugOutput(float3(depth,depth,depth));
|
||||
}
|
||||
|
||||
// ------- Parallax -------
|
||||
|
||||
bool displacementIsClipped = false;
|
||||
|
||||
if(ShouldHandleParallax())
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
GetDepth_Setup(IN.m_blendWeights);
|
||||
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3();
|
||||
|
||||
float parallaxOverallOffset = MaterialSrg::m_displacementMax;
|
||||
float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin;
|
||||
GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset,
|
||||
ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse,
|
||||
IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC, IN.m_position.w, displacementIsClipped);
|
||||
|
||||
// Adjust directional light shadow coorinates for parallax correction
|
||||
if(o_parallax_enablePixelDepthOffset)
|
||||
{
|
||||
const uint shadowIndex = ViewSrg::m_shadowIndexDirectionalLight;
|
||||
if (o_enableShadows && shadowIndex < SceneSrg::m_directionalLightCount)
|
||||
{
|
||||
DirectionalLightShadow::GetShadowCoords(shadowIndex, IN.m_worldPosition, IN.m_shadowCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------- Calculate Layer Blend Mask Values -------
|
||||
|
||||
// Now that any parallax has been calculated, we calculate the blend factors for any layers that are impacted by the parallax.
|
||||
<<<<<<< HEAD
|
||||
float3 blendWeights = GetBlendWeights(IN.m_uv[MaterialSrg::m_blendMaskUvIndex]);
|
||||
|
||||
// ------- Layer 1 (base layer) -----------
|
||||
|
||||
ProcessedMaterialInputs lightingInputLayer1;
|
||||
=======
|
||||
float3 blendWeights = GetBlendWeights(IN.m_uv[MaterialSrg::m_blendMaskUvIndex], IN.m_blendWeights);
|
||||
|
||||
// ------- Normal -------
|
||||
|
||||
float3 layer1_normalFactor = MaterialSrg::m_layer1_m_normalFactor * blendWeights.r;
|
||||
float3 layer2_normalFactor = MaterialSrg::m_layer2_m_normalFactor * blendWeights.g;
|
||||
float3 layer3_normalFactor = MaterialSrg::m_layer3_m_normalFactor * blendWeights.b;
|
||||
float3x3 layer1_uvMatrix = MaterialSrg::m_layer1_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer1_m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 layer2_uvMatrix = MaterialSrg::m_layer2_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer2_m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 layer3_uvMatrix = MaterialSrg::m_layer3_m_normalMapUvIndex == 0 ? MaterialSrg::m_layer3_m_uvMatrix : CreateIdentity3x3();
|
||||
float3 layer1_normalTS = GetNormalInputTS(MaterialSrg::m_layer1_m_normalMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_normalMapUvIndex], MaterialSrg::m_layer1_m_flipNormalX, MaterialSrg::m_layer1_m_flipNormalY, layer1_uvMatrix, o_layer1_o_normal_useTexture, layer1_normalFactor);
|
||||
float3 layer2_normalTS = GetNormalInputTS(MaterialSrg::m_layer2_m_normalMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_normalMapUvIndex], MaterialSrg::m_layer2_m_flipNormalX, MaterialSrg::m_layer2_m_flipNormalY, layer2_uvMatrix, o_layer2_o_normal_useTexture, layer2_normalFactor);
|
||||
float3 layer3_normalTS = GetNormalInputTS(MaterialSrg::m_layer3_m_normalMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_normalMapUvIndex], MaterialSrg::m_layer3_m_flipNormalX, MaterialSrg::m_layer3_m_flipNormalY, layer3_uvMatrix, o_layer3_o_normal_useTexture, layer3_normalFactor);
|
||||
|
||||
float3 normalTS = ReorientTangentSpaceNormal(layer1_normalTS, layer2_normalTS);
|
||||
normalTS = ReorientTangentSpaceNormal(normalTS, layer3_normalTS);
|
||||
// [GFX TODO][ATOM-14591]: This will only work if the normal maps all use the same UV stream. We would need to add support for having them in different UV streams.
|
||||
surface.normal = normalize(TangentSpaceToWorld(normalTS, IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex]));
|
||||
|
||||
// ------- Base Color -------
|
||||
|
||||
float2 layer1_baseColorUv = uvLayer1[MaterialSrg::m_layer1_m_baseColorMapUvIndex];
|
||||
float2 layer2_baseColorUv = uvLayer2[MaterialSrg::m_layer2_m_baseColorMapUvIndex];
|
||||
float2 layer3_baseColorUv = uvLayer3[MaterialSrg::m_layer3_m_baseColorMapUvIndex];
|
||||
|
||||
float3 layer1_sampledColor = GetBaseColorInput(MaterialSrg::m_layer1_m_baseColorMap, MaterialSrg::m_sampler, layer1_baseColorUv, MaterialSrg::m_layer1_m_baseColor.rgb, o_layer1_o_baseColor_useTexture);
|
||||
float3 layer2_sampledColor = GetBaseColorInput(MaterialSrg::m_layer2_m_baseColorMap, MaterialSrg::m_sampler, layer2_baseColorUv, MaterialSrg::m_layer2_m_baseColor.rgb, o_layer2_o_baseColor_useTexture);
|
||||
float3 layer3_sampledColor = GetBaseColorInput(MaterialSrg::m_layer3_m_baseColorMap, MaterialSrg::m_sampler, layer3_baseColorUv, MaterialSrg::m_layer3_m_baseColor.rgb, o_layer3_o_baseColor_useTexture);
|
||||
float3 layer1_baseColor = BlendBaseColor(layer1_sampledColor, MaterialSrg::m_layer1_m_baseColor.rgb, MaterialSrg::m_layer1_m_baseColorFactor, o_layer1_o_baseColorTextureBlendMode, o_layer1_o_baseColor_useTexture);
|
||||
float3 layer2_baseColor = BlendBaseColor(layer2_sampledColor, MaterialSrg::m_layer2_m_baseColor.rgb, MaterialSrg::m_layer2_m_baseColorFactor, o_layer2_o_baseColorTextureBlendMode, o_layer2_o_baseColor_useTexture);
|
||||
float3 layer3_baseColor = BlendBaseColor(layer3_sampledColor, MaterialSrg::m_layer3_m_baseColor.rgb, MaterialSrg::m_layer3_m_baseColorFactor, o_layer3_o_baseColorTextureBlendMode, o_layer3_o_baseColor_useTexture);
|
||||
float3 baseColor = BlendLayers(layer1_baseColor, layer2_baseColor, layer3_baseColor, blendWeights);
|
||||
|
||||
if(o_parallax_highlightClipping && displacementIsClipped)
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
{
|
||||
StandardMaterialInputs inputs;
|
||||
FILL_STANDARD_MATERIAL_INPUTS(inputs, MaterialSrg::m_layer1_, o_layer1_, blendWeights.r)
|
||||
lightingInputLayer1 = ProcessStandardMaterialInputs(inputs);
|
||||
}
|
||||
|
||||
// ----------- Layer 2 -----------
|
||||
|
||||
ProcessedMaterialInputs lightingInputLayer2;
|
||||
if(o_layer2_enabled)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
StandardMaterialInputs inputs;
|
||||
FILL_STANDARD_MATERIAL_INPUTS(inputs, MaterialSrg::m_layer2_, o_layer2_, blendWeights.g)
|
||||
lightingInputLayer2 = ProcessStandardMaterialInputs(inputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingInputLayer2.InitializeToZero();
|
||||
}
|
||||
|
||||
// ----------- Layer 3 -----------
|
||||
=======
|
||||
float layer1_metallic = GetMetallicInput(MaterialSrg::m_layer1_m_metallicMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_metallicMapUvIndex], MaterialSrg::m_layer1_m_metallicFactor, o_layer1_o_metallic_useTexture);
|
||||
float layer2_metallic = GetMetallicInput(MaterialSrg::m_layer2_m_metallicMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_metallicMapUvIndex], MaterialSrg::m_layer2_m_metallicFactor, o_layer2_o_metallic_useTexture);
|
||||
float layer3_metallic = GetMetallicInput(MaterialSrg::m_layer3_m_metallicMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_metallicMapUvIndex], MaterialSrg::m_layer3_m_metallicFactor, o_layer3_o_metallic_useTexture);
|
||||
metallic = BlendLayers(layer1_metallic, layer2_metallic, layer3_metallic, blendWeights);
|
||||
}
|
||||
|
||||
// ------- Specular -------
|
||||
|
||||
float layer1_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer1_m_specularF0Map, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularF0MapUvIndex], MaterialSrg::m_layer1_m_specularF0Factor, o_layer1_o_specularF0_useTexture);
|
||||
float layer2_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer2_m_specularF0Map, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularF0MapUvIndex], MaterialSrg::m_layer2_m_specularF0Factor, o_layer2_o_specularF0_useTexture);
|
||||
float layer3_specularF0Factor = GetSpecularInput(MaterialSrg::m_layer3_m_specularF0Map, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularF0MapUvIndex], MaterialSrg::m_layer3_m_specularF0Factor, o_layer3_o_specularF0_useTexture);
|
||||
float specularF0Factor = BlendLayers(layer1_specularF0Factor, layer2_specularF0Factor, layer3_specularF0Factor, blendWeights);
|
||||
|
||||
surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
|
||||
ProcessedMaterialInputs lightingInputLayer3;
|
||||
if(o_layer3_enabled)
|
||||
{
|
||||
StandardMaterialInputs inputs;
|
||||
FILL_STANDARD_MATERIAL_INPUTS(inputs, MaterialSrg::m_layer3_, o_layer3_, blendWeights.b)
|
||||
lightingInputLayer3 = ProcessStandardMaterialInputs(inputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingInputLayer3.InitializeToZero();
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// ------- Combine all layers ---------
|
||||
|
||||
Surface surface;
|
||||
surface.position = IN.m_worldPosition;
|
||||
surface.transmission.InitializeToZero();
|
||||
=======
|
||||
float layer1_roughness = GetRoughnessInput(MaterialSrg::m_layer1_m_roughnessMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_roughnessMapUvIndex], MaterialSrg::m_layer1_m_roughnessFactor, MaterialSrg::m_layer1_m_roughnessLowerBound, MaterialSrg::m_layer1_m_roughnessUpperBound, o_layer1_o_roughness_useTexture);
|
||||
float layer2_roughness = GetRoughnessInput(MaterialSrg::m_layer2_m_roughnessMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_roughnessMapUvIndex], MaterialSrg::m_layer2_m_roughnessFactor, MaterialSrg::m_layer2_m_roughnessLowerBound, MaterialSrg::m_layer2_m_roughnessUpperBound, o_layer2_o_roughness_useTexture);
|
||||
float layer3_roughness = GetRoughnessInput(MaterialSrg::m_layer3_m_roughnessMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_roughnessMapUvIndex], MaterialSrg::m_layer3_m_roughnessFactor, MaterialSrg::m_layer3_m_roughnessLowerBound, MaterialSrg::m_layer3_m_roughnessUpperBound, o_layer3_o_roughness_useTexture);
|
||||
surface.roughnessLinear = BlendLayers(layer1_roughness, layer2_roughness, layer3_roughness, blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
|
||||
// ------- Combine Normals ---------
|
||||
|
||||
float3 normalTS = lightingInputLayer1.m_normalTS;
|
||||
if(o_layer2_enabled)
|
||||
{
|
||||
normalTS = ReorientTangentSpaceNormal(normalTS, lightingInputLayer2.m_normalTS);
|
||||
}
|
||||
if(o_layer3_enabled)
|
||||
{
|
||||
normalTS = ReorientTangentSpaceNormal(normalTS, lightingInputLayer3.m_normalTS);
|
||||
}
|
||||
// [GFX TODO][ATOM-14591]: This will only work if the normal maps all use the same UV stream. We would need to add support for having them in different UV streams.
|
||||
surface.normal = normalize(TangentSpaceToWorld(normalTS, IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex]));
|
||||
|
||||
// ------- Combine Albedo, roughness, specular, roughness ---------
|
||||
|
||||
float3 baseColor = BlendLayers(lightingInputLayer1.m_baseColor, lightingInputLayer2.m_baseColor, lightingInputLayer3.m_baseColor, blendWeights);
|
||||
float3 specularF0Factor = BlendLayers(lightingInputLayer1.m_specularF0Factor, lightingInputLayer2.m_specularF0Factor, lightingInputLayer3.m_specularF0Factor, blendWeights);
|
||||
float3 metallic = BlendLayers(lightingInputLayer1.m_metallic, lightingInputLayer2.m_metallic, lightingInputLayer3.m_metallic, blendWeights);
|
||||
|
||||
if(o_parallax_highlightClipping && displacementIsClipped)
|
||||
{
|
||||
ApplyParallaxClippingHighlight(baseColor);
|
||||
}
|
||||
|
||||
surface.SetAlbedoAndSpecularF0(baseColor, specularF0Factor, metallic);
|
||||
|
||||
surface.roughnessLinear = BlendLayers(lightingInputLayer1.m_roughness, lightingInputLayer2.m_roughness, lightingInputLayer3.m_roughness, blendWeights);
|
||||
surface.CalculateRoughnessA();
|
||||
|
||||
// ------- Init and Combine 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;
|
||||
|
||||
<<<<<<< HEAD
|
||||
lightingData.emissiveLighting = BlendLayers(lightingInputLayer1.m_emissiveLighting, lightingInputLayer2.m_emissiveLighting, lightingInputLayer3.m_emissiveLighting, blendWeights);
|
||||
lightingData.specularOcclusion = BlendLayers(lightingInputLayer1.m_specularOcclusion, lightingInputLayer2.m_specularOcclusion, lightingInputLayer3.m_specularOcclusion, blendWeights);
|
||||
lightingData.diffuseAmbientOcclusion = BlendLayers(lightingInputLayer1.m_diffuseAmbientOcclusion, lightingInputLayer2.m_diffuseAmbientOcclusion, lightingInputLayer3.m_diffuseAmbientOcclusion, blendWeights);
|
||||
|
||||
lightingData.CalculateMultiscatterCompensation(surface.specularF0, o_specularF0_enableMultiScatterCompensation);
|
||||
=======
|
||||
float3 layer1_emissive = GetEmissiveInput(MaterialSrg::m_layer1_m_emissiveMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_emissiveMapUvIndex], MaterialSrg::m_layer1_m_emissiveIntensity, MaterialSrg::m_layer1_m_emissiveColor.rgb, o_layer1_o_emissiveEnabled, o_layer1_o_emissive_useTexture);
|
||||
float3 layer2_emissive = GetEmissiveInput(MaterialSrg::m_layer2_m_emissiveMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_emissiveMapUvIndex], MaterialSrg::m_layer2_m_emissiveIntensity, MaterialSrg::m_layer2_m_emissiveColor.rgb, o_layer2_o_emissiveEnabled, o_layer2_o_emissive_useTexture);
|
||||
float3 layer3_emissive = GetEmissiveInput(MaterialSrg::m_layer3_m_emissiveMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_emissiveMapUvIndex], MaterialSrg::m_layer3_m_emissiveIntensity, MaterialSrg::m_layer3_m_emissiveColor.rgb, o_layer3_o_emissiveEnabled, o_layer3_o_emissive_useTexture);
|
||||
lightingData.emissiveLighting = BlendLayers(layer1_emissive, layer2_emissive, layer3_emissive, blendWeights);
|
||||
|
||||
// ------- Occlusion -------
|
||||
|
||||
float layer1_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer1_m_diffuseOcclusionFactor, o_layer1_o_diffuseOcclusion_useTexture);
|
||||
float layer2_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer2_m_diffuseOcclusionFactor, o_layer2_o_diffuseOcclusion_useTexture);
|
||||
float layer3_diffuseAmbientOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_diffuseOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_diffuseOcclusionMapUvIndex], MaterialSrg::m_layer3_m_diffuseOcclusionFactor, o_layer3_o_diffuseOcclusion_useTexture);
|
||||
lightingData.diffuseAmbientOcclusion = BlendLayers(layer1_diffuseAmbientOcclusion, layer2_diffuseAmbientOcclusion, layer3_diffuseAmbientOcclusion, blendWeights);
|
||||
|
||||
float layer1_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer1_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer1[MaterialSrg::m_layer1_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer1_m_specularOcclusionFactor, o_layer1_o_specularOcclusion_useTexture);
|
||||
float layer2_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer2_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer2[MaterialSrg::m_layer2_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer2_m_specularOcclusionFactor, o_layer2_o_specularOcclusion_useTexture);
|
||||
float layer3_specularOcclusion = GetOcclusionInput(MaterialSrg::m_layer3_m_specularOcclusionMap, MaterialSrg::m_sampler, uvLayer3[MaterialSrg::m_layer3_m_specularOcclusionMapUvIndex], MaterialSrg::m_layer3_m_specularOcclusionFactor, o_layer3_o_specularOcclusion_useTexture);
|
||||
lightingData.specularOcclusion = BlendLayers(layer1_specularOcclusion, layer2_specularOcclusion, layer3_specularOcclusion, blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
|
||||
// ------- Combine Clearcoat -------
|
||||
|
||||
if(o_clearCoat_feature_enabled)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
surface.clearCoat.factor = BlendLayers(lightingInputLayer1.m_clearCoat.factor, lightingInputLayer2.m_clearCoat.factor, lightingInputLayer3.m_clearCoat.factor, blendWeights);
|
||||
surface.clearCoat.roughness = BlendLayers(lightingInputLayer1.m_clearCoat.roughness, lightingInputLayer2.m_clearCoat.roughness, lightingInputLayer3.m_clearCoat.roughness, blendWeights);
|
||||
|
||||
// [GFX TODO][ATOM-14592] This is not the right way to blend the normals. We need to use ReorientTangentSpaceNormal(), and that requires GetClearCoatInputs() to return the normal in TS instead of WS.
|
||||
surface.clearCoat.normal = BlendLayers(lightingInputLayer1.m_clearCoat.normal, lightingInputLayer2.m_clearCoat.normal, lightingInputLayer3.m_clearCoat.normal, blendWeights);
|
||||
=======
|
||||
// --- Layer 1 ---
|
||||
|
||||
float layer1_clearCoatFactor = 0.0f;
|
||||
float layer1_clearCoatRoughness = 0.0f;
|
||||
float3 layer1_clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
if(o_layer1_o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 layer1_uvMatrix = MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_layer1_m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(MaterialSrg::m_layer1_m_clearCoatInfluenceMap, uvLayer1[MaterialSrg::m_layer1_m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_layer1_m_clearCoatFactor, o_layer1_o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_layer1_m_clearCoatRoughnessMap, uvLayer1[MaterialSrg::m_layer1_m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_layer1_m_clearCoatRoughness, o_layer1_o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_layer1_m_clearCoatNormalMap, uvLayer1[MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex], IN.m_normal, o_layer1_o_clearCoat_normal_useTexture, MaterialSrg::m_layer1_m_clearCoatNormalStrength,
|
||||
layer1_uvMatrix, tangents[MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_layer1_m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
layer1_clearCoatFactor, layer1_clearCoatRoughness, layer1_clearCoatNormal);
|
||||
}
|
||||
|
||||
// --- Layer 2 ---
|
||||
|
||||
float layer2_clearCoatFactor = 0.0f;
|
||||
float layer2_clearCoatRoughness = 0.0f;
|
||||
float3 layer2_clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
if(o_layer2_o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 layer2_uvMatrix = MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_layer2_m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(MaterialSrg::m_layer2_m_clearCoatInfluenceMap, uvLayer2[MaterialSrg::m_layer2_m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_layer2_m_clearCoatFactor, o_layer2_o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_layer2_m_clearCoatRoughnessMap, uvLayer2[MaterialSrg::m_layer2_m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_layer2_m_clearCoatRoughness, o_layer2_o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_layer2_m_clearCoatNormalMap, uvLayer2[MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex], IN.m_normal, o_layer2_o_clearCoat_normal_useTexture, MaterialSrg::m_layer2_m_clearCoatNormalStrength,
|
||||
layer2_uvMatrix, tangents[MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_layer2_m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
layer2_clearCoatFactor, layer2_clearCoatRoughness, layer2_clearCoatNormal);
|
||||
}
|
||||
|
||||
// --- Layer 3 ---
|
||||
|
||||
float layer3_clearCoatFactor = 0.0f;
|
||||
float layer3_clearCoatRoughness = 0.0f;
|
||||
float3 layer3_clearCoatNormal = float3(0.0, 0.0, 0.0);
|
||||
if(o_layer3_o_clearCoat_enabled)
|
||||
{
|
||||
float3x3 layer3_uvMatrix = MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex == 0 ? MaterialSrg::m_layer3_m_uvMatrix : CreateIdentity3x3();
|
||||
|
||||
GetClearCoatInputs(MaterialSrg::m_layer3_m_clearCoatInfluenceMap, uvLayer3[MaterialSrg::m_layer3_m_clearCoatInfluenceMapUvIndex], MaterialSrg::m_layer3_m_clearCoatFactor, o_layer3_o_clearCoat_factor_useTexture,
|
||||
MaterialSrg::m_layer3_m_clearCoatRoughnessMap, uvLayer3[MaterialSrg::m_layer3_m_clearCoatRoughnessMapUvIndex], MaterialSrg::m_layer3_m_clearCoatRoughness, o_layer3_o_clearCoat_roughness_useTexture,
|
||||
MaterialSrg::m_layer3_m_clearCoatNormalMap, uvLayer3[MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex], IN.m_normal, o_layer3_o_clearCoat_normal_useTexture, MaterialSrg::m_layer3_m_clearCoatNormalStrength,
|
||||
layer3_uvMatrix, tangents[MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex], bitangents[MaterialSrg::m_layer3_m_clearCoatNormalMapUvIndex],
|
||||
MaterialSrg::m_sampler, isFrontFace,
|
||||
layer3_clearCoatFactor, layer3_clearCoatRoughness, layer3_clearCoatNormal);
|
||||
}
|
||||
|
||||
// --- Blend Layers ---
|
||||
|
||||
surface.clearCoat.factor = BlendLayers(layer1_clearCoatFactor, layer2_clearCoatFactor, layer3_clearCoatFactor, blendWeights);
|
||||
surface.clearCoat.roughness = BlendLayers(layer1_clearCoatRoughness, layer2_clearCoatRoughness, layer3_clearCoatRoughness, blendWeights);
|
||||
|
||||
// [GFX TODO][ATOM-14592] This is not the right way to blend the normals. We need to use ReorientTangentSpaceNormal(), and that requires GetClearCoatInputs() to return the normal in TS instead of WS.
|
||||
surface.clearCoat.normal = BlendLayers(layer1_clearCoatNormal, layer2_clearCoatNormal, layer3_clearCoatNormal, blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
surface.clearCoat.normal = normalize(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);
|
||||
}
|
||||
|
||||
// ------- 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(0);
|
||||
|
||||
|
||||
const float alpha = 1.0;
|
||||
|
||||
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
|
||||
|
||||
lightingOutput.m_diffuseColor.w = -1; // Disable subsurface scattering
|
||||
|
||||
return lightingOutput;
|
||||
}
|
||||
|
||||
ForwardPassOutputWithDepth ForwardPassPS(VSOutput IN, bool isFrontFace : SV_IsFrontFace)
|
||||
{
|
||||
ForwardPassOutputWithDepth OUT;
|
||||
float depth;
|
||||
|
||||
PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth);
|
||||
|
||||
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;
|
||||
OUT.m_depth = depth;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
[earlydepthstencil]
|
||||
ForwardPassOutput ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : SV_IsFrontFace)
|
||||
{
|
||||
ForwardPassOutput OUT;
|
||||
float depth;
|
||||
|
||||
PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth);
|
||||
|
||||
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;
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
-131
@@ -1,131 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <scenesrg.srgi>
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/Features/PBR/DefaultObjectSrg.azsli>
|
||||
#include <Atom/Features/ParallaxMapping.azsli>
|
||||
#include <Atom/Features/MatrixUtility.azsli>
|
||||
|
||||
#include "MaterialInputs/ParallaxInput.azsli"
|
||||
|
||||
#include "MaterialInputs/ParallaxInput.azsli"
|
||||
COMMON_OPTIONS_PARALLAX(o_layer1_)
|
||||
COMMON_OPTIONS_PARALLAX(o_layer2_)
|
||||
COMMON_OPTIONS_PARALLAX(o_layer3_)
|
||||
|
||||
#include "StandardMultilayerPBR_Common.azsli"
|
||||
|
||||
struct VertexInput
|
||||
{
|
||||
float3 m_position : POSITION;
|
||||
float2 m_uv0 : UV0;
|
||||
float2 m_uv1 : UV1;
|
||||
|
||||
// only used for parallax depth calculation
|
||||
float3 m_normal : NORMAL;
|
||||
float4 m_tangent : TANGENT;
|
||||
float3 m_bitangent : BITANGENT;
|
||||
|
||||
// This gets set automatically by the system at runtime only if it's available.
|
||||
// There is a soft naming convention that associates this with o_blendMask_isBound, which will be set to true whenever m_optional_blendMask is available.
|
||||
// (search "m_optional_" in ShaderVariantAssetBuilder for details on the naming convention).
|
||||
// [GFX TODO][ATOM-14475]: Come up with a more elegant way to associate the isBound flag with the input stream.
|
||||
float4 m_optional_blendMask : COLOR0;
|
||||
};
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
float4 m_position : SV_Position;
|
||||
float2 m_uv[UvSetCount] : UV1;
|
||||
|
||||
// only used for parallax depth calculation
|
||||
float3 m_normal : NORMAL;
|
||||
float3 m_tangent : TANGENT;
|
||||
float3 m_bitangent : BITANGENT;
|
||||
float3 m_worldPosition : UV0;
|
||||
float3 m_blendWeights : UV3;
|
||||
};
|
||||
|
||||
VertexOutput MainVS(VertexInput IN)
|
||||
{
|
||||
const float4x4 objectToWorld = ObjectSrg::GetWorldMatrix();
|
||||
VertexOutput OUT;
|
||||
|
||||
const float3 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)).xyz;
|
||||
OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0));
|
||||
|
||||
// By design, only UV0 is allowed to apply transforms.
|
||||
// Note there are additional UV transforms that happen for each layer, but we defer that step to the pixel shader to avoid bloating the vertex output buffer.
|
||||
OUT.m_uv[0] = mul(MaterialSrg::m_uvMatrix, float3(IN.m_uv0, 1.0)).xy;
|
||||
OUT.m_uv[1] = IN.m_uv1;
|
||||
|
||||
if(ShouldHandleParallaxInDepthShaders())
|
||||
{
|
||||
OUT.m_worldPosition = worldPosition.xyz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if(o_blendMask_isBound)
|
||||
{
|
||||
OUT.m_blendWeights = IN.m_optional_blendMask.rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
OUT.m_blendWeights = float3(1,1,1);
|
||||
}
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
struct PSDepthOutput
|
||||
{
|
||||
float m_depth : SV_Depth;
|
||||
};
|
||||
|
||||
PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace)
|
||||
{
|
||||
PSDepthOutput OUT;
|
||||
|
||||
OUT.m_depth = IN.m_position.z;
|
||||
|
||||
if(ShouldHandleParallaxInDepthShaders())
|
||||
{
|
||||
// We support two UV streams, but only a single stream of tangent/bitangent. So for UV[1+] we generated the tangent/bitangent in screen-space.
|
||||
float3 tangents[UvSetCount] = { IN.m_tangent.xyz, float3(0, 0, 0) };
|
||||
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, float3(0, 0, 0) };
|
||||
PrepareGeneratedTangent(IN.m_normal, IN.m_worldPosition, isFrontFace, IN.m_uv, UvSetCount, tangents, bitangents, 1);
|
||||
|
||||
<<<<<<< HEAD
|
||||
s_blendMaskFromVertexStream = IN.m_blendMask;
|
||||
=======
|
||||
GetDepth_Setup(IN.m_blendWeights);
|
||||
>>>>>>> Atom/santorac/MultilayerPbrImprovements
|
||||
|
||||
float depthNDC;
|
||||
|
||||
float3x3 uvMatrix = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrix : CreateIdentity3x3();
|
||||
float3x3 uvMatrixInverse = MaterialSrg::m_parallaxUvIndex == 0 ? MaterialSrg::m_uvMatrixInverse : CreateIdentity3x3();
|
||||
|
||||
float parallaxOverallOffset = MaterialSrg::m_displacementMax;
|
||||
float parallaxOverallFactor = MaterialSrg::m_displacementMax - MaterialSrg::m_displacementMin;
|
||||
GetParallaxInput(IN.m_normal, tangents[MaterialSrg::m_parallaxUvIndex], bitangents[MaterialSrg::m_parallaxUvIndex], parallaxOverallFactor, parallaxOverallOffset,
|
||||
ObjectSrg::GetWorldMatrix(), uvMatrix, uvMatrixInverse,
|
||||
IN.m_uv[MaterialSrg::m_parallaxUvIndex], IN.m_worldPosition, depthNDC);
|
||||
|
||||
OUT.m_depth = depthNDC;
|
||||
}
|
||||
|
||||
return OUT;
|
||||
}
|
||||
Reference in New Issue
Block a user