diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/MaterialInputs/VegetationBendingPropertyGroup.json b/atom_gems/AtomTutorials/Assets/VegetationBending/MaterialInputs/VegetationBendingPropertyGroup.json new file mode 100644 index 0000000..c0789c9 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/MaterialInputs/VegetationBendingPropertyGroup.json @@ -0,0 +1,98 @@ +{ + "name": "vegetationBending", + "displayName": "Vegetation Bending", + "description": "Properties for configuring the bending.", + "properties": [ + { + "name": "DetailBendingFrequency", + "displayName": "Detail bending frequency", + "description": "Detail bending frequency.", + "type": "Float", + "defaultValue": 0.0, + "min": 0.0, + "max": 1.0, + "connection": { + "type": "ShaderInput", + "name": "m_detailFrequency" + } + }, + { + "name": "DetailBendingLeafAmplitude", + "displayName": "Detail bending leaf amplitude", + "description": "Detail bending leaf amplitude.", + "type": "Float", + "defaultValue": 0.0, + "min": 0.0, + "max": 1.0, + "connection": { + "type": "ShaderInput", + "name": "m_detailLeafAmplitude" + } + }, + { + "name": "DetailBendingBranchAmplitude", + "displayName": "Detail branch amplitude", + "description": "Detail branch amplitude.", + "type": "Float", + "defaultValue": 0.0, + "min": 0.0, + "max": 1.0, + "connection": { + "type": "ShaderInput", + "name": "m_detailBranchAmplitude" + } + }, + { + "name": "WindX", + "displayName": "Wind direction x", + "description": "Wind in the x direction. This would typically come from a wind system instead of a material property, but is here as a proof of concept.", + "type": "Float", + "defaultValue": 0.0, + "min": -1.0, + "max": 1.0, + "connection": { + "type": "ShaderInput", + "name": "m_windX" + } + }, + { + "name": "WindY", + "displayName": "Wind direction y", + "description": "Wind in the y direction. This would typically come from a wind system instead of a material property, but is here as a proof of concept.", + "type": "Float", + "defaultValue": 0.0, + "min": -1.0, + "max": 1.0, + "connection": { + "type": "ShaderInput", + "name": "m_windY" + } + }, + { + "name": "WindBendingStrength", + "displayName": "Bending strength", + "description": "Bending strength. This would typically come from a wind system instead of a material property, but is here as a proof of concept.", + "type": "Float", + "defaultValue": 0.0, + "min": 0.0, + "max": 7.0, + "connection": { + "type": "ShaderInput", + "name": "m_bendingStrength" + } + }, + { + "name": "WindBendingFrequency", + "displayName": "Wind Bending Frequency", + "description": "The frequency that the object sways back and forth caused by the wind. This would typically come from a wind system instead of a material property, but is here as a proof of concept.", + "type": "Float", + "defaultValue": 0.0, + "min": 0.0, + "max": 1.5, + "connection": { + "type": "ShaderInput", + "name": "m_windBendingFrequency" + } + } + ] +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/MeshMotionVectorVegetationBending.azsl b/atom_gems/AtomTutorials/Assets/VegetationBending/MeshMotionVectorVegetationBending.azsl new file mode 100644 index 0000000..761039f --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/MeshMotionVectorVegetationBending.azsl @@ -0,0 +1,77 @@ +/* + * 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 +#include + +#include +#include + +#include + +struct VSInput +{ + float3 m_position : POSITION; + float3 m_normal : NORMAL; + + float4 m_optional_color : COLOR0; +}; + +struct VSOutput +{ + float4 m_position : SV_Position; + float3 m_worldPos : TEXCOORD0; + float3 m_worldPosPrev: TEXCOORD1; +}; + +struct PSOutput +{ + float2 m_motion : SV_Target0; +}; + +VSOutput MainVS(VSInput IN) +{ + VSOutput OUT; + + float4x4 objectToWorld = SceneSrg::GetObjectToWorldMatrix(ObjectSrg::m_objectId); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float4x4 prevObjectToWorld = SceneSrg::GetObjectToWorldMatrixPrev(ObjectSrg::m_objectId); + float4 prevWorldPosition = mul(prevObjectToWorld, float4(IN.m_position, 1.0)); + + float currentTime = SceneSrg::m_time; + worldPosition = ProcessBending(currentTime, IN.m_position, IN.m_normal, IN.m_optional_color, worldPosition, objectToWorld); + float prevTime = SceneSrg::m_prevTime; + prevWorldPosition = ProcessBending(prevTime, IN.m_position, IN.m_normal, IN.m_optional_color, prevWorldPosition, prevObjectToWorld); + + OUT.m_worldPos = worldPosition.xyz; + OUT.m_worldPosPrev = prevWorldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + return OUT; +} + +PSOutput MainPS(VSOutput IN) +{ + PSOutput OUT; + + // Current clip position + float4 clipPos = mul(ViewSrg::m_viewProjectionMatrix, float4(IN.m_worldPos, 1.0)); + + // Reprojected last frame's clip position, for skinned mesh it also implies last key frame + float4 clipPosPrev = mul(ViewSrg::m_viewProjectionPrevMatrix, float4(IN.m_worldPosPrev, 1.0)); + + float2 motion = (clipPos.xy / clipPos.w - clipPosPrev.xy / clipPosPrev.w) * 0.5; + + OUT.m_motion = motion; + + // Flip y to line up with uv coordinates + OUT.m_motion.y = -OUT.m_motion.y; + + return OUT; +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/MeshMotionVectorVegetationBending.shader b/atom_gems/AtomTutorials/Assets/VegetationBending/MeshMotionVectorVegetationBending.shader new file mode 100644 index 0000000..d4f9263 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/MeshMotionVectorVegetationBending.shader @@ -0,0 +1,24 @@ +{ + "Source" : "MeshMotionVectorVegetationBending.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "DrawList" : "motion", + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "MainVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + } +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_bark_01_basecolor.tif b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_bark_01_basecolor.tif new file mode 100644 index 0000000..d8d7cf7 Binary files /dev/null and b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_bark_01_basecolor.tif differ diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_bark_02_basecolor.tif b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_bark_02_basecolor.tif new file mode 100644 index 0000000..7e1bb38 Binary files /dev/null and b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_bark_02_basecolor.tif differ diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_leaf_basecolora.tif b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_leaf_basecolora.tif new file mode 100644 index 0000000..4fb7300 Binary files /dev/null and b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/aspen_leaf_basecolora.tif differ diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/tree.fbx b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/tree.fbx new file mode 100644 index 0000000..3132451 Binary files /dev/null and b/atom_gems/AtomTutorials/Assets/VegetationBending/Objects/tree.fbx differ diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending.materialtype b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending.materialtype new file mode 100644 index 0000000..4b385f3 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending.materialtype @@ -0,0 +1,94 @@ +{ + "description": "Material Type like StandardPBR, but does bending for vegetation.", + "version": 1, + "propertyLayout": { + "propertyGroups": [ + { + "$import": "MaterialInputs/VegetationBendingPropertyGroup.json" + }, + // Currently we cannot import property groups across gems, so we are hard coding the full path, even though it is not portable, as a proof of concept. + // There is a GHI to enable importing across gems at https://github.com/o3de/o3de/issues/10623. + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/BaseColorPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/MetallicPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/RoughnessPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/SpecularPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/NormalPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/OcclusionPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/EmissivePropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/OpacityPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/UvPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/IrradiancePropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/GeneralCommonPropertyGroup.json" + } + ] + }, + "shaders": [ + { + "file": "./VegetationBending_ForwardPass.shader", + "tag": "ForwardPass" + }, + { + "file": "./VegetationBending_ForwardPass_EDS.shader", + "tag": "ForwardPass_EDS" + }, + { + "file": "Shaders/Shadow/Shadowmap.shader", + "tag": "Shadowmap" + }, + { + "file": "./VegetationBending_Shadowmap_WithPS.shader", + "tag": "Shadowmap_WithPS" + }, + { + "file": "./VegetationBending_DepthPass.shader", + "tag": "DepthPass" + }, + { + "file": "./VegetationBending_DepthPass_WithPS.shader", + "tag": "DepthPass_WithPS" + }, + { + "file": "./MeshMotionVectorVegetationBending.shader", + "tag": "MeshMotionVector" + } + ], + "functors": [ + { + "type": "Lua", + "args": { + "file": "VegetationBending_ShaderEnable.lua" + } + } + ], + "uvNameMap": { + "UV0": "Tiled", + "UV1": "Unwrapped" + } +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Common.azsli b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Common.azsli new file mode 100644 index 0000000..b8d1c30 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Common.azsli @@ -0,0 +1,197 @@ +/* + * 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 +#include +#include +#include +#include + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/BaseColorInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/RoughnessInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/MetallicInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/SpecularInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/NormalInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/OcclusionInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/EmissiveInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/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() + COMMON_SRG_INPUTS_CLEAR_COAT() + COMMON_SRG_INPUTS_OCCLUSION() + COMMON_SRG_INPUTS_EMISSIVE() + COMMON_SRG_INPUTS_PARALLAX() + + uint m_parallaxUvIndex; + float m_parallax_pdo_shadowFactor; + + 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. + + float m_opacityFactor; + float m_opacityAffectsSpecularFactor; + Texture2D m_opacityMap; + uint m_opacityMapUvIndex; + + // Detail bending parameters + float m_detailFrequency; + float m_detailLeafAmplitude; + float m_detailBranchAmplitude; + + // Wind for bending. This would typically come from a wind system instead of a material property, but is here as a proof of concept. + float m_windX; + float m_windY; + float m_bendingStrength; + float m_windBendingFrequency; + + 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; + }; +} + +// Callback function for ParallaxMapping.azsli +DepthResult GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy) +{ + return SampleDepthFromHeightmap(MaterialSrg::m_heightmap, MaterialSrg::m_sampler, uv, uv_ddx, uv_ddy); +} + + +COMMON_OPTIONS_PARALLAX() + +bool ShouldHandleParallax() +{ + // Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scattering is enabled. + return !o_enableSubsurfaceScattering && o_parallax_feature_enabled && o_useHeightmap; +} + +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. + return ShouldHandleParallax() && (o_parallax_enablePixelDepthOffset || o_opacity_mode == OpacityMode::Cutout); +} + +option bool o_color_isBound; + +// Derived from "Vegetation Procedural Animation and Shading in Crysis" in GPU Gems 3 +// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-16-vegetation-procedural-animation-and-shading-crysis + +// These are per-object values. They would typically be updated on the CPU to avoid duplicated work, +// but for simplicity they are calculated here for each vertex as a proof of concept +float4 SetUpWindBending(float currentTime, float4 worldPosition) +{ + float2 wind = float2(MaterialSrg::m_windX, MaterialSrg::m_windY); + float bendingStrength = MaterialSrg::m_bendingStrength; + float2 amplitude = float2(wind.x * 0.4 + wind.y * 0.2, wind.y * 0.4 - wind.x * 0.2); + float2 frequency = float2(MaterialSrg::m_windBendingFrequency, MaterialSrg::m_windBendingFrequency * 1.125); + // Using the world position to modify the phase makes it so different trees near each other are at similar but not equal points in the animation, + // so they appear to be reacting to the same wind but at different times as the wind moves through the vegetation. + float2 phase = worldPosition.xy * 0.08; + + float2 bendAmount = sin(currentTime * frequency + phase) * amplitude; + + float4 result; + result.xy = bendAmount + wind; + result.z = length(wind); + result.w = 0.3 * length(result.xy); + result.xyz *= bendingStrength * 0.08; + + return result; +} + +float3 DetailBending(float3 objectSpacePosition, float3 normal, float4 detailBendingParams, float currentTime, float4 worldPosition, float bendLength) +{ + // The information from the vertex colors about how to bend this vertex. + float edgeInfo = detailBendingParams.x; + float branchPhase = detailBendingParams.y; + float branchBendAmount = detailBendingParams.z; + + // Phases (object, vertex, branch) + float objPhase = dot(worldPosition.xyz, 2.0); + branchPhase += objPhase; + float vtxPhase = dot(objectSpacePosition, branchPhase); + + // Detail bending for leaves + // x: is used for leaves, y is used for branch + float2 wavesIn = currentTime; + wavesIn += float2(vtxPhase, branchPhase); + float4 waves = (frac(wavesIn.xxyy * float4(1.975, 0.793, 0.375, 0.193)) * 2.0 - 1.0) * MaterialSrg::m_detailFrequency * bendLength; + waves = abs(frac(waves + 0.5) * 2.0 - 1.0); + + // x: is used for leaves, y is used for branches + float2 wavesSum = waves.xz + waves.yw; + + // Leaf and branch bending (xy is used for leaves, z for branches) + float3 movement = wavesSum.xxy * float3(edgeInfo * MaterialSrg::m_detailLeafAmplitude * normal.xy, branchBendAmount * MaterialSrg::m_detailBranchAmplitude); + return objectSpacePosition + movement; +} + +float3 MainBending(float3 objectSpacePosition, float4 bending) +{ + float windX = bending.x; + float windY = bending.y; + float bendScale = bending.z; + + // More bending occurs higher up on the object + float bendFactor = objectSpacePosition.z * bendScale; + bendFactor *= bendFactor; + + // Rescale the displaced vertex position with the original distance to the object's center + // to restrict vertex movement to minimize deformation artifacts + float len = length(objectSpacePosition); + float3 newPos = objectSpacePosition; + newPos.xy += float2(windX, windY) * bendFactor; + + return normalize(newPos) * len; +} + +float4 ProcessBending(float currentTime, float3 objectSpacePosition, float3 normal, float4 detailBendingParams, float4 worldPosition, float4x4 objectToWorld) +{ + float4 adjustedWorldPosition = float4(worldPosition); + if (o_color_isBound) + { + // Overall wind + float4 currentBending = SetUpWindBending(currentTime, worldPosition); + + // Detail bending + float3 currentOutPosition = DetailBending(objectSpacePosition, normal, detailBendingParams, currentTime, worldPosition, currentBending.w); + + currentOutPosition = MainBending(currentOutPosition, currentBending); + + adjustedWorldPosition = mul(objectToWorld, float4(currentOutPosition, 1.0)); + } + return adjustedWorldPosition; +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.azsl b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.azsl new file mode 100644 index 0000000..47ec5e9 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.azsl @@ -0,0 +1,14 @@ +/* + * 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 +#include + +#include + +// Use the depth pass shader with the default object srg diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.azsli b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.azsli new file mode 100644 index 0000000..8c6e796 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.azsli @@ -0,0 +1,39 @@ +/* + * 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 +#include + +struct VSInput +{ + float3 m_position : POSITION; + float3 m_normal : NORMAL; + + float4 m_optional_color : COLOR0; +}; + +struct VSDepthOutput +{ + precise float4 m_position : SV_Position; +}; + +VSDepthOutput DepthPassVS(VSInput IN) +{ + VSDepthOutput OUT; + + float4x4 objectToWorld = ObjectSrg::GetWorldMatrix(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float currentTime = SceneSrg::m_time; + worldPosition = ProcessBending(currentTime, IN.m_position, IN.m_normal, IN.m_optional_color, worldPosition, objectToWorld); + + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + return OUT; +} \ No newline at end of file diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.shader b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.shader new file mode 100644 index 0000000..5cd5fb4 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass.shader @@ -0,0 +1,20 @@ +{ + "Source" : "./VegetationBending_DepthPass.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "ProgramSettings" : + { + "EntryPoints": + [ + { + "name": "DepthPassVS", + "type" : "Vertex" + } + ] + }, + + "DrawList" : "depth" +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.azsl b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.azsl new file mode 100644 index 0000000..6746fe8 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.azsl @@ -0,0 +1,21 @@ +/* + * 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 "./VegetationBending_Common.azsli" +#include + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli" + +#define ENABLE_ALPHA_CLIP 1 +#include "Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli" +#include "VegetationBending_DepthPass_WithPS.azsli" diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.azsli b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.azsli new file mode 100644 index 0000000..0a79abe --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.azsli @@ -0,0 +1,52 @@ +/* + * 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 + * + */ + +#ifndef ENABLE_ALPHA_CLIP +#define ENABLE_ALPHA_CLIP 0 +#endif + +struct VegetationVSInput +{ + 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; + + float4 m_optional_color : COLOR0; +}; + +VSDepthOutput VegetationVS(VegetationVSInput IN) +{ + VSDepthOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float2 uvs[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uvs, OUT.m_uv); + + if(ShouldHandleParallaxInDepthShaders()) + { + OUT.m_worldPosition = worldPosition.xyz; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + } + + float currentTime = SceneSrg::m_time; + worldPosition = ProcessBending(currentTime, IN.m_position, IN.m_normal, IN.m_optional_color, worldPosition, objectToWorld); + + OUT.m_worldPosition = worldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + return OUT; +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.shader b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.shader new file mode 100644 index 0000000..1492817 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_DepthPass_WithPS.shader @@ -0,0 +1,24 @@ +{ + "Source" : "./VegetationBending_DepthPass_WithPS.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + }, + + "DrawList" : "depth" +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.azsl b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.azsl new file mode 100644 index 0000000..d210beb --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.azsl @@ -0,0 +1,40 @@ +/* + * 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 "VegetationBending_Common.azsli" + +#include + +#include + +// ---------- Material Parameters ---------- + +COMMON_OPTIONS_BASE_COLOR() +COMMON_OPTIONS_ROUGHNESS() +COMMON_OPTIONS_METALLIC() +COMMON_OPTIONS_SPECULAR_F0() +COMMON_OPTIONS_NORMAL() +COMMON_OPTIONS_CLEAR_COAT() +COMMON_OPTIONS_OCCLUSION() +COMMON_OPTIONS_EMISSIVE() +// Note COMMON_OPTIONS_PARALLAX is in StandardPBR_Common.azsli because it's needed by all StandardPBR shaders. + +// Alpha +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/AlphaInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli" + +#include "Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsli" +#include "VegetationBending_ForwardPass.azsli" \ No newline at end of file diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.azsli b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.azsli new file mode 100644 index 0000000..21bdc56 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.azsli @@ -0,0 +1,51 @@ +/* + * 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 + * + */ + +// ---------- Vertex Shader ---------- + +struct VegetationVSInput +{ + // Base fields (required by the template azsli file)... + float3 m_position : POSITION; + float3 m_normal : NORMAL; + float4 m_tangent : TANGENT; + float3 m_bitangent : BITANGENT; + float4 m_optional_color : COLOR0; + + // Extended fields (only referenced in this azsl file)... + float2 m_uv0 : UV0; + float2 m_uv1 : UV1; +}; + + +#include + +VSOutput VegetationBending_ForwardPassVS(VegetationVSInput IN) +{ + VSOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float2 uvs[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uvs, OUT.m_uv); + + // Shadow coords will be calculated in the pixel shader in this case + bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + + float currentTime = SceneSrg::m_time; + worldPosition = ProcessBending(currentTime, IN.m_position, IN.m_normal, IN.m_optional_color, worldPosition, objectToWorld); + + OUT.m_worldPosition = worldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + return OUT; +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.shader b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.shader new file mode 100644 index 0000000..de448ce --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass.shader @@ -0,0 +1,50 @@ +{ + "Source" : "./VegetationBending_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" + } + } + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationBending_ForwardPassVS", + "type": "Vertex" + }, + { + "name": "StandardPbr_ForwardPassPS", + "type": "Fragment" + } + ] + }, + + "DrawList" : "forward" +} + diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass_EDS.shader b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass_EDS.shader new file mode 100644 index 0000000..7593fdb --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ForwardPass_EDS.shader @@ -0,0 +1,49 @@ +{ + "Source" : "./VegetationBending_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" + } + } + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationBending_ForwardPassVS", + "type": "Vertex" + }, + { + "name": "StandardPbr_ForwardPassPS_EDS", + "type": "Fragment" + } + ] + }, + + "DrawList" : "forward" +} diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ShaderEnable.lua b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ShaderEnable.lua new file mode 100644 index 0000000..0395bc0 --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_ShaderEnable.lua @@ -0,0 +1,58 @@ +-------------------------------------------------------------------------------------- +-- +-- 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 +-- +-- +-- +---------------------------------------------------------------------------------------------------- + +function GetMaterialPropertyDependencies() + return {"opacity.mode", "parallax.textureMap", "parallax.useTexture", "parallax.pdo"} +end + +OpacityMode_Opaque = 0 +OpacityMode_Cutout = 1 +OpacityMode_Blended = 2 +OpacityMode_TintedTransparent = 3 + +function Process(context) + + local opacityMode = OpacityMode_Opaque + if context:HasMaterialProperty("opacity.mode") then + opacityMode = context:GetMaterialPropertyValue_enum("opacity.mode") + end + + local displacementMap = context:GetMaterialPropertyValue_Image("parallax.textureMap") + local useDisplacementMap = context:GetMaterialPropertyValue_bool("parallax.useTexture") + local parallaxEnabled = displacementMap ~= nil and useDisplacementMap + local parallaxPdoEnabled = context:GetMaterialPropertyValue_bool("parallax.pdo") + + local depthPass = context:GetShaderByTag("DepthPass") + local shadowMap = context:GetShaderByTag("Shadowmap") + local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS") + + local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS") + local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS") + local forwardPass = context:GetShaderByTag("ForwardPass") + + if parallaxEnabled and parallaxPdoEnabled then + depthPass:SetEnabled(false) + shadowMap:SetEnabled(false) + forwardPassEDS:SetEnabled(false) + + depthPassWithPS:SetEnabled(true) + shadowMapWithPS:SetEnabled(true) + forwardPass:SetEnabled(true) + else + depthPass:SetEnabled(opacityMode == OpacityMode_Opaque) + shadowMap:SetEnabled(opacityMode == OpacityMode_Opaque) + forwardPassEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent)) + + depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout) + shadowMapWithPS:SetEnabled(opacityMode == OpacityMode_Cutout) + forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout) + end +end diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Shadowmap_WithPS.azsl b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Shadowmap_WithPS.azsl new file mode 100644 index 0000000..d4bf33c --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Shadowmap_WithPS.azsl @@ -0,0 +1,27 @@ +/* + * 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 + * + */ + +#define SHADOWMAP 1 +#define ENABLE_ALPHA_CLIP 1 + +#include +#include "VegetationBending_Common.azsli" +#include + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/AlphaInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli" + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli" + +#include "Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli" +#include "VegetationBending_DepthPass_WithPS.azsli" diff --git a/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Shadowmap_WithPS.shader b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Shadowmap_WithPS.shader new file mode 100644 index 0000000..11c24db --- /dev/null +++ b/atom_gems/AtomTutorials/Assets/VegetationBending/VegetationBending_Shadowmap_WithPS.shader @@ -0,0 +1,32 @@ +{ + "Source" : "./VegetationBending_Shadowmap_WithPS.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "LessEqual" } + }, + + "DrawList" : "shadow", + + // Note that lights now expose their own bias controls. + // It may be worth increasing their default values in the future and reducing the depthBias values encoded here. + "RasterState" : + { + "depthBias" : "10", + "depthBiasSlopeScale" : "4" + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + } +} diff --git a/atom_gems/AtomTutorials/CMakeLists.txt b/atom_gems/AtomTutorials/CMakeLists.txt new file mode 100644 index 0000000..b2dc9d8 --- /dev/null +++ b/atom_gems/AtomTutorials/CMakeLists.txt @@ -0,0 +1,10 @@ + +set(gem_path ${CMAKE_CURRENT_LIST_DIR}) +set(gem_json ${gem_path}/gem.json) +o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path) + +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}") + +ly_add_external_target_path(${CMAKE_CURRENT_LIST_DIR}/3rdParty) + +add_subdirectory(Code) diff --git a/atom_gems/AtomTutorials/Code/CMakeLists.txt b/atom_gems/AtomTutorials/Code/CMakeLists.txt new file mode 100644 index 0000000..15ea291 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/CMakeLists.txt @@ -0,0 +1,184 @@ + +o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}") + +# The AtomTutorials.API target declares the common interface that users of this gem should depend on in their targets +ly_add_target( + NAME AtomTutorials.API INTERFACE + NAMESPACE Gem + FILES_CMAKE + atomtutorials_api_files.cmake + INCLUDE_DIRECTORIES + INTERFACE + Include + BUILD_DEPENDENCIES + INTERFACE + AZ::AzCore +) + +# The AtomTutorials.Private.Object target is an internal target +# It should not be used outside of this Gems CMakeLists.txt +ly_add_target( + NAME AtomTutorials.Private.Object STATIC + NAMESPACE Gem + FILES_CMAKE + atomtutorials_private_files.cmake + TARGET_PROPERTIES + O3DE_PRIVATE_TARGET TRUE + INCLUDE_DIRECTORIES + PRIVATE + Include + Source + BUILD_DEPENDENCIES + PUBLIC + AZ::AzCore + AZ::AzFramework +) + +# Here add AtomTutorials target, it depends on the Private Object library and Public API interface +ly_add_target( + NAME AtomTutorials ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} + NAMESPACE Gem + FILES_CMAKE + atomtutorials_shared_files.cmake + INCLUDE_DIRECTORIES + PUBLIC + Include + PRIVATE + Source + BUILD_DEPENDENCIES + PUBLIC + Gem::AtomTutorials.API + PRIVATE + Gem::AtomTutorials.Private.Object +) + +# By default, we will specify that the above target AtomTutorials would be used by +# Client and Server type targets when this gem is enabled. If you don't want it +# active in Clients or Servers by default, delete one of both of the following lines: +ly_create_alias(NAME AtomTutorials.Clients NAMESPACE Gem TARGETS Gem::AtomTutorials) +ly_create_alias(NAME AtomTutorials.Servers NAMESPACE Gem TARGETS Gem::AtomTutorials) + +# For the Client and Server variants of AtomTutorials Gem, an alias to the AtomTutorials.API target will be made +ly_create_alias(NAME AtomTutorials.Clients.API NAMESPACE Gem TARGETS Gem::AtomTutorials.API) +ly_create_alias(NAME AtomTutorials.Servers.API NAMESPACE Gem TARGETS Gem::AtomTutorials.API) + +# If we are on a host platform, we want to add the host tools targets like the AtomTutorials.Editor MODULE target +if(PAL_TRAIT_BUILD_HOST_TOOLS) + # The AtomTutorials.Editor.API target can be used by other gems that want to interact with the AtomTutorials.Editor module + ly_add_target( + NAME AtomTutorials.Editor.API INTERFACE + NAMESPACE Gem + FILES_CMAKE + atomtutorials_editor_api_files.cmake + INCLUDE_DIRECTORIES + INTERFACE + Include + BUILD_DEPENDENCIES + INTERFACE + AZ::AzToolsFramework + ) + + # The AtomTutorials.Editor.Private.Object target is an internal target + # which is only to be used by this gems CMakeLists.txt and any subdirectories + # Other gems should not use this target + ly_add_target( + NAME AtomTutorials.Editor.Private.Object STATIC + NAMESPACE Gem + AUTOMOC + AUTORCC + FILES_CMAKE + atomtutorials_editor_private_files.cmake + TARGET_PROPERTIES + O3DE_PRIVATE_TARGET TRUE + INCLUDE_DIRECTORIES + PRIVATE + Include + Source + BUILD_DEPENDENCIES + PUBLIC + AZ::AzToolsFramework + $ + ) + + ly_add_target( + NAME AtomTutorials.Editor GEM_MODULE + NAMESPACE Gem + AUTOMOC + FILES_CMAKE + atomtutorials_editor_shared_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Source + PUBLIC + Include + BUILD_DEPENDENCIES + PUBLIC + Gem::AtomTutorials.Editor.API + PRIVATE + Gem::AtomTutorials.Editor.Private.Object + ) + + # By default, we will specify that the above target AtomTutorials would be used by + # Tool and Builder type targets when this gem is enabled. If you don't want it + # active in Tools or Builders by default, delete one of both of the following lines: + ly_create_alias(NAME AtomTutorials.Tools NAMESPACE Gem TARGETS Gem::AtomTutorials.Editor) + ly_create_alias(NAME AtomTutorials.Builders NAMESPACE Gem TARGETS Gem::AtomTutorials.Editor) + + # For the Tools and Builders variants of AtomTutorials Gem, an alias to the AtomTutorials.Editor API target will be made + ly_create_alias(NAME AtomTutorials.Tools.API NAMESPACE Gem TARGETS Gem::AtomTutorials.Editor.API) + ly_create_alias(NAME AtomTutorials.Builders.API NAMESPACE Gem TARGETS Gem::AtomTutorials.Editor.API) + +endif() + +################################################################################ +# Tests +################################################################################ +# See if globally, tests are supported +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) + # We support AtomTutorials.Tests on this platform, add dependency on the Private Object target + ly_add_target( + NAME AtomTutorials.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE Gem + FILES_CMAKE + atomtutorials_tests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + Source + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + AZ::AzFramework + Gem::AtomTutorials.Private.Object + ) + + # Add AtomTutorials.Tests to googletest + ly_add_googletest( + NAME Gem::AtomTutorials.Tests + ) + + # If we are a host platform we want to add tools test like editor tests here + if(PAL_TRAIT_BUILD_HOST_TOOLS) + # We support AtomTutorials.Editor.Tests on this platform, add AtomTutorials.Editor.Tests target which depends on + # private AtomTutorials.Editor.Private.Object target + ly_add_target( + NAME AtomTutorials.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE Gem + FILES_CMAKE + atomtutorials_editor_tests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + Source + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + Gem::AtomTutorials.Private.Object + ) + + # Add AtomTutorials.Editor.Tests to googletest + ly_add_googletest( + NAME Gem::AtomTutorials.Editor.Tests + ) + endif() +endif() diff --git a/atom_gems/AtomTutorials/Code/Source/AtomTutorialsModuleInterface.h b/atom_gems/AtomTutorials/Code/Source/AtomTutorialsModuleInterface.h new file mode 100644 index 0000000..51488db --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/AtomTutorialsModuleInterface.h @@ -0,0 +1,36 @@ + +#include +#include +#include + +namespace AtomTutorials +{ + class AtomTutorialsModuleInterface + : public AZ::Module + { + public: + AZ_RTTI(AtomTutorialsModuleInterface, "{553B66F8-E05B-450B-81D2-3D5139B60B8A}", AZ::Module); + AZ_CLASS_ALLOCATOR(AtomTutorialsModuleInterface, AZ::SystemAllocator, 0); + + AtomTutorialsModuleInterface() + { + // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. + // Add ALL components descriptors associated with this gem to m_descriptors. + // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and EditContext. + // This happens through the [MyComponent]::Reflect() function. + m_descriptors.insert(m_descriptors.end(), { + AtomTutorialsSystemComponent::CreateDescriptor(), + }); + } + + /** + * Add required SystemComponents to the SystemEntity. + */ + AZ::ComponentTypeList GetRequiredSystemComponents() const override + { + return AZ::ComponentTypeList{ + azrtti_typeid(), + }; + } + }; +}// namespace AtomTutorials diff --git a/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsModule.cpp b/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsModule.cpp new file mode 100644 index 0000000..1e2da51 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsModule.cpp @@ -0,0 +1,16 @@ + +#include +#include "AtomTutorialsSystemComponent.h" + +namespace AtomTutorials +{ + class AtomTutorialsModule + : public AtomTutorialsModuleInterface + { + public: + AZ_RTTI(AtomTutorialsModule, "{C96BD29A-15A9-4C5F-8076-4C4DB113A5FE}", AtomTutorialsModuleInterface); + AZ_CLASS_ALLOCATOR(AtomTutorialsModule, AZ::SystemAllocator, 0); + }; +}// namespace AtomTutorials + +AZ_DECLARE_MODULE_CLASS(Gem_AtomTutorials, AtomTutorials::AtomTutorialsModule) diff --git a/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsSystemComponent.cpp b/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsSystemComponent.cpp new file mode 100644 index 0000000..e0b99d1 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsSystemComponent.cpp @@ -0,0 +1,59 @@ + +#include "AtomTutorialsSystemComponent.h" + +#include +#include +#include + +namespace AtomTutorials +{ + void AtomTutorialsSystemComponent::Reflect(AZ::ReflectContext* context) + { + if (AZ::SerializeContext* serialize = azrtti_cast(context)) + { + serialize->Class() + ->Version(0) + ; + + if (AZ::EditContext* ec = serialize->GetEditContext()) + { + ec->Class("AtomTutorials", "[Description of functionality provided by this System Component]") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System")) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ; + } + } + } + + void AtomTutorialsSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("AtomTutorialsService")); + } + + void AtomTutorialsSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC_CE("AtomTutorialsService")); + } + + void AtomTutorialsSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) + { + } + + void AtomTutorialsSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + } + + void AtomTutorialsSystemComponent::Init() + { + } + + void AtomTutorialsSystemComponent::Activate() + { + } + + void AtomTutorialsSystemComponent::Deactivate() + { + } + +} // namespace AtomTutorials diff --git a/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsSystemComponent.h b/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsSystemComponent.h new file mode 100644 index 0000000..c61f232 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Clients/AtomTutorialsSystemComponent.h @@ -0,0 +1,31 @@ + +#pragma once + +#include + +namespace AtomTutorials +{ + class AtomTutorialsSystemComponent + : public AZ::Component + { + public: + AZ_COMPONENT(AtomTutorialsSystemComponent, "{301F9A4A-0D92-4E7C-9D8B-41DF80624A18}"); + + static void Reflect(AZ::ReflectContext* context); + + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); + + protected: + + //////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Init() override; + void Activate() override; + void Deactivate() override; + //////////////////////////////////////////////////////////////////////// + }; + +} // namespace AtomTutorials diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorials.qrc b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorials.qrc new file mode 100644 index 0000000..6192638 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorials.qrc @@ -0,0 +1,5 @@ + + + toolbar_icon.svg + + diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorModule.cpp b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorModule.cpp new file mode 100644 index 0000000..2fffb14 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorModule.cpp @@ -0,0 +1,46 @@ + +#include +#include "AtomTutorialsEditorSystemComponent.h" + +void InitAtomTutorialsResources() +{ + // We must register our Qt resources (.qrc file) since this is being loaded from a separate module (gem) + Q_INIT_RESOURCE(AtomTutorials); +} + +namespace AtomTutorials +{ + class AtomTutorialsEditorModule + : public AtomTutorialsModuleInterface + { + public: + AZ_RTTI(AtomTutorialsEditorModule, "{C96BD29A-15A9-4C5F-8076-4C4DB113A5FE}", AtomTutorialsModuleInterface); + AZ_CLASS_ALLOCATOR(AtomTutorialsEditorModule, AZ::SystemAllocator, 0); + + AtomTutorialsEditorModule() + { + InitAtomTutorialsResources(); + + // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. + // Add ALL components descriptors associated with this gem to m_descriptors. + // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and EditContext. + // This happens through the [MyComponent]::Reflect() function. + m_descriptors.insert(m_descriptors.end(), { + AtomTutorialsEditorSystemComponent::CreateDescriptor(), + }); + } + + /** + * Add required SystemComponents to the SystemEntity. + * Non-SystemComponents should not be added here + */ + AZ::ComponentTypeList GetRequiredSystemComponents() const override + { + return AZ::ComponentTypeList { + azrtti_typeid(), + }; + } + }; +}// namespace AtomTutorials + +AZ_DECLARE_MODULE_CLASS(Gem_AtomTutorials, AtomTutorials::AtomTutorialsEditorModule) diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorSystemComponent.cpp b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorSystemComponent.cpp new file mode 100644 index 0000000..de71a23 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorSystemComponent.cpp @@ -0,0 +1,69 @@ + +#include + +#include + +#include "AtomTutorialsWidget.h" +#include "AtomTutorialsEditorSystemComponent.h" + +namespace AtomTutorials +{ + void AtomTutorialsEditorSystemComponent::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0); + } + } + + AtomTutorialsEditorSystemComponent::AtomTutorialsEditorSystemComponent() = default; + + AtomTutorialsEditorSystemComponent::~AtomTutorialsEditorSystemComponent() = default; + + void AtomTutorialsEditorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + BaseSystemComponent::GetProvidedServices(provided); + provided.push_back(AZ_CRC_CE("AtomTutorialsEditorService")); + } + + void AtomTutorialsEditorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + BaseSystemComponent::GetIncompatibleServices(incompatible); + incompatible.push_back(AZ_CRC_CE("AtomTutorialsEditorService")); + } + + void AtomTutorialsEditorSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) + { + BaseSystemComponent::GetRequiredServices(required); + } + + void AtomTutorialsEditorSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent) + { + BaseSystemComponent::GetDependentServices(dependent); + } + + void AtomTutorialsEditorSystemComponent::Activate() + { + AtomTutorialsSystemComponent::Activate(); + AzToolsFramework::EditorEvents::Bus::Handler::BusConnect(); + } + + void AtomTutorialsEditorSystemComponent::Deactivate() + { + AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); + AtomTutorialsSystemComponent::Deactivate(); + } + + void AtomTutorialsEditorSystemComponent::NotifyRegisterViews() + { + AzToolsFramework::ViewPaneOptions options; + options.paneRect = QRect(100, 100, 500, 400); + options.showOnToolsToolbar = true; + options.toolbarIcon = ":/AtomTutorials/toolbar_icon.svg"; + + // Register our custom widget as a dockable tool with the Editor under an Examples sub-menu + AzToolsFramework::RegisterViewPane("AtomTutorials", "Examples", options); + } + +} // namespace AtomTutorials diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorSystemComponent.h b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorSystemComponent.h new file mode 100644 index 0000000..a34783a --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsEditorSystemComponent.h @@ -0,0 +1,36 @@ + +#pragma once + +#include + +#include + +namespace AtomTutorials +{ + /// System component for AtomTutorials editor + class AtomTutorialsEditorSystemComponent + : public AtomTutorialsSystemComponent + , private AzToolsFramework::EditorEvents::Bus::Handler + { + using BaseSystemComponent = AtomTutorialsSystemComponent; + public: + AZ_COMPONENT(AtomTutorialsEditorSystemComponent, "{DEB4D116-5835-4C7D-8130-35A69F29EB39}", BaseSystemComponent); + static void Reflect(AZ::ReflectContext* context); + + AtomTutorialsEditorSystemComponent(); + ~AtomTutorialsEditorSystemComponent(); + + private: + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); + static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); + + // AZ::Component + void Activate() override; + void Deactivate() override; + + // AzToolsFramework::EditorEventsBus overrides ... + void NotifyRegisterViews() override; + }; +} // namespace AtomTutorials diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsWidget.cpp b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsWidget.cpp new file mode 100644 index 0000000..23f233f --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsWidget.cpp @@ -0,0 +1,33 @@ + +#include + +#include +#include + +#include "AtomTutorialsWidget.h" + +namespace AtomTutorials +{ + AtomTutorialsWidget::AtomTutorialsWidget(QWidget* parent) + : QWidget(parent) + { + QVBoxLayout* mainLayout = new QVBoxLayout(this); + + QLabel* introLabel = new QLabel(QObject::tr("Put your cool stuff here!"), this); + mainLayout->addWidget(introLabel, 0, Qt::AlignCenter); + + QString helpText = QString( + "For help getting started, visit the UI Development documentation
or come ask a question in the sig-ui-ux channel on Discord"); + + QLabel* helpLabel = new QLabel(this); + helpLabel->setTextFormat(Qt::RichText); + helpLabel->setText(helpText); + helpLabel->setOpenExternalLinks(true); + + mainLayout->addWidget(helpLabel, 0, Qt::AlignCenter); + + setLayout(mainLayout); + } +} + +#include diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsWidget.h b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsWidget.h new file mode 100644 index 0000000..0858e4c --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/AtomTutorialsWidget.h @@ -0,0 +1,19 @@ + +#pragma once + +#if !defined(Q_MOC_RUN) +#include + +#include +#endif + +namespace AtomTutorials +{ + class AtomTutorialsWidget + : public QWidget + { + Q_OBJECT + public: + explicit AtomTutorialsWidget(QWidget* parent = nullptr); + }; +} diff --git a/atom_gems/AtomTutorials/Code/Source/Tools/toolbar_icon.svg b/atom_gems/AtomTutorials/Code/Source/Tools/toolbar_icon.svg new file mode 100644 index 0000000..59de669 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Source/Tools/toolbar_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/atom_gems/AtomTutorials/Code/Tests/Clients/AtomTutorialsTest.cpp b/atom_gems/AtomTutorials/Code/Tests/Clients/AtomTutorialsTest.cpp new file mode 100644 index 0000000..274a990 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Tests/Clients/AtomTutorialsTest.cpp @@ -0,0 +1,4 @@ + +#include + +AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/atom_gems/AtomTutorials/Code/Tests/Tools/AtomTutorialsEditorTest.cpp b/atom_gems/AtomTutorials/Code/Tests/Tools/AtomTutorialsEditorTest.cpp new file mode 100644 index 0000000..274a990 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/Tests/Tools/AtomTutorialsEditorTest.cpp @@ -0,0 +1,4 @@ + +#include + +AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_api_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_api_files.cmake new file mode 100644 index 0000000..f5526ee --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_api_files.cmake @@ -0,0 +1,3 @@ + +set(FILES +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_editor_api_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_editor_api_files.cmake new file mode 100644 index 0000000..8cd37a5 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_editor_api_files.cmake @@ -0,0 +1,4 @@ + + +set(FILES +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_editor_private_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_editor_private_files.cmake new file mode 100644 index 0000000..6b5df74 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_editor_private_files.cmake @@ -0,0 +1,8 @@ + +set(FILES + Source/Tools/AtomTutorialsEditorSystemComponent.cpp + Source/Tools/AtomTutorialsEditorSystemComponent.h + Source/Tools/AtomTutorialsWidget.cpp + Source/Tools/AtomTutorialsWidget.h + Source/Tools/AtomTutorials.qrc +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_editor_shared_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_editor_shared_files.cmake new file mode 100644 index 0000000..c140053 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_editor_shared_files.cmake @@ -0,0 +1,4 @@ + +set(FILES + Source/Tools/AtomTutorialsEditorModule.cpp +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_editor_tests_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_editor_tests_files.cmake new file mode 100644 index 0000000..4e1bf61 --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_editor_tests_files.cmake @@ -0,0 +1,4 @@ + +set(FILES + Tests/Tools/AtomTutorialsEditorTest.cpp +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_private_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_private_files.cmake new file mode 100644 index 0000000..d52d38f --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_private_files.cmake @@ -0,0 +1,6 @@ + +set(FILES + Source/AtomTutorialsModuleInterface.h + Source/Clients/AtomTutorialsSystemComponent.cpp + Source/Clients/AtomTutorialsSystemComponent.h +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_shared_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_shared_files.cmake new file mode 100644 index 0000000..21e09ed --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_shared_files.cmake @@ -0,0 +1,4 @@ + +set(FILES + Source/Clients/AtomTutorialsModule.cpp +) diff --git a/atom_gems/AtomTutorials/Code/atomtutorials_tests_files.cmake b/atom_gems/AtomTutorials/Code/atomtutorials_tests_files.cmake new file mode 100644 index 0000000..009607d --- /dev/null +++ b/atom_gems/AtomTutorials/Code/atomtutorials_tests_files.cmake @@ -0,0 +1,4 @@ + +set(FILES + Tests/Clients/AtomTutorialsTest.cpp +) diff --git a/atom_gems/AtomTutorials/Registry/assetprocessor_settings.setreg b/atom_gems/AtomTutorials/Registry/assetprocessor_settings.setreg new file mode 100644 index 0000000..17d9bf1 --- /dev/null +++ b/atom_gems/AtomTutorials/Registry/assetprocessor_settings.setreg @@ -0,0 +1,18 @@ +{ + "Amazon": { + "AssetProcessor": { + "Settings": { + "ScanFolder AtomTutorials/Assets": { + "watch": "@GEMROOT:AtomTutorials@/Assets", + "recursive": 1, + "order": 101 + }, + "ScanFolder AtomTutorials/Registry": { + "watch": "@GEMROOT:AtomTutorials@/Registry", + "recursive": 1, + "order": 102 + } + } + } + } +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/MeshMotionVectorVegetationBending.azsl b/atom_gems/AtomTutorials/Templates/VegetationBending/MeshMotionVectorVegetationBending.azsl new file mode 100644 index 0000000..5258a45 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/MeshMotionVectorVegetationBending.azsl @@ -0,0 +1,72 @@ +/* + * 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 +#include + +#include +#include + +#include + +struct VSInput +{ + float3 m_position : POSITION; + float3 m_normal : NORMAL; + + float4 m_optional_color : COLOR0; +}; + +struct VSOutput +{ + float4 m_position : SV_Position; + float3 m_worldPos : TEXCOORD0; + float3 m_worldPosPrev: TEXCOORD1; +}; + +struct PSOutput +{ + float2 m_motion : SV_Target0; +}; + +VSOutput MainVS(VSInput IN) +{ + VSOutput OUT; + + float4x4 objectToWorld = SceneSrg::GetObjectToWorldMatrix(ObjectSrg::m_objectId); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float4x4 prevObjectToWorld = SceneSrg::GetObjectToWorldMatrixPrev(ObjectSrg::m_objectId); + float4 prevWorldPosition = mul(prevObjectToWorld, float4(IN.m_position, 1.0)); + + OUT.m_worldPos = worldPosition.xyz; + OUT.m_worldPosPrev = prevWorldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + return OUT; +} + +PSOutput MainPS(VSOutput IN) +{ + PSOutput OUT; + + // Current clip position + float4 clipPos = mul(ViewSrg::m_viewProjectionMatrix, float4(IN.m_worldPos, 1.0)); + + // Reprojected last frame's clip position, for skinned mesh it also implies last key frame + float4 clipPosPrev = mul(ViewSrg::m_viewProjectionPrevMatrix, float4(IN.m_worldPosPrev, 1.0)); + + float2 motion = (clipPos.xy / clipPos.w - clipPosPrev.xy / clipPosPrev.w) * 0.5; + + OUT.m_motion = motion; + + // Flip y to line up with uv coordinates + OUT.m_motion.y = -OUT.m_motion.y; + + return OUT; +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/MeshMotionVectorVegetationBending.shader b/atom_gems/AtomTutorials/Templates/VegetationBending/MeshMotionVectorVegetationBending.shader new file mode 100644 index 0000000..d4f9263 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/MeshMotionVectorVegetationBending.shader @@ -0,0 +1,24 @@ +{ + "Source" : "MeshMotionVectorVegetationBending.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "DrawList" : "motion", + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "MainVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + } +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending.materialtype b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending.materialtype new file mode 100644 index 0000000..6f281bf --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending.materialtype @@ -0,0 +1,71 @@ +{ + "description": "Material Type like StandardPBR, but does bending for vegetation.", + "version": 1, + "propertyLayout": { + "propertyGroups": [ + // Currently we cannot import property groups across gems, so we are hard coding the full path, even though it is not portable, as a proof of concept. + // There is a GHI to enable importing across gems at https://github.com/o3de/o3de/issues/10623. + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/BaseColorPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/MetallicPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/RoughnessPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/SpecularPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/NormalPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/OcclusionPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/EmissivePropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/OpacityPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/UvPropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/IrradiancePropertyGroup.json" + }, + { + "$import": "{your-path-to-o3de}/o3de/Gems/Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/GeneralCommonPropertyGroup.json" + } + ] + }, + "shaders": [ + { + "file": "./VegetationBending_ForwardPass.shader", + "tag": "ForwardPass" + }, + { + "file": "./VegetationBending_ForwardPass_EDS.shader", + "tag": "ForwardPass_EDS" + }, + { + "file": "Shaders/Shadow/Shadowmap.shader", + "tag": "Shadowmap" + }, + { + "file": "./VegetationBending_DepthPass.shader", + "tag": "DepthPass" + } + ], + "uvNameMap": { + "UV0": "Tiled", + "UV1": "Unwrapped" + } +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBendingPropertyGroup.json b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBendingPropertyGroup.json new file mode 100644 index 0000000..cebbc4c --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBendingPropertyGroup.json @@ -0,0 +1,20 @@ +{ + "name": "vegetationBending", + "displayName": "Vegetation Bending", + "description": "Properties for configuring the bending.", + "properties": [ + { + "name": "xOffset", + "displayName": "xOffset", + "description": "The offset in the x direction.", + "type": "Float", + "defaultValue": 0.0, + "min": 0.0, + "max": 10.0, + "connection": { + "type": "ShaderInput", + "name": "m_xOffset" + } + } + ] +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Common.azsli b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Common.azsli new file mode 100644 index 0000000..7731b01 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Common.azsli @@ -0,0 +1,97 @@ +/* + * 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 +#include +#include +#include +#include + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/BaseColorInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/RoughnessInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/MetallicInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/SpecularInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/NormalInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ClearCoatInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/OcclusionInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/EmissiveInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/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() + COMMON_SRG_INPUTS_CLEAR_COAT() + COMMON_SRG_INPUTS_OCCLUSION() + COMMON_SRG_INPUTS_EMISSIVE() + COMMON_SRG_INPUTS_PARALLAX() + + uint m_parallaxUvIndex; + float m_parallax_pdo_shadowFactor; + + 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. + + float m_opacityFactor; + float m_opacityAffectsSpecularFactor; + Texture2D m_opacityMap; + uint m_opacityMapUvIndex; + + 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; + }; +} + +// Callback function for ParallaxMapping.azsli +DepthResult GetDepth(float2 uv, float2 uv_ddx, float2 uv_ddy) +{ + return SampleDepthFromHeightmap(MaterialSrg::m_heightmap, MaterialSrg::m_sampler, uv, uv_ddx, uv_ddy); +} + + +COMMON_OPTIONS_PARALLAX() + +bool ShouldHandleParallax() +{ + // Parallax mapping's non uniform uv transformations break screen space subsurface scattering, disable it when subsurface scattering is enabled. + return !o_enableSubsurfaceScattering && o_parallax_feature_enabled && o_useHeightmap; +} + +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. + return ShouldHandleParallax() && (o_parallax_enablePixelDepthOffset || o_opacity_mode == OpacityMode::Cutout); +} + diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.azsl b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.azsl new file mode 100644 index 0000000..47ec5e9 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.azsl @@ -0,0 +1,14 @@ +/* + * 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 +#include + +#include + +// Use the depth pass shader with the default object srg diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.azsli b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.azsli new file mode 100644 index 0000000..cbaf31c --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.azsli @@ -0,0 +1,35 @@ +/* + * 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 +#include + +struct VSInput +{ + float3 m_position : POSITION; + float3 m_normal : NORMAL; +}; + +struct VSDepthOutput +{ + precise float4 m_position : SV_Position; +}; + +VSDepthOutput DepthPassVS(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); + + return OUT; +} \ No newline at end of file diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.shader b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.shader new file mode 100644 index 0000000..5cd5fb4 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass.shader @@ -0,0 +1,20 @@ +{ + "Source" : "./VegetationBending_DepthPass.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "ProgramSettings" : + { + "EntryPoints": + [ + { + "name": "DepthPassVS", + "type" : "Vertex" + } + ] + }, + + "DrawList" : "depth" +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.azsl b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.azsl new file mode 100644 index 0000000..6746fe8 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.azsl @@ -0,0 +1,21 @@ +/* + * 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 "./VegetationBending_Common.azsli" +#include + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli" + +#define ENABLE_ALPHA_CLIP 1 +#include "Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli" +#include "VegetationBending_DepthPass_WithPS.azsli" diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.azsli b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.azsli new file mode 100644 index 0000000..b375fce --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.azsli @@ -0,0 +1,49 @@ +/* + * 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 + * + */ + +#ifndef ENABLE_ALPHA_CLIP +#define ENABLE_ALPHA_CLIP 0 +#endif + +struct VegetationVSInput +{ + 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; + + float4 m_optional_color : COLOR0; +}; + +VSDepthOutput VegetationVS(VSInput IN) +{ + VSDepthOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float2 uvs[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uvs, OUT.m_uv); + + if(ShouldHandleParallaxInDepthShaders()) + { + OUT.m_worldPosition = worldPosition.xyz; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + } + + OUT.m_worldPosition = worldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + return OUT; +} \ No newline at end of file diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.shader b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.shader new file mode 100644 index 0000000..1492817 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_DepthPass_WithPS.shader @@ -0,0 +1,24 @@ +{ + "Source" : "./VegetationBending_DepthPass_WithPS.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + }, + + "DrawList" : "depth" +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.azsl b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.azsl new file mode 100644 index 0000000..d210beb --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.azsl @@ -0,0 +1,40 @@ +/* + * 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 "VegetationBending_Common.azsli" + +#include + +#include + +// ---------- Material Parameters ---------- + +COMMON_OPTIONS_BASE_COLOR() +COMMON_OPTIONS_ROUGHNESS() +COMMON_OPTIONS_METALLIC() +COMMON_OPTIONS_SPECULAR_F0() +COMMON_OPTIONS_NORMAL() +COMMON_OPTIONS_CLEAR_COAT() +COMMON_OPTIONS_OCCLUSION() +COMMON_OPTIONS_EMISSIVE() +// Note COMMON_OPTIONS_PARALLAX is in StandardPBR_Common.azsli because it's needed by all StandardPBR shaders. + +// Alpha +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/AlphaInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateStandardSurface.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli" + +#include "Atom/Feature/Common/Assets/Materials/Types/StandardSurface_ForwardPass.azsli" +#include "VegetationBending_ForwardPass.azsli" \ No newline at end of file diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.azsli b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.azsli new file mode 100644 index 0000000..a5e7326 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.azsli @@ -0,0 +1,46 @@ +/* + * 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 + * + */ + +// ---------- Vertex Shader ---------- + +struct VegetationVSInput +{ + // 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; +}; + +#include + +VSOutput VegetationBending_ForwardPassVS(VegetationVSInput IN) +{ + VSOutput OUT; + + float4x4 objectToWorld = GetObjectToWorld(); + float4 worldPosition = mul(objectToWorld, float4(IN.m_position, 1.0)); + + float2 uvs[UvSetCount] = { IN.m_uv0, IN.m_uv1 }; + TransformUvs(uvs, OUT.m_uv); + + // Shadow coords will be calculated in the pixel shader in this case + bool skipShadowCoords = ShouldHandleParallax() && o_parallax_enablePixelDepthOffset; + + float3x3 objectToWorldIT = GetNormalToWorld(); + ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent, OUT.m_bitangent); + + OUT.m_worldPosition = worldPosition.xyz; + OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, worldPosition); + + return OUT; +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.shader b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.shader new file mode 100644 index 0000000..de448ce --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass.shader @@ -0,0 +1,50 @@ +{ + "Source" : "./VegetationBending_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" + } + } + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationBending_ForwardPassVS", + "type": "Vertex" + }, + { + "name": "StandardPbr_ForwardPassPS", + "type": "Fragment" + } + ] + }, + + "DrawList" : "forward" +} + diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass_EDS.shader b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass_EDS.shader new file mode 100644 index 0000000..7593fdb --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ForwardPass_EDS.shader @@ -0,0 +1,49 @@ +{ + "Source" : "./VegetationBending_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" + } + } + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationBending_ForwardPassVS", + "type": "Vertex" + }, + { + "name": "StandardPbr_ForwardPassPS_EDS", + "type": "Fragment" + } + ] + }, + + "DrawList" : "forward" +} diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ShaderEnable.lua b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ShaderEnable.lua new file mode 100644 index 0000000..0395bc0 --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_ShaderEnable.lua @@ -0,0 +1,58 @@ +-------------------------------------------------------------------------------------- +-- +-- 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 +-- +-- +-- +---------------------------------------------------------------------------------------------------- + +function GetMaterialPropertyDependencies() + return {"opacity.mode", "parallax.textureMap", "parallax.useTexture", "parallax.pdo"} +end + +OpacityMode_Opaque = 0 +OpacityMode_Cutout = 1 +OpacityMode_Blended = 2 +OpacityMode_TintedTransparent = 3 + +function Process(context) + + local opacityMode = OpacityMode_Opaque + if context:HasMaterialProperty("opacity.mode") then + opacityMode = context:GetMaterialPropertyValue_enum("opacity.mode") + end + + local displacementMap = context:GetMaterialPropertyValue_Image("parallax.textureMap") + local useDisplacementMap = context:GetMaterialPropertyValue_bool("parallax.useTexture") + local parallaxEnabled = displacementMap ~= nil and useDisplacementMap + local parallaxPdoEnabled = context:GetMaterialPropertyValue_bool("parallax.pdo") + + local depthPass = context:GetShaderByTag("DepthPass") + local shadowMap = context:GetShaderByTag("Shadowmap") + local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS") + + local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS") + local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS") + local forwardPass = context:GetShaderByTag("ForwardPass") + + if parallaxEnabled and parallaxPdoEnabled then + depthPass:SetEnabled(false) + shadowMap:SetEnabled(false) + forwardPassEDS:SetEnabled(false) + + depthPassWithPS:SetEnabled(true) + shadowMapWithPS:SetEnabled(true) + forwardPass:SetEnabled(true) + else + depthPass:SetEnabled(opacityMode == OpacityMode_Opaque) + shadowMap:SetEnabled(opacityMode == OpacityMode_Opaque) + forwardPassEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent)) + + depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout) + shadowMapWithPS:SetEnabled(opacityMode == OpacityMode_Cutout) + forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout) + end +end diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Shadowmap_WithPS.azsl b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Shadowmap_WithPS.azsl new file mode 100644 index 0000000..d4bf33c --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Shadowmap_WithPS.azsl @@ -0,0 +1,27 @@ +/* + * 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 + * + */ + +#define SHADOWMAP 1 +#define ENABLE_ALPHA_CLIP 1 + +#include +#include "VegetationBending_Common.azsli" +#include + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/AlphaInput.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialInputs/ParallaxInput.azsli" + +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetObjectToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetNormalToWorld.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardGetAlphaAndClip.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/StandardTransformUvs.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/EvaluateTangentFrame.azsli" +#include "Atom/Feature/Common/Assets/Materials/Types/MaterialFunctions/ParallaxDepth.azsli" + +#include "Atom/Feature/Common/Assets/Materials/Types/DepthPass_WithPS.azsli" +#include "VegetationBending_DepthPass_WithPS.azsli" diff --git a/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Shadowmap_WithPS.shader b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Shadowmap_WithPS.shader new file mode 100644 index 0000000..11c24db --- /dev/null +++ b/atom_gems/AtomTutorials/Templates/VegetationBending/VegetationBending_Shadowmap_WithPS.shader @@ -0,0 +1,32 @@ +{ + "Source" : "./VegetationBending_Shadowmap_WithPS.azsl", + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "LessEqual" } + }, + + "DrawList" : "shadow", + + // Note that lights now expose their own bias controls. + // It may be worth increasing their default values in the future and reducing the depthBias values encoded here. + "RasterState" : + { + "depthBias" : "10", + "depthBiasSlopeScale" : "4" + }, + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "VegetationVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + } +} diff --git a/atom_gems/AtomTutorials/gem.json b/atom_gems/AtomTutorials/gem.json new file mode 100644 index 0000000..5195b08 --- /dev/null +++ b/atom_gems/AtomTutorials/gem.json @@ -0,0 +1,21 @@ +{ + "gem_name": "AtomTutorials", + "display_name": "AtomTutorials", + "license": "Apache-2.0 or MIT", + "license_url": "https://github.com/o3de/sample-code-gems/blob/main/LICENSE.txt", + "origin": "Open 3D Engine - o3de.org", + "origin_url": "https://github.com/o3de/sample-code-gems", + "type": "Code", + "summary": "The AtomTutorials Gem provides the final results for the Atom tutorials.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "AtomTutorials" + ], + "icon_path": "preview.png", + "requirements": "This requires the Atom/Feature/Common gem.", + "documentation_url": "https://o3de.org/docs/learning-guide/tutorials/rendering/", + "dependencies": [], + "restricted": "AtomTutorials" +} diff --git a/atom_gems/AtomTutorials/preview.png b/atom_gems/AtomTutorials/preview.png new file mode 100644 index 0000000..83afae4 Binary files /dev/null and b/atom_gems/AtomTutorials/preview.png differ