add simple fog
This commit is contained in:
@ -664,7 +664,7 @@ namespace Prism
|
||||
{
|
||||
SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
m_EditorScene->SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
m_EditorCamera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
|
||||
m_EditorCamera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 1000.0f));
|
||||
m_EditorCamera.SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
||||
|
||||
|
||||
@ -75,6 +75,9 @@ const float Epsilon = 0.00001;
|
||||
const int LightCount = 1;
|
||||
const vec3 Fdielectric = vec3(0.04);
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
layout(location = 1) out vec4 o_BloomColor;
|
||||
|
||||
struct DirectionalLight {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
@ -113,8 +116,6 @@ in VertexOutput
|
||||
vec4 FragPosLightSpace;
|
||||
} vs_Input;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
layout(location = 1) out vec4 o_BloomColor;
|
||||
|
||||
uniform DirectionalLight u_DirectionalLights;
|
||||
uniform vec3 u_CameraPosition;
|
||||
|
||||
@ -61,6 +61,9 @@ const float Epsilon = 0.00001;
|
||||
const int LightCount = 1;
|
||||
const vec3 Fdielectric = vec3(0.04);
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
layout(location = 1) out vec4 o_BloomColor;
|
||||
|
||||
struct DirectionalLight {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
@ -100,9 +103,6 @@ in VertexOutput
|
||||
vec4 FragPosLightSpace;
|
||||
} vs_Input;
|
||||
|
||||
layout(location = 0) out vec4 color;
|
||||
layout(location = 1) out vec4 o_BloomColor;
|
||||
|
||||
uniform DirectionalLight u_DirectionalLights;
|
||||
|
||||
uniform int u_PointLightCount;
|
||||
|
||||
@ -22,8 +22,20 @@ layout(location = 1) out vec4 o_BloomTexture;
|
||||
in vec2 v_TexCoord;
|
||||
|
||||
uniform sampler2DMS u_Texture;
|
||||
uniform sampler2DMS u_DepthTexture;
|
||||
uniform sampler2D u_BloomTexture;
|
||||
|
||||
uniform mat4 u_InvProjection;
|
||||
uniform mat4 u_InvView;
|
||||
|
||||
// Fog
|
||||
uniform float u_FogEnabled;
|
||||
uniform vec3 u_FogColor;
|
||||
uniform float u_FogDensity; // 雾密度,典型值 0.01~0.05
|
||||
uniform float u_FogHeight; // 雾的起始高度(世界 Y 坐标),低于此高度雾最浓
|
||||
uniform float u_FogHeightFalloff; // 高度衰减系数,值越大高度影响越剧烈(典型 0.5~2.0)
|
||||
|
||||
|
||||
|
||||
uniform bool u_EnableAutoExposure;
|
||||
uniform float u_ManualExposure;
|
||||
@ -82,10 +94,14 @@ void main()
|
||||
color += bloomColor;
|
||||
}
|
||||
|
||||
|
||||
float exposure = 1.0f;
|
||||
if(u_EnableAutoExposure)
|
||||
color *= u_Exposure;
|
||||
exposure = u_Exposure;
|
||||
else
|
||||
color *= u_ManualExposure;
|
||||
exposure = u_ManualExposure;
|
||||
color *= exposure;
|
||||
|
||||
|
||||
// Reinhard tonemapping operator.
|
||||
// see: "Photographic Tone Reproduction for Digital Images", eq. 4
|
||||
@ -95,6 +111,49 @@ void main()
|
||||
// Scale color by ratio of average luminances.
|
||||
vec3 mappedColor = (mappedLuminance / luminance) * color;
|
||||
|
||||
if (u_FogEnabled > 0.5)
|
||||
{
|
||||
// 1. 获取深度并重建视空间坐标
|
||||
float depth = MultiSampleDepth(u_DepthTexture, v_TexCoord);
|
||||
vec4 clipPos = vec4(v_TexCoord * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||
vec4 viewPos4 = u_InvProjection * clipPos;
|
||||
viewPos4 /= viewPos4.w;
|
||||
vec3 viewPos = viewPos4.xyz; // 视空间坐标(相机为原点,Z 轴向内)
|
||||
|
||||
// 2. 距离雾因子(指数雾)
|
||||
float distance = length(viewPos);
|
||||
float distanceFactor = 1.0 - exp(-distance * u_FogDensity);
|
||||
// 可选:指数平方雾(更平滑)
|
||||
// float distanceFactor = 1.0 - exp(-pow(distance * u_FogDensity, 2.0));
|
||||
|
||||
// 3. 高度雾因子(基于世界 Y)
|
||||
// 将视空间坐标转换到世界空间
|
||||
vec4 worldPos4 = u_InvView* vec4(viewPos, 1.0);
|
||||
vec3 worldPos = worldPos4.xyz / worldPos4.w;
|
||||
float worldY = worldPos.y;
|
||||
|
||||
float heightFactor = 0.0;
|
||||
if (worldY < u_FogHeight)
|
||||
{
|
||||
// 低于起始高度:雾最浓,因子为 1
|
||||
heightFactor = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 高于起始高度:指数衰减,高度越高雾越淡
|
||||
float deltaY = worldY - u_FogHeight;
|
||||
heightFactor = exp(-deltaY * u_FogHeightFalloff);
|
||||
}
|
||||
// 可选:使用 clamp 限制范围
|
||||
heightFactor = clamp(heightFactor, 0.0, 1.0);
|
||||
|
||||
// 4. 综合雾因子(可相乘,也可取最大值,通常相乘)
|
||||
float fogFactor = distanceFactor * heightFactor;
|
||||
|
||||
// 5. 混合雾颜色(雾颜色直接使用 u_FogColor,已在 LDR 空间)
|
||||
mappedColor = mix(mappedColor, u_FogColor, fogFactor);
|
||||
}
|
||||
|
||||
// Gamma correction.
|
||||
o_Color = vec4(pow(mappedColor, vec3(1.0 / gamma)), 1.0);
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "DefaultAssetEditors.h"
|
||||
|
||||
#include "Prism/Asset/AssetSerializer.h"
|
||||
#include "Prism/Core/Log.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class RenderPass;
|
||||
|
||||
class PhysicsMaterialEditor : public AssetEditor
|
||||
{
|
||||
public:
|
||||
|
||||
@ -148,6 +148,17 @@ namespace Prism
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLShader::SetFloatArray(const std::string& name, float* arr, int count)
|
||||
{
|
||||
Renderer::Submit([=]()
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
UploadUniformFloat(name, arr[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLShader::SetInt(const std::string& name, int value)
|
||||
{
|
||||
Renderer::Submit([=]() {
|
||||
|
||||
@ -31,6 +31,7 @@ namespace Prism
|
||||
virtual void SetFloat(const std::string& name, float value) override;
|
||||
virtual void SetFloat2(const std::string& name, const glm::vec2& value) override;
|
||||
virtual void SetFloat3(const std::string& name, const glm::vec3& value) override;
|
||||
virtual void SetFloatArray(const std::string& name, float* arr, int count) override;
|
||||
virtual void SetInt(const std::string& name, int value) override;
|
||||
virtual void SetUInt(const std::string& name, unsigned int value) override;
|
||||
virtual void SetMat4(const std::string& name, const glm::mat4& value) override;
|
||||
|
||||
@ -13,4 +13,20 @@ namespace Prism
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float Camera::GetNear() const
|
||||
{
|
||||
if (m_ProjectionMatrix[3][3] == 1.0f) // 正交投影
|
||||
return (m_ProjectionMatrix[3][2] - 1.0f) / m_ProjectionMatrix[2][2];
|
||||
else // 透视投影
|
||||
return m_ProjectionMatrix[3][2] / (m_ProjectionMatrix[2][2] - 1.0f);
|
||||
}
|
||||
|
||||
float Camera::GetFar() const
|
||||
{
|
||||
if (m_ProjectionMatrix[3][3] == 1.0f) // 正交
|
||||
return (m_ProjectionMatrix[3][2] + 1.0f) / m_ProjectionMatrix[2][2];
|
||||
else // 透视
|
||||
return m_ProjectionMatrix[3][2] / (m_ProjectionMatrix[2][2] + 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,9 @@ namespace Prism
|
||||
|
||||
const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; }
|
||||
|
||||
float GetNear() const;
|
||||
float GetFar() const;
|
||||
|
||||
void SetProjectionMatrix(const glm::mat4& projectionMatrix) { m_ProjectionMatrix = projectionMatrix; }
|
||||
|
||||
float GetExposure() const { return m_Exposure; }
|
||||
|
||||
@ -201,6 +201,16 @@ namespace Prism
|
||||
DrawIndexed(6, PrimitiveType::Triangles, depthTest, cullFace);
|
||||
}
|
||||
|
||||
void Renderer::SubmitFullscreenQuad(const bool depthTest, const bool cullFace)
|
||||
{
|
||||
|
||||
s_Data.m_FullscreenQuadVertexBuffer->Bind();
|
||||
s_Data.m_FullscreenQuadPipeline->Bind();
|
||||
s_Data.m_FullscreenQuadIndexBuffer->Bind();
|
||||
|
||||
DrawIndexed(6, PrimitiveType::Triangles, depthTest, cullFace);
|
||||
}
|
||||
|
||||
void Renderer::SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
||||
{
|
||||
// auto material = overrideMaterial ? overrideMaterial : mesh->GetMaterialInstance();
|
||||
|
||||
@ -61,6 +61,7 @@ namespace Prism
|
||||
|
||||
static void SubmitQuad(Ref<MaterialInstance>& material, const glm::mat4& transform = glm::mat4(1.0f));
|
||||
static void SubmitFullscreenQuad(Ref<MaterialInstance> material);
|
||||
static void SubmitFullscreenQuad(bool depthTest = true, bool cullFace = true);
|
||||
static void SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials = {});
|
||||
static void SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial = nullptr);
|
||||
static void SubmitMeshWithShader(Ref<Mesh> mesh, const glm::mat4& transform, Ref<Shader> shader);
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
#include "Renderer2D.h"
|
||||
#include "SceneRenderer.h"
|
||||
#include "StorageBuffer.h"
|
||||
#include "glad/glad.h"
|
||||
#include "Prism/Scene/Components.h"
|
||||
#include "RHI/RHICommandBuffer.h"
|
||||
#include "RHI/RHIDevice.h"
|
||||
@ -31,6 +30,15 @@ namespace Prism
|
||||
Ref<Environment> SceneEnvironment;
|
||||
} SceneData;
|
||||
|
||||
struct FogData
|
||||
{
|
||||
bool FogEnabled = false;
|
||||
glm::vec3 FogColor{1.0f};
|
||||
float FogDensity = 0.01f;
|
||||
float FogHeight = 0.0f;
|
||||
float FogHeightFalloff = 0.01f;
|
||||
}FogData;
|
||||
|
||||
Ref<Texture2D> BRDFLUT;
|
||||
Ref<Shader> CompositeShader;
|
||||
Ref<Shader> BloomBlurShader;
|
||||
@ -815,10 +823,10 @@ namespace Prism
|
||||
auto reg = rd->GetRegister();
|
||||
auto tex = s_Data.ShadowMapRenderPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID();
|
||||
|
||||
Renderer::Submit([reg, tex]() mutable
|
||||
Renderer::Submit([reg, tex, cmd]() mutable
|
||||
{
|
||||
glBindTextureUnit(reg, tex);
|
||||
glBindSampler(reg, s_Data.ShadowMapSampler);
|
||||
cmd->BindTextureUnit(reg, tex);
|
||||
cmd->BindSampler(reg, s_Data.ShadowMapSampler);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1039,17 +1047,39 @@ namespace Prism
|
||||
s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples);
|
||||
s_Data.CompositeShader->SetBool("u_EnableBloom", s_Data.EnableBloom);
|
||||
|
||||
// 绑定几何阶段颜色纹理(多重采样)
|
||||
|
||||
// Fog
|
||||
s_Data.CompositeShader->SetFloat("u_FogEnabled", s_Data.FogData.FogEnabled ? 1.0f : 0.0f);
|
||||
if (s_Data.FogData.FogEnabled)
|
||||
{
|
||||
s_Data.CompositeShader->SetMat4("u_InvProjection", glm::inverse(s_Data.SceneData.SceneCamera.Camera.GetProjectionMatrix()));
|
||||
s_Data.CompositeShader->SetMat4("u_InvView", glm::inverse(s_Data.SceneData.SceneCamera.ViewMatrix));
|
||||
s_Data.CompositeShader->SetFloat3("u_FogColor", s_Data.FogData.FogColor);
|
||||
s_Data.CompositeShader->SetFloat("u_FogDensity", s_Data.FogData.FogDensity);
|
||||
s_Data.CompositeShader->SetFloat("u_FogHeight", s_Data.FogData.FogHeight);
|
||||
s_Data.CompositeShader->SetFloat("u_FogHeightFalloff", s_Data.FogData.FogHeightFalloff);
|
||||
}
|
||||
|
||||
s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
|
||||
s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindDepthTexture(1);
|
||||
|
||||
if (s_Data.EnableBloom)
|
||||
{
|
||||
s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->BindTexture(0, 2);
|
||||
s_Data.CompositeShader->SetInt("u_BloomTexture", 2); // 告诉着色器使用单元2
|
||||
s_Data.CompositeShader->SetInt("u_BloomTexture", 2);
|
||||
}
|
||||
|
||||
Renderer::SubmitFullscreenQuad(nullptr);
|
||||
Renderer::SubmitFullscreenQuad(false);
|
||||
|
||||
auto depthFB = s_Data.GeoPass->GetSpecification().TargetFramebuffer;
|
||||
auto outFB = outRenderPass->GetSpecification().TargetFramebuffer;
|
||||
Renderer::Submit([cmd, depthFB, outFB]()
|
||||
{
|
||||
cmd->BindFramebuffer(FramebufferTarget::Read, depthFB->GetDepthAttachmentRendererID());
|
||||
cmd->BindFramebuffer(FramebufferTarget::Draw, outFB->GetDepthAttachmentRendererID());
|
||||
cmd->BlitFramebuffer(0, 0, depthFB->GetWidth(), depthFB->GetHeight(),
|
||||
0, 0, outFB->GetWidth(), outFB->GetHeight(), BlitMask::Depth, BlitFilter::Nearest);
|
||||
});
|
||||
|
||||
Renderer::EndRenderPass();
|
||||
}
|
||||
@ -1110,6 +1140,22 @@ namespace Prism
|
||||
UI::Property("Shadow Pass time", s_Stats.ShadowPass);
|
||||
UI::Property("AutoExposure Pass time", s_Stats.AutoExposurePass);
|
||||
|
||||
if (UI::BeginTreeNode("FogConfig", false))
|
||||
{
|
||||
UI::BeginPropertyGrid();
|
||||
UI::Property("Enabled", s_Data.FogData.FogEnabled);
|
||||
if (s_Data.FogData.FogEnabled)
|
||||
{
|
||||
UI::PropertyColor("Fog Color", s_Data.FogData.FogColor);
|
||||
UI::Property("Fog Density", s_Data.FogData.FogDensity, 0.001f, 0.001f, 0.1f);
|
||||
UI::Property("Fog Height", s_Data.FogData.FogHeight, 0.001f, -10.0f, 10.0f);
|
||||
UI::Property("Fog HeightFalloff", s_Data.FogData.FogHeightFalloff, 0.001f, 0.001f, 0.5f);
|
||||
}
|
||||
UI::EndPropertyGrid();
|
||||
|
||||
UI::EndTreeNode();
|
||||
}
|
||||
|
||||
if (UI::BeginTreeNode("Grid Config", false))
|
||||
{
|
||||
// Grid plane: 0 = XZ (Y up), 1 = XY (Z forward), 2 = YZ (X right)
|
||||
|
||||
@ -215,8 +215,6 @@ namespace Prism
|
||||
const auto fbWidth = fb->GetWidth();
|
||||
const auto fbHeight = fb->GetHeight();
|
||||
|
||||
|
||||
|
||||
Renderer::Submit([fb, fbWidth, fbHeight]()
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb->GetColorAttachmentRendererID());
|
||||
|
||||
@ -116,6 +116,7 @@ namespace Prism
|
||||
virtual void SetFloat(const std::string& name, float value) = 0;
|
||||
virtual void SetFloat2(const std::string& name, const glm::vec2& value) = 0;
|
||||
virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0;
|
||||
virtual void SetFloatArray(const std::string& name, float* arr, int count) = 0;
|
||||
virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0;
|
||||
virtual void SetMat4FromRenderThread(const std::string& name, const glm::mat4& value, bool bind = true) = 0;
|
||||
|
||||
|
||||
@ -239,7 +239,10 @@ namespace Prism
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
#ifdef PRISM_RUNTIME
|
||||
SceneRenderer::FlushToScreen();
|
||||
#endif
|
||||
SceneRenderer::EndScene();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user