diff --git a/Editor/assets/shaders/BloomBlur.glsl b/Editor/assets/shaders/BloomBlur.glsl index 03bc805..2ac3df4 100644 --- a/Editor/assets/shaders/BloomBlur.glsl +++ b/Editor/assets/shaders/BloomBlur.glsl @@ -21,59 +21,64 @@ layout(location = 0) out vec4 o_Color; in vec2 v_TexCoord; uniform sampler2D u_Texture; -uniform bool u_Horizontal; +uniform bool u_Horizontal; // 未使用,可保留或移除 +uniform bool u_FirstPass; // 是否进行阈值处理 +uniform float u_Threshold; // 亮度阈值 void main() { -#if 1 - // From learnopengl.com - float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); + float Pi = 6.28318530718; // 2*PI - vec2 tex_offset = 1.0 / textureSize(u_Texture, 0); // gets size of single texel - vec3 result = texture(u_Texture, v_TexCoord).rgb * weight[0]; // current fragment's contribution - if (u_Horizontal) + float Directions = 32.0; // 模糊方向数 + float Quality = 6.0; // 每个方向上的采样质量(采样次数) + float Size = 16.0; // 模糊半径 + + vec2 Radius = Size / textureSize(u_Texture, 0); + + // 中心像素采样 + vec3 centerColor = texture(u_Texture, v_TexCoord).rgb; + float centerLum = dot(centerColor, vec3(0.2126, 0.7152, 0.0722)); + + // 如果启用第一次处理且中心像素亮度低于阈值,则直接输出黑色(不进行模糊) + if (u_FirstPass && centerLum <= u_Threshold) { - for(int i = 1; i < 5; ++i) + o_Color = vec4(0.0, 0.0, 0.0, 1.0); + return; + } + + vec3 result = centerColor; // 先累加中心像素 + float totalSamples = 1.0; // 有效采样计数(中心像素已计入) + + // 周围像素采样 + for (float d = 0.0; d < Pi; d += Pi / Directions) + { + for (float i = 1.0 / Quality; i <= 1.0; i += 1.0 / Quality) { - result += texture(u_Texture, v_TexCoord + vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; - result += texture(u_Texture, v_TexCoord - vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; - } - } - else - { - for(int i = 1; i < 5; ++i) - { - result += texture(u_Texture, v_TexCoord + vec2(0.0, tex_offset.y * i)).rgb * weight[i]; - result += texture(u_Texture, v_TexCoord - vec2(0.0, tex_offset.y * i)).rgb * weight[i]; + vec2 offset = vec2(cos(d), sin(d)) * Radius * i; + vec3 sampleColor = texture(u_Texture, v_TexCoord + offset).rgb; + + if (u_FirstPass) + { + float lum = dot(sampleColor, vec3(0.2126, 0.7152, 0.0722)); + if (lum <= u_Threshold) + { + // 低于阈值则贡献黑色,但采样点仍计入分母?这里选择不计入有效采样数 + // 若希望保持模糊能量,可以 continue 跳过累加,但需调整分母 + // 为简单起见,此处设为黑色并计入计数(分母不变),也可选择跳过 + sampleColor = vec3(0.0); + // 如果希望忽略该采样点,可以 continue 并减少 totalSamples + // 但为了效果平滑,这里保留为黑色并计入计数 + } + } + + result += sampleColor; + totalSamples += 1.0; } } + + // 归一化:除以总采样数(包括中心像素) + // 若之前选择忽略低于阈值的采样点(continue),则需相应调整 totalSamples + result /= totalSamples; + o_Color = vec4(result, 1.0); -#else - // From https://www.shadertoy.com/view/Xltfzj - - float Pi = 6.28318530718; // Pi*2 - - // GAUSSIAN BLUR SETTINGS {{{ - float Directions =32.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower) - float Quality = 6.0; // BLUR QUALITY (Default 4.0 - More is better but slower) - float Size = 16.0; // BLUR SIZE (Radius) - // GAUSSIAN BLUR SETTINGS }}} - - vec2 Radius = Size/textureSize(u_Texture, 0); - - vec3 result = texture(u_Texture, v_TexCoord).rgb; - vec2 uv = v_TexCoord; - // Blur calculations - for( float d=0.0; dCreateEntity("Sky Light"); - newEntity.AddComponent(); + auto& slc = newEntity.AddComponent(); + slc.DynamicSky = true; + + Ref preethamEnv = Renderer3D::CreatePreethamSky(slc.TurbidityAzimuthInclination); + slc.SceneEnvironment = Ref::Create(preethamEnv, preethamEnv); + isCreated = true; SetSelected(newEntity); } @@ -681,7 +686,12 @@ namespace Prism ImGui::SeparatorText("Light Component"); AddComponentPopup("Directional Light"); - AddComponentPopup("sky Light"); + AddComponentPopup("Sky Light", [&]( SkyLightComponent& slc) + { + slc.DynamicSky = true; + Ref preethamEnv = Renderer3D::CreatePreethamSky(slc.TurbidityAzimuthInclination); + slc.SceneEnvironment = Ref::Create(preethamEnv, preethamEnv); + }); AddComponentPopup("Point Light"); AddComponentPopup("Spot Light"); @@ -939,6 +949,10 @@ namespace Prism }); DrawComponent("Camera", entity, [](CameraComponent& cameraComponent) { + + UI::Property("ShowIcon", cameraComponent.ShowIcon); + UI::Separator(); + // Projection Type const char* projTypeStrings[] = { "Perspective", "Orthographic" }; const char* currentProj = projTypeStrings[(int)cameraComponent.Camera.GetProjectionType()]; @@ -996,6 +1010,8 @@ namespace Prism DrawComponent("Directional Light", entity, [](DirectionalLightComponent& dlc) { UI::BeginPropertyGrid(); + UI::Property("ShowIcon", dlc.ShowIcon); + UI::Separator(); UI::PropertyColor("Radiance", dlc.Radiance); UI::Property("Intensity", dlc.Intensity); UI::Property("Cast Shadows", dlc.CastShadows); @@ -1007,6 +1023,8 @@ namespace Prism DrawComponent("Point Light", entity, [](PointLightComponent& pc) { UI::BeginPropertyGrid(); + UI::Property("ShowIcon", pc.ShowIcon); + UI::Separator(); UI::PropertyColor("Radiance", pc.Radiance); UI::Property("Intensity", pc.Intensity); @@ -1018,6 +1036,8 @@ namespace Prism DrawComponent("Spot Light", entity, [](SpotLightComponent& sc) { UI::BeginPropertyGrid(); + UI::Property("ShowIcon", sc.ShowIcon); + UI::Separator(); UI::PropertyColor("Radiance", sc.Radiance); UI::Property("Intensity", sc.Intensity); @@ -1032,9 +1052,17 @@ namespace Prism { UI::BeginPropertyGrid(); - UI::PropertyAssetReference("Environment Map", slc.SceneEnvironment, AssetType::EnvMap); + + UI::Property("ShowIcon", slc.ShowIcon); + UI::Separator(); + + if (UI::PropertyAssetReference("Environment Map", slc.SceneEnvironment, AssetType::EnvMap)) + { + if (slc.DynamicSky) slc.DynamicSky = false; + } UI::Property("Intensity", slc.Intensity, 0.01f, 0.0f, 5.0f); + ImGui::Separator(); const bool isEnable = UI::Property("Dynamic Sky", slc.DynamicSky); if (slc.DynamicSky) @@ -1044,7 +1072,7 @@ namespace Prism changed |= UI::Property("Inclination", slc.TurbidityAzimuthInclination.z, 0.01f); if (changed || isEnable) { - Ref preethamEnv = Renderer3D::CreatePreethamSky(slc.TurbidityAzimuthInclination.x, slc.TurbidityAzimuthInclination.y, slc.TurbidityAzimuthInclination.z); + Ref preethamEnv = Renderer3D::CreatePreethamSky(slc.TurbidityAzimuthInclination); slc.SceneEnvironment = Ref::Create(preethamEnv, preethamEnv); } } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp index 4acabb9..4a324da 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp @@ -98,7 +98,7 @@ namespace Prism } OpenGLFrameBuffer::OpenGLFrameBuffer(const FramebufferSpecification& spec) - : m_Specification(spec), m_Width(spec.Width), m_Height(spec.Height) + : m_Specification(spec) { for (auto format : m_Specification.Attachments.Attachments) { @@ -124,7 +124,7 @@ namespace Prism Ref instance = this; Renderer::Submit([instance]() { glBindFramebuffer(GL_FRAMEBUFFER, instance->m_RendererID); - glViewport(0, 0, instance->m_Width, instance->m_Height); + glViewport(0, 0, instance->m_Specification.Width, instance->m_Specification.Height); }); } @@ -137,11 +137,11 @@ namespace Prism void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height, const bool forceReCreate) { - if (!forceReCreate && (m_Width == width && m_Height == height)) + if (!forceReCreate && (m_Specification.Width == width && m_Specification.Height == height)) return; - m_Width = width; - m_Height = height; + m_Specification.Width = width; + m_Specification.Height = height; Ref instance = this; Renderer::Submit([instance]() mutable @@ -173,16 +173,16 @@ namespace Prism switch (instance->m_ColorAttachmentFormats[i]) { case FramebufferTextureFormat::RGBA8: - Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RGBA8, instance->m_Width, instance->m_Height, i); + Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RGBA8, instance->m_Specification.Width, instance->m_Specification.Height, i); break; case FramebufferTextureFormat::RGBA16F: - Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RGBA16F, instance->m_Width, instance->m_Height, i); + Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RGBA16F, instance->m_Specification.Width, instance->m_Specification.Height, i); break; case FramebufferTextureFormat::RGBA32F: - Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RGBA32F, instance->m_Width, instance->m_Height, i); + Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RGBA32F, instance->m_Specification.Width, instance->m_Specification.Height, i); break; case FramebufferTextureFormat::RG32F: - Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RG32F, instance->m_Width, instance->m_Height, i); + Utils::AttachColorTexture(instance->m_ColorAttachments[i], instance->m_Specification.Samples, GL_RG32F, instance->m_Specification.Width, instance->m_Specification.Height, i); break; } @@ -196,10 +196,10 @@ namespace Prism switch (instance->m_DepthAttachmentFormat) { case FramebufferTextureFormat::DEPTH24STENCIL8: - Utils::AttachDepthTexture(instance->m_DepthAttachment, instance->m_Specification.Samples, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, instance->m_Width, instance->m_Height); + Utils::AttachDepthTexture(instance->m_DepthAttachment, instance->m_Specification.Samples, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, instance->m_Specification.Width, instance->m_Specification.Height); break; case FramebufferTextureFormat::DEPTH32F: - Utils::AttachDepthTexture(instance->m_DepthAttachment, instance->m_Specification.Samples, GL_DEPTH_COMPONENT32F, GL_DEPTH_ATTACHMENT, instance->m_Width, instance->m_Height); + Utils::AttachDepthTexture(instance->m_DepthAttachment, instance->m_Specification.Samples, GL_DEPTH_COMPONENT32F, GL_DEPTH_ATTACHMENT, instance->m_Specification.Width, instance->m_Specification.Height); break; } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h index 09a2d5e..127fd14 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h @@ -40,8 +40,6 @@ namespace Prism std::vector m_ColorAttachmentFormats; FramebufferTextureFormat m_DepthAttachmentFormat = FramebufferTextureFormat::None; - - uint32_t m_Width = 0, m_Height = 0; }; } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLStorageBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLStorageBuffer.cpp index a1e78df..c93b5ba 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLStorageBuffer.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLStorageBuffer.cpp @@ -67,7 +67,10 @@ namespace Prism { void OpenGLStorageBuffer::GetData(void* outData, const uint32_t size, const uint32_t offset) const { - glGetNamedBufferSubData(m_RendererID, offset, size, outData); + Renderer::Submit([this, outData, size, offset]() + { + glGetNamedBufferSubData(m_RendererID, offset, size, outData); + }); } } \ No newline at end of file diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp index 4f8200e..4018522 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp @@ -17,7 +17,7 @@ namespace Prism { case TextureFormat::RGB: return GL_RGB; case TextureFormat::RGBA: return GL_RGBA; - case TextureFormat::Float16: return GL_RGBA16F; + case TextureFormat::RGBA16F: return GL_RGBA16F; } return 0; } @@ -26,7 +26,7 @@ namespace Prism switch (format) { case TextureFormat::RGB: return GL_RGB8; case TextureFormat::RGBA: return GL_RGBA8; - case TextureFormat::Float16: return GL_RGBA16F; + case TextureFormat::RGBA16F: return GL_RGBA16F; default: return 0; } } @@ -35,7 +35,7 @@ namespace Prism switch (format) { case TextureFormat::RGB: return GL_RGB; case TextureFormat::RGBA: return GL_RGBA; - case TextureFormat::Float16: return GL_RGBA; // 根据实际情况调整 + case TextureFormat::RGBA16F: return GL_RGBA; // 根据实际情况调整 default: return 0; } } @@ -44,7 +44,7 @@ namespace Prism switch (format) { case TextureFormat::RGB: case TextureFormat::RGBA: return GL_UNSIGNED_BYTE; - case TextureFormat::Float16: return GL_HALF_FLOAT; + case TextureFormat::RGBA16F: return GL_HALF_FLOAT; default: return 0; } } @@ -69,7 +69,12 @@ namespace Prism glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); glTextureParameterf(instance->m_RendererID, GL_TEXTURE_MAX_ANISOTROPY, RendererAPI::GetCapabilities().MaxAnisotropy); - glTexImage2D(GL_TEXTURE_2D, 0, PrismToOpenGLTextureFormat(instance->m_Format), (GLint)instance->m_Width, (GLint)instance->m_Height, 0, Prism::PrismToOpenGLTextureFormat(instance->m_Format), GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, + SizedInternalFormat(instance->m_Format), // 内部格式 + (GLint)instance->m_Width, (GLint)instance->m_Height, 0, + ImageFormat(instance->m_Format), // 像素格式 + DataType(instance->m_Format), // 数据类型 + nullptr); // glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); @@ -88,7 +93,7 @@ namespace Prism PM_CORE_INFO("Loading HDR texture {0}, srgb={1}", path, srgb); m_ImageData.Data = (byte*)stbi_loadf(path.c_str(), &width, &height, &channels, 0); m_IsHDR = true; - m_Format = TextureFormat::Float16; + m_Format = TextureFormat::RGBA16F; } else { @@ -126,9 +131,12 @@ namespace Prism glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + const GLint wrap = instance->m_Wrap == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT; + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, wrap); GLenum internalFormat = PrismToOpenGLTextureFormat(instance->m_Format); GLenum format = srgb ? GL_SRGB8 : (instance->m_IsHDR ? GL_RGB : PrismToOpenGLTextureFormat(instance->m_Format)); // HDR = GL_RGB for now @@ -178,6 +186,27 @@ namespace Prism }); } + void OpenGLTexture2D::SetData(const void* data, int count) + { + Lock(); + + PM_CORE_ASSERT(count <= m_ImageData.Size * 4); + // Convert RGBA32F color to RGBA8 + auto pixels = m_ImageData.Data; + + const auto* pixelData = static_cast(data); + for (uint32_t i = 0; i < m_Width * m_Height; i++) + { + const glm::vec4& value = pixelData[i]; + *pixels++ = static_cast(value.x * 255.0f); + *pixels++ = static_cast(value.y * 255.0f); + *pixels++ = static_cast(value.z * 255.0f); + *pixels++ = static_cast(value.w * 255.0f); + } + + Unlock(); + } + void OpenGLTexture2D::Resize(uint32_t width, uint32_t height) { PM_CORE_ASSERT(m_Locked, "Texture must be locked!"); diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h index 4ef9647..4d24c3c 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h @@ -30,6 +30,8 @@ namespace Prism virtual void Lock() override; virtual void Unlock() override; + virtual void SetData(const void* data, int count) override; + virtual void Resize(uint32_t width, uint32_t height) override; virtual Buffer GetWriteableBuffer() override; @@ -47,7 +49,7 @@ namespace Prism RendererID m_RendererID = 0; TextureFormat m_Format; unsigned int m_Width, m_Height; - TextureWrap m_Wrap = TextureWrap::Clamp; + TextureWrap m_Wrap = TextureWrap::Repeat; bool m_IsHDR = false; bool m_Loaded = false; diff --git a/Prism/src/Prism/Renderer/Material.h b/Prism/src/Prism/Renderer/Material.h index 7b73cad..487958a 100644 --- a/Prism/src/Prism/Renderer/Material.h +++ b/Prism/src/Prism/Renderer/Material.h @@ -119,6 +119,8 @@ namespace Prism static Ref Create(const Ref& material); + static Ref Copy(Ref other); + template T& Get(const std::string& name) { diff --git a/Prism/src/Prism/Renderer/Renderer3D.cpp b/Prism/src/Prism/Renderer/Renderer3D.cpp index f233276..eec019c 100644 --- a/Prism/src/Prism/Renderer/Renderer3D.cpp +++ b/Prism/src/Prism/Renderer/Renderer3D.cpp @@ -38,13 +38,16 @@ namespace Prism // Ref CompositePass; Ref BloomBlurPass[2]; Ref BloomBlendPass; + Ref ResolvedHDRTexture; // 解析后的单样本 HDR 颜色 struct AutoExposureData { Ref LuminancePass; + float Exposure = 1.0f; + bool EnableAutoExposure = true; - float Key = 0.11f; + float Key = 0.3f; Timer ExposureTimer; float MaxExposure = 5.0f; float MinExposure = 0.01f; @@ -266,12 +269,16 @@ namespace Prism s_Data.BlackCubeTexture = TextureCube::Create(TextureFormat::RGBA, 1, 1, &blackTextureData); } - void Renderer3D::SetViewportSize(uint32_t width, uint32_t height) + void Renderer3D::SetViewportSize(const uint32_t width, const uint32_t height) { s_Data.GeoPass->GetSpecification().TargetFramebuffer->Resize(width, height); // s_Data.CompositePass->GetSpecification().TargetFramebuffer->Resize(width, height); if (s_Data.AutoExposureData.LuminancePass) s_Data.AutoExposureData.LuminancePass->GetSpecification().TargetFramebuffer->Resize(width, height); + + s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer->Resize(width, height); + s_Data.BloomBlurPass[1]->GetSpecification().TargetFramebuffer->Resize(width, height); + s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->Resize(width, height); } void Renderer3D::BeginScene(const Scene* scene, const SceneRendererCamera& camera) @@ -331,11 +338,11 @@ namespace Prism constexpr uint32_t cubemapSize = 2048; constexpr uint32_t irradianceMapSize = 32; - Ref envUnfiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize); + Ref envUnfiltered = TextureCube::Create(TextureFormat::RGBA16F, cubemapSize, cubemapSize); if (!equirectangularConversionShader) equirectangularConversionShader = Shader::Create("assets/shaders/EquirectangularToCubeMap.glsl"); Ref envEquirect = Texture2D::Create(filepath); - if (envEquirect->GetFormat() != TextureFormat::Float16) + if (envEquirect->GetFormat() != TextureFormat::RGBA16F) PM_CORE_WARN("Texture is not HDR!"); equirectangularConversionShader->Bind(); @@ -351,7 +358,7 @@ namespace Prism if (!envFilteringShader) envFilteringShader = Shader::Create("assets/shaders/EnvironmentMipFilter.glsl"); - Ref envFiltered = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize); + Ref envFiltered = TextureCube::Create(TextureFormat::RGBA16F, cubemapSize, cubemapSize); Renderer::Submit([envUnfiltered, envFiltered]() { @@ -377,7 +384,7 @@ namespace Prism if (!envIrradianceShader) envIrradianceShader = Shader::Create("assets/shaders/EnvironmentIrradiance.glsl"); - Ref irradianceMap = TextureCube::Create(TextureFormat::Float16, irradianceMapSize, irradianceMapSize); + Ref irradianceMap = TextureCube::Create(TextureFormat::RGBA16F, irradianceMapSize, irradianceMapSize); envIrradianceShader->Bind(); envFiltered->Bind(); Renderer::Submit([irradianceMap]() @@ -393,19 +400,18 @@ namespace Prism static Ref preethamSkyShader; - Ref Renderer3D::CreatePreethamSky(float turbidity, float azimuth, float inclination) + Ref Renderer3D::CreatePreethamSky(const glm::vec3& turbidityAzimuthInclination) { constexpr uint32_t cubemapSize = 2048; - Ref environmentMap = TextureCube::Create(TextureFormat::Float16, cubemapSize, cubemapSize); + Ref environmentMap = TextureCube::Create(TextureFormat::RGBA16F, cubemapSize, cubemapSize); if (!preethamSkyShader) preethamSkyShader = Shader::Create("assets/shaders/PreethamSky.glsl"); preethamSkyShader->Bind(); - const glm::vec3 TurbidityAzimuthInclination = { turbidity, azimuth, inclination}; - preethamSkyShader->SetFloat3("u_TurbidityAzimuthInclination", TurbidityAzimuthInclination); + preethamSkyShader->SetFloat3("u_TurbidityAzimuthInclination", turbidityAzimuthInclination); Renderer::Submit([environmentMap, cubemapSize]() { @@ -418,13 +424,6 @@ namespace Prism return environmentMap; } - /* - Ref Renderer3D::GetFinalRenderPass() - { - return s_Data.CompositePass; - } - */ - Ref Renderer3D::GetGeoPass() { return s_Data.GeoPass; @@ -441,12 +440,6 @@ namespace Prism s_Data.FocusPoint = point; } - /* - uint32_t Renderer3D::GetFinalColorBufferRendererID() - { - return s_Data.CompositePass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); - } - */ SceneRendererOptions& Renderer3D::GetOptions() { @@ -475,6 +468,8 @@ namespace Prism Renderer::Submit([] { s_Stats.GeometryPass = s_Stats.GeometryPassTimer.ElapsedMillis(); }); } + ResolveMSAA(); + // Compute average luminance and update exposure (GPU-copy + mipmap -> read 1 texel) { Renderer::Submit([]() { s_Stats.AutoExposurePassTimer.Reset(); }); @@ -482,30 +477,13 @@ namespace Prism Renderer::Submit([] { s_Stats.AutoExposurePass = s_Stats.AutoExposurePassTimer.ElapsedMillis(); }); } + BloomBlurPass(); + + OverlayPass(); + { Renderer::Submit([]() { s_Stats.CompositePassTimer.Reset(); }); - // CompositePass(); - { - Renderer::BeginRenderPass(outRenderPass); - - s_Data.CompositeShader->Bind(); - - s_Data.AutoExposureData.ExposureSSBO->BindBase(2); - s_Data.CompositeShader->SetBool("u_EnableAutoExposure",s_Data.AutoExposureData.EnableAutoExposure); - s_Data.CompositeShader->SetFloat("u_ManualExposure", s_Data.SceneData.SceneCamera.Camera.GetExposure()); - s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples); - s_Data.CompositeShader->SetFloat("u_EnableBloom", s_Data.EnableBloom); - - s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture(); - Renderer::Submit([]() - { - glBindTextureUnit(1, s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID()); - }); - - Renderer::SubmitFullscreenQuad(nullptr); - - Renderer::EndRenderPass(); - } + CompositePass(outRenderPass); Renderer::Submit([] { s_Stats.CompositePass = s_Stats.CompositePassTimer.ElapsedMillis(); }); // BloomBlurPass(); } @@ -517,6 +495,119 @@ namespace Prism s_Data.SceneData = {}; } + void Renderer3D::AutoExposurePass() + { + auto& ae = s_Data.AutoExposureData; + if (!ae.EnableAutoExposure) + return; + + auto srcFB = s_Data.GeoPass->GetSpecification().TargetFramebuffer; + auto dstFB = ae.LuminancePass->GetSpecification().TargetFramebuffer; + if (!srcFB || !dstFB) return; + + float dt = ae.ExposureTimer; + ae.ExposureTimer.Reset(); + + Renderer::Submit([srcFB, dstFB, logMin = ae.LogMin, logMax = ae.LogMax, histCS = ae.HistogramCS, histSSBO = ae.HistogramSSBO]() { + glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFB->GetRendererID()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFB->GetRendererID()); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glBlitFramebuffer(0, 0, srcFB->GetWidth(), srcFB->GetHeight(), + 0, 0, dstFB->GetWidth(), dstFB->GetHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + const uint32_t zero = 0; + glClearNamedBufferData(histSSBO->GetRendererID(), GL_R32UI, GL_RED, GL_UNSIGNED_INT, &zero); + + glUseProgram(histCS->GetRendererID()); + glBindTextureUnit(0, dstFB->GetColorAttachmentRendererID()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, histSSBO->GetRendererID()); + + const GLint locLogMin = glGetUniformLocation(histCS->GetRendererID(), "u_LogMin"); + const GLint locLogMax = glGetUniformLocation(histCS->GetRendererID(), "u_LogMax"); + if (locLogMin != -1) glProgramUniform1f(histCS->GetRendererID(), locLogMin, logMin); + if (locLogMax != -1) glProgramUniform1f(histCS->GetRendererID(), locLogMax, logMax); + + const uint32_t groupsX = (dstFB->GetWidth() + 15) / 16; + const uint32_t groupsY = (dstFB->GetHeight() + 15) / 16; + glDispatchCompute(groupsX, groupsY, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + }); + + Renderer::Submit([&ae, dt]() { + glUseProgram(ae.ExposureCS->GetRendererID()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ae.HistogramSSBO->GetRendererID()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ae.ExposureSSBO->GetRendererID()); + + auto setUniform = [&](const char* name, const float value) { + const GLint loc = glGetUniformLocation(ae.ExposureCS->GetRendererID(), name); + if (loc != -1) glProgramUniform1f(ae.ExposureCS->GetRendererID(), loc, value); + }; + + setUniform("u_SpeedUp", ae.SpeedUp); + setUniform("u_SpeedDown", ae.SpeedDown); + setUniform("u_Key", ae.Key); + setUniform("u_LowPercent", ae.LowPercent); + setUniform("u_HighPercent", ae.HighPercent); + setUniform("u_MinExposure", ae.MinExposure); + setUniform("u_MaxExposure", ae.MaxExposure); + setUniform("u_DeltaTime", dt); + setUniform("u_LogMin", ae.LogMin); + setUniform("u_LogMax", ae.LogMax); + + glDispatchCompute(1, 1, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + }); + } + + void Renderer3D::ShadowMapPass() + { + const auto& directionalLights = s_Data.SceneData.SceneLightEnvironment.DirectionalLights; + if (!s_Data.ShadowEnabled || directionalLights[0].Intensity == 0.0f || !directionalLights[0].CastShadows) + { + // Clear shadow maps + Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass); + Renderer::EndRenderPass(); + return; + } + + // TODO: this will not be hardcode + const glm::vec3 lightDir = glm::normalize(directionalLights[0].Direction); // 光线方向(从光源指向场景) + const glm::vec3 lightPos = lightDir * 100.0f; + const glm::mat4 lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + + const float orthoSize = 100.0f; + const float nearPlane = 0.01f, farPlane = 1000.0f; + const glm::mat4 lightProjection = glm::ortho(-orthoSize, orthoSize, -orthoSize, orthoSize, nearPlane, farPlane); + const glm::mat4 lightSpaceMatrix = lightProjection * lightView; + + Renderer::Submit([]() + { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + }); + + { + Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass); + + s_Data.LightMatrices = lightSpaceMatrix; + + + // Render entities + for (auto& dc : s_Data.ShadowPassDrawList) + { + Ref shader = dc.mesh->IsAnimated() ? s_Data.ShadowMapAnimShader : s_Data.ShadowMapShader; + shader->SetMat4("u_LightViewProjection", lightSpaceMatrix); + Renderer::SubmitMeshWithShader(dc.mesh, dc.Transform, shader); + } + + Renderer::EndRenderPass(); + } + } + void Renderer3D::GeometryPass() { const bool outline = !s_Data.SelectedMeshDrawList.empty(); @@ -549,7 +640,6 @@ namespace Prism // Skybox - auto skyboxShader = s_Data.SceneData.SkyboxMaterial->GetShader(); s_Data.SceneData.SkyboxMaterial->Set("u_InverseVP", glm::inverse(cameraViewProjection)); s_Data.SceneData.SkyboxMaterial->Set("u_SkyIntensity", s_Data.SceneData.SceneEnvironmentIntensity); // s_Data.SceneInfo.EnvironmentIrradianceMap->Bind(0); @@ -830,24 +920,7 @@ namespace Prism // Grid - const auto option = GetOptions(); - if (option.ShowGrid) - { - s_Data.GridData.GridMaterial->Set("u_View", sceneCamera.ViewMatrix); - s_Data.GridData.GridMaterial->Set("u_Projection", cameraProjection); - s_Data.GridData.GridMaterial->Set("u_CameraPosition", cameraPosition); - - // grid config - s_Data.GridData.GridMaterial->Set("u_GridPlane", s_Data.GridData.GridPlane); - s_Data.GridData.GridMaterial->Set("u_GridScale", s_Data.GridData.GridScale); - s_Data.GridData.GridMaterial->Set("u_GridColorThin", s_Data.GridData.GridColorThin); - s_Data.GridData.GridMaterial->Set("u_GridColorThick", s_Data.GridData.GridColorThick); - s_Data.GridData.GridMaterial->Set("u_AxisColorX", s_Data.GridData.AxisColorX); - s_Data.GridData.GridMaterial->Set("u_AxisColorZ", s_Data.GridData.AxisColorZ); - s_Data.GridData.GridMaterial->Set("u_FadeDistance", s_Data.GridData.FadeDistance); - - Renderer::SubmitFullscreenQuad(s_Data.GridData.GridMaterial); - } + const auto option = GetOptions(); if (option.ShowBoundingBoxes) { @@ -860,74 +933,174 @@ namespace Prism Renderer::EndRenderPass(); } - void Renderer3D::AutoExposurePass() + void Renderer3D::BloomBlurPass() { - auto& ae = s_Data.AutoExposureData; - if (!ae.EnableAutoExposure) + if (!s_Data.EnableBloom) + { + // 如果关闭 Bloom,可以清除 BloomBlendPass(避免使用旧数据) + Renderer::BeginRenderPass(s_Data.BloomBlendPass); + Renderer::EndRenderPass(); return; + } - auto srcFB = s_Data.GeoPass->GetSpecification().TargetFramebuffer; - auto dstFB = ae.LuminancePass->GetSpecification().TargetFramebuffer; - if (!srcFB || !dstFB) return; + uint32_t srcTex = s_Data.ResolvedHDRTexture->GetRendererID(); + const int iterations = 5; // 模糊迭代次数,可调 - float dt = ae.ExposureTimer; - ae.ExposureTimer.Reset(); + // 第一次:提取高光 + 水平模糊 + { + Renderer::BeginRenderPass(s_Data.BloomBlurPass[0]); + s_Data.BloomBlurShader->Bind(); + s_Data.BloomBlurShader->SetInt("u_Texture", 0); + // s_Data.BloomBlurShader->SetBool("u_Horizontal", true); + s_Data.BloomBlurShader->SetBool("u_FirstPass", true); + s_Data.BloomBlurShader->SetFloat("u_Threshold", s_Data.BloomThreshold); + Renderer::Submit([srcTex]() { glBindTextureUnit(0, srcTex); }); + Renderer::SubmitFullscreenQuad(nullptr); + Renderer::EndRenderPass(); + } - Renderer::Submit([srcFB, dstFB, logMin = ae.LogMin, logMax = ae.LogMax, histCS = ae.HistogramCS, histSSBO = ae.HistogramSSBO]() { - glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFB->GetRendererID()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFB->GetRendererID()); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glBlitFramebuffer(0, 0, srcFB->GetWidth(), srcFB->GetHeight(), - 0, 0, dstFB->GetWidth(), dstFB->GetHeight(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + // 后续迭代 + for (int i = 1; i < iterations; ++i) + { + bool horizontal = (i % 2 == 1); // 第二次垂直,第三次水平... + uint32_t inputTex = (i % 2 == 1) ? + s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID() : + s_Data.BloomBlurPass[1]->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); + auto outputPass = (i % 2 == 1) ? s_Data.BloomBlurPass[1] : s_Data.BloomBlurPass[0]; - const uint32_t zero = 0; - glClearNamedBufferData(histSSBO->GetRendererID(), GL_R32UI, GL_RED, GL_UNSIGNED_INT, &zero); + Renderer::BeginRenderPass(outputPass); + s_Data.BloomBlurShader->Bind(); + s_Data.BloomBlurShader->SetInt("u_Texture", 0); + // s_Data.BloomBlurShader->SetBool("u_Horizontal", horizontal); + s_Data.BloomBlurShader->SetBool("u_FirstPass", false); + Renderer::Submit([inputTex]() { glBindTextureUnit(0, inputTex); }); + Renderer::SubmitFullscreenQuad(nullptr); + Renderer::EndRenderPass(); + } - glUseProgram(histCS->GetRendererID()); - glBindTextureUnit(0, dstFB->GetColorAttachmentRendererID()); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, histSSBO->GetRendererID()); + // 将最终模糊结果拷贝到 BloomBlendPass(供合成使用) + uint32_t finalBlurTex = (iterations % 2 == 0) ? + s_Data.BloomBlurPass[1]->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID() : + s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); - const GLint locLogMin = glGetUniformLocation(histCS->GetRendererID(), "u_LogMin"); - const GLint locLogMax = glGetUniformLocation(histCS->GetRendererID(), "u_LogMax"); - if (locLogMin != -1) glProgramUniform1f(histCS->GetRendererID(), locLogMin, logMin); - if (locLogMax != -1) glProgramUniform1f(histCS->GetRendererID(), locLogMax, logMax); - - const uint32_t groupsX = (dstFB->GetWidth() + 15) / 16; - const uint32_t groupsY = (dstFB->GetHeight() + 15) / 16; - glDispatchCompute(groupsX, groupsY, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - }); - - Renderer::Submit([&ae, dt]() { - glUseProgram(ae.ExposureCS->GetRendererID()); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ae.HistogramSSBO->GetRendererID()); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ae.ExposureSSBO->GetRendererID()); - - auto setUniform = [&](const char* name, const float value) { - const GLint loc = glGetUniformLocation(ae.ExposureCS->GetRendererID(), name); - if (loc != -1) glProgramUniform1f(ae.ExposureCS->GetRendererID(), loc, value); - }; - - setUniform("u_SpeedUp", ae.SpeedUp); - setUniform("u_SpeedDown", ae.SpeedDown); - setUniform("u_Key", ae.Key); - setUniform("u_LowPercent", ae.LowPercent); - setUniform("u_HighPercent", ae.HighPercent); - setUniform("u_MinExposure", ae.MinExposure); - setUniform("u_MaxExposure", ae.MaxExposure); - setUniform("u_DeltaTime", dt); - setUniform("u_LogMin", ae.LogMin); - setUniform("u_LogMax", ae.LogMax); - - glDispatchCompute(1, 1, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - }); + Renderer::BeginRenderPass(s_Data.BloomBlendPass); + s_Data.BloomBlurShader->Bind(); + s_Data.BloomBlurShader->SetInt("u_Texture", 0); + // s_Data.BloomBlurShader->SetBool("u_Horizontal", false); + s_Data.BloomBlurShader->SetBool("u_FirstPass", false); + Renderer::Submit([finalBlurTex]() { glBindTextureUnit(0, finalBlurTex); }); + Renderer::SubmitFullscreenQuad(nullptr); + Renderer::EndRenderPass(); } + void Renderer3D::OverlayPass() + { + Renderer::BeginRenderPass(s_Data.GeoPass, false); + + if (const auto option = GetOptions(); option.ShowGrid) + { + const auto& sceneCamera = s_Data.SceneData.SceneCamera; + + const auto cameraProjection = sceneCamera.Camera.GetProjectionMatrix(); + const glm::vec3 cameraPosition = glm::inverse(s_Data.SceneData.SceneCamera.ViewMatrix)[3]; // TODO: Negate instead + + s_Data.GridData.GridMaterial->Set("u_View", sceneCamera.ViewMatrix); + s_Data.GridData.GridMaterial->Set("u_Projection", cameraProjection); + s_Data.GridData.GridMaterial->Set("u_CameraPosition", cameraPosition); + + // grid config + s_Data.GridData.GridMaterial->Set("u_GridPlane", s_Data.GridData.GridPlane); + s_Data.GridData.GridMaterial->Set("u_GridScale", s_Data.GridData.GridScale); + s_Data.GridData.GridMaterial->Set("u_GridColorThin", s_Data.GridData.GridColorThin); + s_Data.GridData.GridMaterial->Set("u_GridColorThick", s_Data.GridData.GridColorThick); + s_Data.GridData.GridMaterial->Set("u_AxisColorX", s_Data.GridData.AxisColorX); + s_Data.GridData.GridMaterial->Set("u_AxisColorZ", s_Data.GridData.AxisColorZ); + s_Data.GridData.GridMaterial->Set("u_FadeDistance", s_Data.GridData.FadeDistance); + + Renderer::SubmitFullscreenQuad(s_Data.GridData.GridMaterial); + } + + Renderer::EndRenderPass(); + } + + void Renderer3D::CompositePass(const Ref& outRenderPass) + { + Renderer::BeginRenderPass(outRenderPass); + + s_Data.CompositeShader->Bind(); + + s_Data.AutoExposureData.ExposureSSBO->BindBase(2); + s_Data.CompositeShader->SetBool("u_EnableAutoExposure", s_Data.AutoExposureData.EnableAutoExposure); + s_Data.CompositeShader->SetFloat("u_ManualExposure", s_Data.SceneData.SceneCamera.Camera.GetExposure()); + s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples); + s_Data.CompositeShader->SetBool("u_EnableBloom", s_Data.EnableBloom); + + // 绑定几何阶段颜色纹理(多重采样) + s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture(0); // 通常绑定到单元0 + Renderer::Submit([]() { + glBindTextureUnit(1, s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID()); + }); + + // 新增:绑定 Bloom 纹理(如果启用) + if (s_Data.EnableBloom) + { + uint32_t bloomTex = s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); + Renderer::Submit([bloomTex]() { + glBindTextureUnit(2, bloomTex); // 绑定到单元2 + }); + s_Data.CompositeShader->SetInt("u_BloomTexture", 2); // 告诉着色器使用单元2 + } + + Renderer::SubmitFullscreenQuad(nullptr); + + Renderer::EndRenderPass(); + } + + + /* + void Renderer3D::CompositePass(const Ref& outRenderPass) + { + Renderer::BeginRenderPass(outRenderPass); + + s_Data.CompositeShader->Bind(); + + s_Data.BloomBlendShader->Bind(); + s_Data.BloomBlendShader->SetBool("u_EnableBloom", s_Data.EnableBloom); + + s_Data.AutoExposureData.ExposureSSBO->BindBase(2); + + Renderer::Submit([]() { + glBindTextureUnit(0, s_Data.ResolvedHDRTexture->GetRendererID()); + }); + s_Data.BloomBlendShader->SetInt("u_SceneTexture", 0); + + s_Data.CompositeShader->SetBool("u_EnableAutoExposure",s_Data.AutoExposureData.EnableAutoExposure); + s_Data.CompositeShader->SetFloat("u_ManualExposure", s_Data.SceneData.SceneCamera.Camera.GetExposure()); + s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples); + s_Data.CompositeShader->SetFloat("u_EnableBloom", s_Data.EnableBloom); + + if (s_Data.EnableBloom) + { + uint32_t bloomTex = s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); + Renderer::Submit([bloomTex]() { + glBindTextureUnit(1, bloomTex); + }); + s_Data.BloomBlendShader->SetInt("u_BloomTexture", 1); + } + + s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture(); + Renderer::Submit([]() + { + glBindTextureUnit(1, s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID()); + }); + + Renderer::SubmitFullscreenQuad(nullptr); + + Renderer::EndRenderPass(); + } + */ + + /* struct FrustumBounds { @@ -1084,61 +1257,47 @@ namespace Prism return corners; } - void Renderer3D::ShadowMapPass() + + void Renderer3D::ResolveMSAA() { - const auto& directionalLights = s_Data.SceneData.SceneLightEnvironment.DirectionalLights; - if (directionalLights[0].Intensity == 0.0f || !directionalLights[0].CastShadows) + auto srcFB = s_Data.GeoPass->GetSpecification().TargetFramebuffer; + const uint32_t width = srcFB->GetWidth(); + const uint32_t height = srcFB->GetHeight(); + + if (!s_Data.ResolvedHDRTexture || + s_Data.ResolvedHDRTexture->GetWidth() != width || + s_Data.ResolvedHDRTexture->GetHeight() != height) { - for (int i = 0; i < 4; i++) - { - // Clear shadow maps - Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass); - Renderer::EndRenderPass(); - } - return; + s_Data.ResolvedHDRTexture = Texture2D::Create(TextureFormat::RGBA16F, width, height); } - // TODO: this will not be hardcode - const glm::vec3 lightDir = glm::normalize(directionalLights[0].Direction); // 光线方向(从光源指向场景) - const glm::vec3 lightPos = lightDir * 100.0f; - const glm::mat4 lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + Renderer::Submit([srcFB, resolvedTex = s_Data.ResolvedHDRTexture]() { + GLuint resolveFBO; + glGenFramebuffers(1, &resolveFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolvedTex->GetRendererID(), 0); - const float orthoSize = 100.0f; - const float nearPlane = 0.01f, farPlane = 1000.0f; - const glm::mat4 lightProjection = glm::ortho(-orthoSize, orthoSize, -orthoSize, orthoSize, nearPlane, farPlane); - const glm::mat4 lightSpaceMatrix = lightProjection * lightView; + glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFB->GetRendererID()); + glReadBuffer(GL_COLOR_ATTACHMENT0); - Renderer::Submit([]() - { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + glBlitFramebuffer(0, 0, srcFB->GetWidth(), srcFB->GetHeight(), + 0, 0, srcFB->GetWidth(), srcFB->GetHeight(), + GL_COLOR_BUFFER_BIT, GL_LINEAR); + + glDeleteFramebuffers(1, &resolveFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); }); - - { - Renderer::BeginRenderPass(s_Data.ShadowMapRenderPass); - - s_Data.LightMatrices = lightSpaceMatrix; - - - // Render entities - for (auto& dc : s_Data.ShadowPassDrawList) - { - Ref shader = dc.mesh->IsAnimated() ? s_Data.ShadowMapAnimShader : s_Data.ShadowMapShader; - shader->SetMat4("u_LightViewProjection", lightSpaceMatrix); - Renderer::SubmitMeshWithShader(dc.mesh, dc.Transform, shader); - } - - Renderer::EndRenderPass(); - } } + void SceneRenderer::OnImGuiRender() { ImGui::Begin("Scene Renderer"); - UI::Property("Composite Pass time", s_Stats.CompositePass); UI::Property("Geometry Pass time", s_Stats.GeometryPass); + UI::Property("Composite Pass time", s_Stats.CompositePass); UI::Property("Shadow Pass time", s_Stats.ShadowPass); UI::Property("AutoExposure Pass time", s_Stats.AutoExposurePass); @@ -1207,10 +1366,15 @@ namespace Prism auto fb = s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer; const auto id = fb->GetColorAttachmentRendererID(); + auto fb2 = s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer; + const auto id2 = fb2->GetColorAttachmentRendererID(); + const float size = ImGui::GetContentRegionAvail().x; // (float)fb->GetWidth() * 0.5f, (float)fb->GetHeight() * 0.5f float w = size; float h = w / ((float)fb->GetWidth() / (float)fb->GetHeight()); ImGui::Image((ImTextureID)id, { w, h }, { 0, 1 }, { 1, 0 }); + ImGui::Image((ImTextureID)id2, { w, h }, { 0, 1 }, { 1, 0 }); + ImGui::Image((ImTextureID)s_Data.ResolvedHDRTexture->GetRendererID(), { w, h }, { 0, 1 }, { 1, 0 }); UI::EndTreeNode(); } diff --git a/Prism/src/Prism/Renderer/Renderer3D.h b/Prism/src/Prism/Renderer/Renderer3D.h index 42cf05f..e11a3ef 100644 --- a/Prism/src/Prism/Renderer/Renderer3D.h +++ b/Prism/src/Prism/Renderer/Renderer3D.h @@ -41,7 +41,7 @@ namespace Prism static void SubmitColliderMesh(const CapsuleColliderComponent& component, const glm::mat4& parentTransform = glm::mat4(1.0f)); static void SubmitColliderMesh(const MeshColliderComponent& component, const glm::mat4& parentTransform = glm::mat4(1.0f)); static std::pair, Ref> CreateEnvironmentMap(const std::string& filepath); - static Ref CreatePreethamSky(float turbidity, float azimuth, float inclination); + static Ref CreatePreethamSky(const glm::vec3& turbidityAzimuthInclination); // static Ref GetFinalRenderPass(); static Ref GetGeoPass(); @@ -59,10 +59,15 @@ namespace Prism static void FlushDrawList(Ref& outRenderPass); static void AutoExposurePass(); - static void GeometryPass(); - // static void CompositePass(); - // static void BloomBlurPass(); static void ShadowMapPass(); + static void GeometryPass(); + static void BloomBlurPass(); + static void OverlayPass(); + + static void CompositePass(const Ref& outRenderPass); + + + static void ResolveMSAA(); }; } diff --git a/Prism/src/Prism/Renderer/SceneRenderer.h b/Prism/src/Prism/Renderer/SceneRenderer.h index 78d3484..f55f371 100644 --- a/Prism/src/Prism/Renderer/SceneRenderer.h +++ b/Prism/src/Prism/Renderer/SceneRenderer.h @@ -23,9 +23,6 @@ namespace Prism { Prism::Camera Camera; glm::mat4 ViewMatrix; - - float Near, Far; - float FOV; }; class PRISM_API SceneRenderer diff --git a/Prism/src/Prism/Renderer/Texture.h b/Prism/src/Prism/Renderer/Texture.h index 1339e51..a7d9e67 100644 --- a/Prism/src/Prism/Renderer/Texture.h +++ b/Prism/src/Prism/Renderer/Texture.h @@ -18,7 +18,7 @@ namespace Prism None = 0, RGB = 1, RGBA = 2, - Float16 = 3, + RGBA16F = 3, }; enum class TextureWrap @@ -62,6 +62,7 @@ namespace Prism virtual void Lock() = 0; virtual void Unlock() = 0; + virtual void SetData(const void* data, int count) = 0; virtual void Resize(uint32_t width, uint32_t height) = 0; virtual Buffer GetWriteableBuffer() = 0; diff --git a/Prism/src/Prism/Scene/Components.h b/Prism/src/Prism/Scene/Components.h index df13f3b..e876184 100644 --- a/Prism/src/Prism/Scene/Components.h +++ b/Prism/src/Prism/Scene/Components.h @@ -91,13 +91,32 @@ namespace Prism struct MeshComponent { Ref Mesh; + // std::vector> Materials; MeshComponent() = default; MeshComponent(const MeshComponent& other) = default; MeshComponent(const Ref& mesh) - : Mesh(mesh) {} + : Mesh(mesh) {} operator Ref () { return Mesh; } + + /* + MeshComponent(Ref mesh) + : Mesh(mesh) + { + // 复制 Mesh 的材质实例,每个实体拥有独立副本 + if (mesh) + { + const auto& srcMaterials = mesh->GetMaterials(); + Materials.reserve(srcMaterials.size()); + for (auto& srcMat : srcMaterials) + { + auto newMat = MaterialInstance::Copy(srcMat); + Materials.push_back(newMat); + } + } + } + */ }; struct AnimationComponent @@ -126,6 +145,7 @@ namespace Prism { SceneCamera Camera; bool Primary = true; + bool ShowIcon = true; CameraComponent() = default; CameraComponent(const CameraComponent& other) = default; @@ -373,6 +393,7 @@ namespace Prism bool CastShadows = true; bool SoftShadows = true; float LightSize = 0.5f; // For PCSS + bool ShowIcon = true; }; struct PointLightComponent @@ -381,6 +402,7 @@ namespace Prism float Radius = 10.0f; float Intensity = 1.0f; uint32_t CastShadows; + bool ShowIcon = true; PointLightComponent() = default; PointLightComponent(const PointLightComponent& other) = default; @@ -395,6 +417,7 @@ namespace Prism float InnerConeAngle = glm::radians(30.0f); // 内锥角(半角) float OuterConeAngle = glm::radians(45.0f); // 外锥角(半角) bool CastShadows = true; // 聚光通常需要阴影 + bool ShowIcon = true; SpotLightComponent() = default; SpotLightComponent(const SpotLightComponent& other) = default; @@ -405,6 +428,7 @@ namespace Prism Ref SceneEnvironment; float Intensity = 1.0f; float Angle = 0.0f; + bool ShowIcon = false; bool DynamicSky = false; glm::vec3 TurbidityAzimuthInclination = { 2.0, 0.0, 0.0 }; diff --git a/Prism/src/Prism/Scene/Scene.cpp b/Prism/src/Prism/Scene/Scene.cpp index 1057960..8cebea5 100644 --- a/Prism/src/Prism/Scene/Scene.cpp +++ b/Prism/src/Prism/Scene/Scene.cpp @@ -159,34 +159,15 @@ namespace Prism return; const glm::mat4 cameraViewMatrix = glm::inverse(GetTransformRelativeToParent(cameraEntity)); - PM_CORE_ASSERT(cameraEntity, "Scene does not contain any cameras!"); SceneCamera& camera = cameraEntity.GetComponent(); camera.SetViewportSize(m_ViewportWidth, m_ViewportHeight); - - ///////////////////////////////////////////////////////////////////// // RENDER 3D SCENE // ///////////////////////////////////////////////////////////////////// // Process lights - { - m_LightEnvironment = LightEnvironment(); - const auto lights = m_Registry.group(entt::get); - uint32_t directionalLightIndex = 0; - for (const auto entity : lights) - { - auto [transformComponent, lightComponent] = lights.get(entity); - const glm::vec3 direction = -glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(0.0f, 0.0f, -1.0f)); - m_LightEnvironment.DirectionalLights[directionalLightIndex++] = - { - direction, - lightComponent.Radiance, - lightComponent.Intensity, - lightComponent.CastShadows - }; - } - } + UpdateLights(); // TODO: only one sky light at the moment! { @@ -248,70 +229,9 @@ namespace Prism void Scene::OnRenderEditor(const TimeStep ts, const EditorCamera& editorCamera) { - ///////////////////////////////////////////////////////////////////// - // RENDER 3D SCENE // - ///////////////////////////////////////////////////////////////////// - // Process lights - { - const auto lights = m_Registry.group(entt::get); - uint32_t directionalLightIndex = 0; - for (const auto entity : lights) - { - auto [transformComponent, lightComponent] = lights.get(entity); - const glm::vec3 direction = glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(0.0f, 0.0f,1.0f)); - m_LightEnvironment.DirectionalLights[directionalLightIndex++] = - { - direction, - lightComponent.Radiance, - lightComponent.Intensity, - lightComponent.CastShadows - }; - } - } - - { - const auto pointLights = m_Registry.group(entt::get); - uint32_t pointLightIndex = 0; - for (const auto entity : pointLights) - { - if (pointLightIndex >= 8) break; - auto [transform, light] = pointLights.get(entity); - m_LightEnvironment.PointLights[pointLightIndex++] = { - transform.Translation, - light.Radiance, - light.Radius, - light.Intensity, - light.CastShadows, - }; - - m_LightEnvironment.PointLightCount ++; - } - } - - { - const auto spotLights = m_Registry.group(entt::get); - uint32_t pointLightIndex = 0; - for (const auto entity : spotLights) - { - if (pointLightIndex >= 8) break; - auto [transform, light] = spotLights.get(entity); - const glm::vec3 direction = glm::normalize(glm::mat3(transform.GetTransform()) * glm::vec3(0.0f, 0.0f, 1.0f)); - const float innerCos = glm::cos(glm::radians(light.InnerConeAngle)); - const float outerCos = glm::cos(glm::radians(light.OuterConeAngle)); - m_LightEnvironment.SpotLights[pointLightIndex++] = { - transform.Translation, - direction, - light.Radiance, - light.Intensity, - light.Range, - innerCos, - outerCos, - light.CastShadows, - }; - m_LightEnvironment.SpotLightCount ++; - } - } + // Process lights Direction, Point, Spot + UpdateLights(); // TODO: only one sky light at the moment! { @@ -325,7 +245,7 @@ namespace Prism auto [transformComponent, skyLightComponent] = lights.get(entity); if (!skyLightComponent.SceneEnvironment && skyLightComponent.DynamicSky) { - Ref preethamEnv = Renderer3D::CreatePreethamSky(skyLightComponent.TurbidityAzimuthInclination.x, skyLightComponent.TurbidityAzimuthInclination.y, skyLightComponent.TurbidityAzimuthInclination.z); + Ref preethamEnv = Renderer3D::CreatePreethamSky(skyLightComponent.TurbidityAzimuthInclination); skyLightComponent.SceneEnvironment = Ref::Create(preethamEnv, preethamEnv); } @@ -341,8 +261,13 @@ namespace Prism // TODO: this value should be storage and can modify // TODO: Renderer2D cannot blend with Renderer3D - SceneRenderer::BeginScene(this, { static_cast(editorCamera), editorCamera.GetViewMatrix(), 0.1f, 1000.0f, 45.0f}, false); + SceneRenderer::BeginScene(this, { static_cast(editorCamera), editorCamera.GetViewMatrix()}, false); { + + ///////////////////////////////////////////////////////////////////// + // RENDER 3D SCENE // + ///////////////////////////////////////////////////////////////////// + const auto group = m_Registry.group(entt::get); { for (const auto [entity, meshComponent, transformComponent]: group.each()) @@ -400,23 +325,57 @@ namespace Prism // render camera icon { + const auto editorCameraPosition = editorCamera.GetPosition(); + const auto editorCameraUpDirection = editorCamera.GetUpDirection(); + const auto cameras = m_Registry.view(); if (!cameras.empty()) { for (auto& entity : cameras) { Entity e = { entity, this }; - SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_CameraIcon, editorCamera.GetPosition(), editorCamera.GetUpDirection()); + if (!e.GetComponent().ShowIcon) continue; + SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_CameraIcon, editorCameraPosition, editorCameraUpDirection); } } - const auto lights = m_Registry.view(); - if (!lights.empty()) + if (const auto skyLights = m_Registry.view(); !skyLights.empty()) { - for (auto& entity : lights) + for (auto& entity : skyLights) { Entity e = { entity, this }; - SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCamera.GetPosition(), editorCamera.GetUpDirection()); + if (!e.GetComponent().ShowIcon) continue; + SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection); + } + } + + if (const auto directionLight = m_Registry.view(); !directionLight.empty()) + { + for (auto& entity : directionLight) + { + Entity e = { entity, this }; + if (!e.GetComponent().ShowIcon) continue; + SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection); + } + } + + if (const auto pointLight = m_Registry.view(); !pointLight.empty()) + { + for (auto& entity : pointLight ) + { + Entity e = { entity, this }; + if (!e.GetComponent().ShowIcon) continue; + SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection); + } + } + + if (const auto spotLight = m_Registry.view(); !spotLight.empty()) + { + for (auto& entity : spotLight ) + { + Entity e = { entity, this }; + if (!e.GetComponent().ShowIcon) continue; + SceneRenderer::SubmitBillBoardQuad(e.Transform().Translation, m_LightIcon, editorCameraPosition, editorCameraUpDirection); } } } @@ -446,6 +405,7 @@ namespace Prism // Box2D physics Physics2D::CreateBody(this); + // PhyX { auto view = m_Registry.view(); // Physics3D::ExpandEntityBuffer(static_cast(view.size())); @@ -485,11 +445,10 @@ namespace Prism Entity Scene::GetMainCameraEntity() { - auto view = m_Registry.view(); + const auto view = m_Registry.view(); for (auto entity : view) { - auto& comp = view.get(entity); - if (comp.Primary) + if (const auto& comp = view.get(entity); comp.Primary) return { entity, this }; } return {}; @@ -577,33 +536,6 @@ namespace Prism newEntity = CreateEntity(); CopyComponentIfExists(AllComponent{},newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - /* - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - CopyComponentIfExists(newEntity.m_EntityHandle, entity.m_EntityHandle, m_Registry); - */ - - } Entity Scene::FindEntityByTag(const std::string &tag) { @@ -613,7 +545,7 @@ namespace Prism { const auto& canditate = view.get(entity).Tag; if (canditate == tag) - return Entity(entity, this); + return {entity, this}; } return Entity{}; @@ -625,8 +557,7 @@ namespace Prism auto view = m_Registry.view(); for (auto entity : view) { - auto& idComponent = m_Registry.get(entity); - if (idComponent.ID == uuid) + if (auto& idComponent = m_Registry.get(entity); idComponent.ID == uuid) return {entity, this}; } @@ -660,32 +591,7 @@ namespace Prism enttMap[uuid] = e.m_EntityHandle; } CopyComponent(AllComponent{},target->m_Registry, m_Registry, enttMap); - /* - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - CopyComponent(target->m_Registry, m_Registry, enttMap); - */ const auto& entityInstanceMap = ScriptEngine::GetEntityInstanceMap(); if (entityInstanceMap.find(target->GetUUID()) != entityInstanceMap.end()) @@ -717,6 +623,72 @@ namespace Prism b2World_SetGravity(m_Registry.get(m_SceneEntity).World, {0.0f, gravity}); } + void Scene::UpdateLights() + { + // direction Light + { + const auto lights = m_Registry.group(entt::get); + uint32_t directionalLightIndex = 0; + for (const auto entity : lights) + { + auto [transformComponent, lightComponent] = lights.get(entity); + const glm::vec3 direction = glm::normalize(glm::mat3(transformComponent.GetTransform()) * glm::vec3(0.0f, 0.0f,1.0f)); + m_LightEnvironment.DirectionalLights[directionalLightIndex++] = + { + direction, + lightComponent.Radiance, + lightComponent.Intensity, + lightComponent.CastShadows + }; + } + } + + // Point Light + { + const auto pointLights = m_Registry.group(entt::get); + uint32_t pointLightIndex = 0; + for (const auto entity : pointLights) + { + if (pointLightIndex >= 8) break; + auto [transform, light] = pointLights.get(entity); + m_LightEnvironment.PointLights[pointLightIndex++] = { + transform.Translation, + light.Radiance, + light.Radius, + light.Intensity, + light.CastShadows, + }; + + m_LightEnvironment.PointLightCount ++; + } + } + + // Spot Light + { + const auto spotLights = m_Registry.group(entt::get); + uint32_t pointLightIndex = 0; + for (const auto entity : spotLights) + { + if (pointLightIndex >= 8) break; + auto [transform, light] = spotLights.get(entity); + const glm::vec3 direction = glm::normalize(glm::mat3(transform.GetTransform()) * glm::vec3(0.0f, 0.0f, 1.0f)); + const float innerCos = glm::cos(glm::radians(light.InnerConeAngle)); + const float outerCos = glm::cos(glm::radians(light.OuterConeAngle)); + m_LightEnvironment.SpotLights[pointLightIndex++] = { + transform.Translation, + direction, + light.Radiance, + light.Intensity, + light.Range, + innerCos, + outerCos, + light.CastShadows, + }; + m_LightEnvironment.SpotLightCount ++; + } + } + } + void Scene::DestroyEntity(Entity entity) { diff --git a/Prism/src/Prism/Scene/Scene.h b/Prism/src/Prism/Scene/Scene.h index 1d068dd..060b86a 100644 --- a/Prism/src/Prism/Scene/Scene.h +++ b/Prism/src/Prism/Scene/Scene.h @@ -139,6 +139,9 @@ namespace Prism // Editor-specific void SetSelectedEntity(const entt::entity entity) { m_SelectedEntity = entity; } + private: + void UpdateLights(); + private: UUID m_SceneID; entt::entity m_SceneEntity; diff --git a/Prism/src/Prism/Scene/SceneSerializer.cpp b/Prism/src/Prism/Scene/SceneSerializer.cpp index 6aff2c2..3182785 100644 --- a/Prism/src/Prism/Scene/SceneSerializer.cpp +++ b/Prism/src/Prism/Scene/SceneSerializer.cpp @@ -291,6 +291,9 @@ namespace Prism out << YAML::Key << "Intensity" << YAML::Value << skyLightComponent.Intensity; out << YAML::Key << "Angle" << YAML::Value << skyLightComponent.Angle; + out << YAML::Key << "DynamicSky" << YAML::Value << skyLightComponent.DynamicSky; + out << YAML::Key << "TurbidityAzimuthInclination" << YAML::Value << skyLightComponent.TurbidityAzimuthInclination; + out << YAML::EndMap; // SkyLightComponent } @@ -855,7 +858,7 @@ namespace Prism AssetHandle assetHandle; if (skyLightComponent["EnvironmentAssetPath"]) { - const std::string filePath = skyLightComponent["EnvironmentAssetPath"].as(); + const auto filePath = skyLightComponent["EnvironmentAssetPath"].as(); assetHandle = AssetsManager::GetAssetHandleFromFilePath(filepath); } else @@ -870,6 +873,10 @@ namespace Prism component.Intensity = skyLightComponent["Intensity"].as(); component.Angle = skyLightComponent["Angle"].as(); + + component.DynamicSky = skyLightComponent["DynamicSky"].as(); + component.TurbidityAzimuthInclination = skyLightComponent["TurbidityAzimuthInclination"].as(); + } if (auto cameraComponent = entity["CameraComponent"]) diff --git a/Prism/src/Prism/Script/ScriptWrappers.cpp b/Prism/src/Prism/Script/ScriptWrappers.cpp index b6912c5..fcd6032 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.cpp +++ b/Prism/src/Prism/Script/ScriptWrappers.cpp @@ -781,25 +781,7 @@ namespace Prism { namespace Script { void Prism_Texture2D_SetData(Ref* _this, MonoArray* inData, int32_t count) { Ref& instance = *_this; - - const uint32_t dataSize = count * sizeof(glm::vec4) / 4; - - instance->Lock(); - const Buffer buffer = instance->GetWriteableBuffer(); - PM_CORE_ASSERT(dataSize <= buffer.Size); - // Convert RGBA32F color to RGBA8 - auto pixels = static_cast(buffer.Data); - - for (uint32_t i = 0; i < instance->GetWidth() * instance->GetHeight(); i++) - { - const glm::vec4& value = mono_array_get(inData, glm::vec4, i); - *pixels++ = static_cast(value.x * 255.0f); - *pixels++ = static_cast(value.y * 255.0f); - *pixels++ = static_cast(value.z * 255.0f); - *pixels++ = static_cast(value.w * 255.0f); - } - - instance->Unlock(); + instance->SetData(inData, count); } void Prism_Material_Destructor(const Ref* _this)