123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /*
- * 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
- *
- */
- // Specular IBL reflection pipeline:
- // Stencil -> BlendWeight -> GlobalFullscreen -> RenderOuter -> RenderInner -> Composite
- // -----------
- //
- // This shader writes the blend weight of a particular probe to this location in the blend
- // weight texture. This is an additive operation since other overlapping probes will write
- // their blend weights here as well. Note that this shader only considers pixels stenciled
- // to the outer volumes. Inner volumes always blend at 100% so there is no need to write them
- // to the blend weight texture.
- #include <scenesrg_all.srgi>
- #include <viewsrg_all.srgi>
- #include "ReflectionProbeRenderObjectSrg.azsli"
- ShaderResourceGroup PassSrg : SRG_PerPass
- {
- Texture2DMS<float> m_depth;
- }
- #include "ReflectionCommon.azsli"
- // Vertex Shader
- struct VSInput
- {
- float3 m_position : POSITION;
- };
- struct VSOutput
- {
- float4 m_position : SV_Position;
- };
- VSOutput MainVS(VSInput vsInput)
- {
- VSOutput OUT;
- float3 positionWS = mul(ObjectSrg::GetWorldMatrix(), float4(vsInput.m_position, 1.0)).xyz;
- OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(positionWS, 1.0));
- return OUT;
- }
- // Pixel Shader
- struct PSOutput
- {
- float m_blendWeight : SV_Target0;
- };
- PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
- {
- // reconstruct world position from depth
- // Note: this is the world position of the rendered object covered by the volume, not the volume itself
- uint2 dimensions;
- uint samples;
- PassSrg::m_depth.GetDimensions(dimensions.x, dimensions.y, samples);
- float depth = PassSrg::m_depth.Load(IN.m_position.xy, sampleIndex).r;
- float3 positionWS = ReconstructWorldPositionFromDepth(IN.m_position.xy, depth, dimensions, sampleIndex).xyz;
- // make sure the pixel belongs to this probe volume
- // this is necessary since it could have the correct stencil value but actually reside
- // in another volume that's in between the camera and the volume we're rendering
- if (!ObbContainsPoint(ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_outerObbHalfLengths, positionWS))
- {
- discard;
- }
- // determine blend based on position with respect to the inner and outer AABBs
- // if it's inside the inner AABB it blends at 100%, otherwise it's the percentage of the distance between the inner/outer AABB
- float blendWeight = 1.0f;
- if (!ObbContainsPoint(ObjectSrg::GetWorldMatrixInverse(), ObjectSrg::m_innerObbHalfLengths, positionWS))
- {
- // not inside the inner AABB, so it's in between the inner and outer AABBs
- // compute blend amount based on the distance to the outer AABB
- blendWeight = ComputeLerpBetweenInnerOuterOBBs(
- (float3x4)ObjectSrg::GetWorldMatrixInverse(),
- ObjectSrg::m_innerObbHalfLengths,
- ObjectSrg::m_outerObbHalfLengths,
- positionWS);
- }
- // write the blend weight (additive) at this position for the probe volume
- PSOutput OUT;
- OUT.m_blendWeight = blendWeight;
- return OUT;
- }
|