EditorModeMask.azsl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/Features/SrgSemantics.azsli>
  9. #include <viewsrg_all.srgi>
  10. #include <scenesrg_all.srgi>
  11. ShaderResourceGroup ObjectSrg : SRG_PerObject
  12. {
  13. //! Id of this draw object for retrieval of transformation matrices.
  14. uint m_objectId;
  15. //! Returns the matrix for transforming points from Object Space to World Space.
  16. float4x4 GetWorldMatrix()
  17. {
  18. return SceneSrg::GetObjectToWorldMatrix(m_objectId);
  19. }
  20. }
  21. ShaderResourceGroup PassSrg : SRG_PerPass
  22. {
  23. //! The depth buffer data for existing fragments in the color buffer.
  24. Texture2D<float> m_existingDepth;
  25. //! Dimensions of depth buffer texture (xy is width and height, zw is 1/width and 1/height).
  26. float4 m_existingDepthDimensions;
  27. Sampler LinearSampler
  28. {
  29. MinFilter = Linear;
  30. MagFilter = Linear;
  31. MipFilter = Linear;
  32. AddressU = Clamp;
  33. AddressV = Clamp;
  34. AddressW = Clamp;
  35. };
  36. }
  37. struct VSInput
  38. {
  39. // Base fields (required by the template azsli file)...
  40. float3 m_position : POSITION;
  41. };
  42. struct VSOutput
  43. {
  44. // Base fields (required by the template azsli file)...
  45. // "centroid" is needed for SV_Depth to compile
  46. precise linear centroid float4 m_position : SV_Position;
  47. // Fragment depth
  48. float m_depth : UV0;
  49. };
  50. VSOutput MainVS(VSInput IN)
  51. {
  52. VSOutput OUT;
  53. const float3 worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz;
  54. OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0));
  55. // The existing depth buffer contents are the result of the resolved MSAA depth buffer so contain depth contributions
  56. // from surrounding sub-fragments so we need to pull the current fragment towards the viewer slightly in order to reduce
  57. // z fighting with the sub-fragment depth contributions
  58. OUT.m_position.z *= 1.01;
  59. // Fragment depth
  60. OUT.m_depth = OUT.m_position.z / OUT.m_position.w;
  61. return OUT;
  62. }
  63. struct PixelOutput
  64. {
  65. float2 m_mask : SV_Target0;
  66. };
  67. //! Returns the linearized depth of the specified non-linear depth value.
  68. float LinearizeDepth(const float depth)
  69. {
  70. return abs(((ViewSrg::GetFarZTimesNearZ()) / (ViewSrg::GetFarZMinusNearZ() * depth - ViewSrg::GetFarZ())));
  71. }
  72. PixelOutput MainPS(VSOutput IN)
  73. {
  74. PixelOutput OUT;
  75. const float2 screenUV = IN.m_position.xy * PassSrg::m_existingDepthDimensions.zw;
  76. const float existingLinearDepth = LinearizeDepth(PassSrg::m_existingDepth.Sample(PassSrg::LinearSampler, screenUV).r);
  77. const float linearDepth = LinearizeDepth(IN.m_depth);
  78. // Do not write out any visible fragments to the red channel unless the depth test below passes
  79. OUT.m_mask.r = 0.0;
  80. // Write out all visible and occluded fragments to the green channel
  81. OUT.m_mask.g = 1.0;
  82. // Performing a equal or greater than depth test is still to flakey so we will instead perform a depth test within a small
  83. // tolerance range in order for this fragment to pass the test
  84. if((linearDepth - existingLinearDepth) <= 0.0001)
  85. {
  86. // Depth test passed, update the mask with this closest value
  87. OUT.m_mask.r = 1.0;
  88. }
  89. return OUT;
  90. }