3
0

SkyBoxFeatureProcessor.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. #pragma once
  9. #include <Atom/RHI/BufferPool.h>
  10. #include <Atom/RHI/ShaderResourceGroup.h>
  11. #include <Atom/RPI.Public/Buffer/Buffer.h>
  12. #include <Atom/RPI.Public/FeatureProcessor.h>
  13. #include <Atom/RPI.Reflect/Image/Image.h>
  14. #include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
  15. #include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
  16. #include <Atom/Feature/SkyBox/SkyboxConstants.h>
  17. namespace AZ
  18. {
  19. namespace Render
  20. {
  21. // default SunParameters is set to radius of earth's sun, distance from sun -> earth, and cos(angularDiameter) of the sun
  22. struct SunParameters
  23. {
  24. float m_radius = PhysicalSunRadius; // Sun physical radius, unit is millions of km
  25. float m_distance = PhysicalSunDistance; // Sun distance to planet, unit is millions of km
  26. float m_cosAngularDiameter = PhysicalSunCosAngularDiameter; // Cosine angular diameter of the sun, unit is radians
  27. };
  28. struct HosekSky
  29. {
  30. AZ::Vector3 a; // Darkening or brightening of the horizon. Negative is brighter relative to the zenith luminance.
  31. AZ::Vector3 b; // Smoothness of the gradient that is caused by darkening or brightening of the horizon. Higher values result in a more gradual transition.
  32. AZ::Vector3 c; // Added in the extended formula due to the complication arose by anisotropic term, not exist in the original Perez formula.
  33. AZ::Vector3 d; // Relative intensity of the area near the sun. Higher values result in higher luminance.
  34. AZ::Vector3 e; // The width of the region described above by D is modulated by E. Higher values result in a more gradual transition.
  35. AZ::Vector3 f; // Relative intensity of back-scattered light - in other words, the light reflected back from the ground. Higher values result in more reflected light.
  36. AZ::Vector3 g; // Relative intensity of the aureole (the area around the sun).
  37. AZ::Vector3 h; // Size of the aureole.
  38. AZ::Vector3 i; // Smooth gradient around zenith.
  39. AZ::Vector3 z; // Absolute luminance at zenith.
  40. };
  41. class SkyBoxFeatureProcessor final
  42. : public SkyBoxFeatureProcessorInterface
  43. {
  44. public:
  45. AZ_CLASS_ALLOCATOR(SkyBoxFeatureProcessor, AZ::SystemAllocator)
  46. AZ_RTTI(AZ::Render::SkyBoxFeatureProcessor, "{CB7D1F95-2A02-4152-86F1-BB29DC802CF7}", AZ::Render::SkyBoxFeatureProcessorInterface);
  47. static void Reflect(AZ::ReflectContext* context);
  48. SkyBoxFeatureProcessor();
  49. virtual ~SkyBoxFeatureProcessor() = default;
  50. //! FeatureProcessor
  51. void Activate() override;
  52. void Deactivate() override;
  53. void Simulate(const FeatureProcessor::SimulatePacket& packet) override;
  54. void Render(const FeatureProcessor::RenderPacket& packet) override;
  55. // SkyBoxFeatureProcessorInterface overrides ...
  56. void Enable(bool enable) override;
  57. bool IsEnabled() override;
  58. void SetSkyboxMode(SkyBoxMode mode) override;
  59. void SetFogSettings(const SkyBoxFogSettings& fogSettings) override;
  60. void SetFogEnabled(bool enable) override;
  61. bool IsFogEnabled() override;
  62. void SetFogColor(const AZ::Color& color) override;
  63. void SetFogTopHeight(float topHeight) override;
  64. void SetFogBottomHeight(float bottomHeight) override;
  65. void SetCubemapRotationMatrix(AZ::Matrix4x4 matrix) override;
  66. void SetCubemap(Data::Instance<RPI::Image> cubemap) override;
  67. void SetCubemapExposure(float exposure) override;
  68. void SetSunPosition(SunPosition sunPosition) override;
  69. void SetSunPosition(float azimuth, float altitude) override;
  70. void SetTurbidity(int turbidity) override;
  71. void SetSkyIntensity(float intensity, PhotometricUnit unit) override;
  72. void SetSunIntensity(float intensity, PhotometricUnit unit) override;
  73. void SetSunRadiusFactor(float factor) override;
  74. private:
  75. static constexpr const char* FeatureProcessorName = "SkyBoxFeatureProcessor";
  76. // Parameters definition written above
  77. struct PhysicalSkyData
  78. {
  79. AZStd::array<float, 4> m_physicalSkyParameterA;
  80. AZStd::array<float, 4> m_physicalSkyParameterB;
  81. AZStd::array<float, 4> m_physicalSkyParameterC;
  82. AZStd::array<float, 4> m_physicalSkyParameterD;
  83. AZStd::array<float, 4> m_physicalSkyParameterE;
  84. AZStd::array<float, 4> m_physicalSkyParameterF;
  85. AZStd::array<float, 4> m_physicalSkyParameterG;
  86. AZStd::array<float, 4> m_physicalSkyParameterH;
  87. AZStd::array<float, 4> m_physicalSkyParameterI;
  88. AZStd::array<float, 4> m_physicalSkyParameterZ;
  89. AZStd::array<float, 4> m_physicalSkySunParameters;
  90. AZStd::array<float, 4> m_physicalSkySunDirection;
  91. AZStd::array<float, 4> m_physicalSkySunRGB;
  92. AZStd::array<float, 4> m_physicalSkyAndSunIntensity;
  93. };
  94. SkyBoxFeatureProcessor(const SkyBoxFeatureProcessor&) = delete;
  95. void LoadDefaultCubeMap();
  96. void InitBuffer();
  97. HosekSky ComputeHosekSky();
  98. //! Sun color is based on Preetham's paper
  99. //! https://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf
  100. AZ::Vector4 ComputeSunRGB();
  101. //! Sample function for the look up table
  102. double SampleLUT(const double* dataset, size_t stride, int turbidity, float albedo, float inverseAltitude);
  103. double EvaluateSpline(const double* spline, size_t stride, double value);
  104. AZ::Vector3 ComputeSpherical(float altitude, float azimuth) const;
  105. //! Irradiance to CIE XYZ
  106. //! http://jcgt.org/published/0002/02/01/paper.pdf
  107. AZ::Vector3 EvaluateCIEXYZ(int lambda);
  108. //--------------------------------------------------------------------------
  109. //! Evaluates the Perez (extended) formula to find the luminance, in RGB, of the sky
  110. //! https://cgg.mff.cuni.cz/projects/SkylightModelling/HosekWilkie_SkylightModel_SIGGRAPH2012_Preprint_lowres.pdf
  111. //!
  112. //! \param cosTheta Viewing angle on Y axis in radians
  113. //! \param gamma Angle, in radians, between view direction and sun direction
  114. //! \param cosGamma Float dot product of view direction and sun direction
  115. //! \param hosek Sky model parameters
  116. //--------------------------------------------------------------------------
  117. AZ::Vector3 EvaluateHosek(float cosTheta, float gamma, float cosGamma,const HosekSky& hosek);
  118. AZ::Vector3 Vector3Pow(AZ::Vector3 a, AZ::Vector3 b);
  119. AZ::Vector3 Vector3Exp(AZ::Vector3 a);
  120. Data::Instance<RPI::Buffer> m_buffer;
  121. PhysicalSkyData m_physicalSkyData;
  122. RHI::ShaderInputNameIndex m_skyboxEnableIndex = "m_enable";
  123. RHI::ShaderInputNameIndex m_physicalSkyBufferIndex = "m_physicalSkyData";
  124. RHI::ShaderInputNameIndex m_physicalSkyIndex = "m_physicalSky";
  125. RHI::ShaderInputNameIndex m_cubemapIndex = "m_skyboxCubemap";
  126. RHI::ShaderInputNameIndex m_cubemapRotationMatrixIndex = "m_cubemapRotationMatrix";
  127. RHI::ShaderInputNameIndex m_cubemapExposureIndex = "m_cubemapExposure";
  128. RHI::ShaderInputNameIndex m_fogEnableIndex = "m_fogEnable";
  129. RHI::ShaderInputNameIndex m_fogColorIndex = "m_fogColor";
  130. RHI::ShaderInputNameIndex m_fogTopHeightIndex = "m_fogTopHeight";
  131. RHI::ShaderInputNameIndex m_fogBottomHeightIndex = "m_fogBottomHeight";
  132. bool m_skyNeedUpdate = true;
  133. bool m_sunNeedUpdate = true;
  134. bool m_mapBuffer = true;
  135. bool m_enable = false;
  136. SkyBoxMode m_skyboxMode = SkyBoxMode::None;
  137. SkyBoxFogSettings m_fogSettings;
  138. Data::Instance<RPI::ShaderResourceGroup> m_sceneSrg = nullptr;
  139. Data::Instance<RPI::Image> m_cubemapTexture = nullptr;
  140. float m_cubemapExposure = 0;
  141. AZ::Matrix4x4 m_cubemapRotationMatrix = AZ::Matrix4x4::CreateIdentity();
  142. int m_turbidity = 1; // A measure of the aerosol content in the air, it is not linearly interpolated as a float due to numerical instability, but rather treated as integer steps
  143. SunPosition m_sunPosition; // Sun position in the Sky( Azimuth, Altitude)
  144. SunParameters m_sunParameters; // Sun physical parameters
  145. AZ::Vector3 m_sunDirection;
  146. PhotometricValue m_sunIntensity;
  147. PhotometricValue m_skyIntensity;
  148. Data::Instance<RPI::Image> m_defaultCubemapTexture;
  149. };
  150. } // namespace Render
  151. } // namespace AZ