From c3d3e20ab465d7920a3afea31a6f5b0c015edfd8 Mon Sep 17 00:00:00 2001 From: antopilo Date: Wed, 1 Sep 2021 22:31:45 -0400 Subject: [PATCH] Fixed shading in deferred. Added sky in deferred. Started render buffer abstraction --- Editor/resources/Shaders/deferred.shader | 166 +++++++++++++----- Editor/resources/Shaders/gbuffer.shader | 11 +- Editor/resources/Shaders/pbr.shader | 1 - Editor/src/EditorInterface.cpp | 10 ++ Nuake/src/Rendering/Buffers/RenderBuffer.h | 19 ++ Nuake/src/Rendering/Renderer.cpp | 50 ++++-- Nuake/src/Rendering/Renderer.h | 2 +- Nuake/src/Scene/Components/LightComponent.cpp | 5 - Nuake/src/Scene/Scene.cpp | 44 ++++- Nuake/src/Scene/Scene.h | 1 + Nuake/src/Window.cpp | 37 +++- Nuake/src/Window.h | 3 +- 12 files changed, 268 insertions(+), 81 deletions(-) create mode 100644 Nuake/src/Rendering/Buffers/RenderBuffer.h diff --git a/Editor/resources/Shaders/deferred.shader b/Editor/resources/Shaders/deferred.shader index 8f4e6b22..81c2bd9d 100644 --- a/Editor/resources/Shaders/deferred.shader +++ b/Editor/resources/Shaders/deferred.shader @@ -4,7 +4,6 @@ layout(location = 0) in vec3 VertexPosition; layout(location = 1) in vec2 UVPosition; out flat vec2 UV; -out vec3 FragPos; out mat4 InvProjection; out mat4 InvView; @@ -14,9 +13,9 @@ uniform mat4 u_View; void main() { UV = UVPosition; - FragPos = VertexPosition; InvProjection = inverse(u_Projection); InvView = inverse(u_View); + gl_Position = vec4(VertexPosition, 1.0f); } @@ -25,7 +24,6 @@ void main() out vec4 FragColor; -in vec3 FragPos; in vec2 UV; in mat4 InvProjection; in mat4 InvView; @@ -33,18 +31,24 @@ in mat4 InvView; // Camera uniform float u_Exposure; uniform vec3 u_EyePosition; -// IBL + +// Environmnent +uniform float u_FogAmount; +uniform float u_FogStepCount; uniform samplerCube u_IrradianceMap; uniform samplerCube u_PrefilterMap; uniform sampler2D u_BrdfLUT; -// Material +// GBuffer uniform sampler2D m_Depth; uniform sampler2D m_Albedo; uniform sampler2D m_Material; uniform sampler2D m_Normal; // Lights +const int MaxLight = 20; +uniform int LightCount = 0; + struct Light { int Type; // 0 = directional, 1 = point vec3 Direction; @@ -55,15 +59,19 @@ struct Light { float LinearAttenuation; float QuadraticAttenuation; mat4 LightTransform; + sampler2D ShadowMaps[4]; + float CascadeDepth[4]; + mat4 LightTransforms[4]; sampler2D ShadowMap; - + sampler2D RSMFlux; + sampler2D RSMNormal; + sampler2D RSMPos; + int Volumetric; }; -const int MaxLight = 20; -uniform int LightCount = 0; uniform Light Lights[MaxLight]; - +// Converts depth to World space coords. vec3 WorldPosFromDepth(float depth) { float z = depth * 2.0 - 1.0; @@ -78,7 +86,7 @@ vec3 WorldPosFromDepth(float depth) { return worldSpacePosition.xyz; } -const float PI = 3.141592653589793f; // mark this as static const wait idk if you can do that in glsl +const float PI = 3.141592653589793f; float height_scale = 0.02f; float DistributionGGX(vec3 N, vec3 H, float a) @@ -123,53 +131,123 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) } -float ShadowCalculation(vec4 fragPosLightSpace, sampler2D shadowMap, vec3 normal, vec3 lightDir) +float ShadowCalculation(Light light, vec3 FragPos, vec3 normal) { + // Get Depth + float depth = length(FragPos - u_EyePosition); + int shadowmap = 0; + + // Get CSM depth + for (int i = 0; i < 4; i++) + { + float CSMDepth = light.CascadeDepth[i]; + + if (depth < CSMDepth + 0.0001) + { + shadowmap = i; + break; + } + } + + if (shadowmap == -1) + return 1.0; + + vec4 fragPosLightSpace = light.LightTransforms[0] * vec4(FragPos, 1.0f); + // perform perspective divide vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; // transform to [0,1] range projCoords = projCoords * 0.5 + 0.5; // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) - float closestDepth = texture(shadowMap, projCoords.xy).r; + float closestDepth = texture(light.ShadowMaps[0], projCoords.xy).r; // get depth of current fragment from light's perspective float currentDepth = projCoords.z; // check whether current frag pos is in shadow - float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); + float bias = max(0.005 * (1.0 - dot(normal, light.Direction)), 0.0005); float shadow = 0.0; - vec2 texelSize = 1.0 / textureSize(shadowMap, 0); - for (int x = -1; x <= 1; ++x) - { - for (int y = -1; y <= 1; ++y) - { - float pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r; - shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; - } - } - shadow /= 9.0; - return shadow; + + float pcfDepth = texture(light.ShadowMaps[0], projCoords.xy).r; + return currentDepth - bias > pcfDepth ? 1.0 : 0.0; } +// Mie scaterring approximated with Henyey-Greenstein phase function. +float ComputeScattering(float lightDotView) +{ + float result = 1.0f - u_FogAmount * u_FogAmount; + result /= (4.0f * PI * pow(1.0f + u_FogAmount * u_FogAmount - (2.0f * u_FogAmount) * lightDotView, 1.5f)); + return result; +} + + +vec3 ComputeVolumetric(vec3 FragPos, Light light) +{ + // world space frag position. + vec3 startPosition = u_EyePosition; // Camera Position + vec3 rayVector = FragPos - startPosition; // Ray Direction + + float rayLength = length(rayVector); // Length of the raymarched + + float stepLength = rayLength / u_FogStepCount; // Step length + vec3 rayDirection = rayVector / rayLength; + vec3 step = rayDirection * stepLength; // Normalized to step length direction + + vec3 currentPosition = startPosition; // First step position + vec3 accumFog = vec3(0.0f, 0.0f, 0.0f); // accumulative color + + // Raymarching + for (int i = 0; i < u_FogStepCount; i++) + { + vec4 fragPosLightSpace = light.LightTransforms[0] * vec4(currentPosition, 1.0f); + // perform perspective divide + vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; + // transform to [0,1] range + projCoords = projCoords * 0.5 + 0.5; + + float currentDepth = projCoords.z; + + // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) + vec2 texelSize = 1.0 / textureSize(light.ShadowMaps[0], 0); + + float closestDepth = texture(light.ShadowMaps[0], projCoords.xy).r; + + if (closestDepth > currentDepth) + accumFog += (ComputeScattering(dot(rayDirection, light.Direction)).xxx * light.Color); + + currentPosition += step; + } + accumFog /= u_FogStepCount; + + return accumFog; +} void main() { vec3 worldPos = WorldPosFromDepth(texture(m_Depth, UV).r); + if (texture(m_Depth, UV).r == 1) { + FragColor = vec4(0, 0, 0, 0); + return; + } + // Convert from [0, 1] to [-1, 1]. vec3 albedo = texture(m_Albedo, UV).rgb; - vec3 normal = (texture(m_Normal, UV).rgb - 0.5) * 2.0; + vec3 normal = texture(m_Normal, UV).rgb * 2.0 - 1.0; float metallic = texture(m_Material, UV).r; - float roughness = texture(m_Material, UV).g; - float ao = texture(m_Material, UV).b; + float roughness = texture(m_Material, UV).b; + float ao = texture(m_Material, UV).g; - vec3 N = normalize(normal); + vec3 N = normal; vec3 V = normalize(u_EyePosition - worldPos); vec3 R = reflect(-V, N); vec3 F0 = vec3(0.04); - F0 = mix(F0, albedo, vec3(metallic)); + F0 = mix(F0, albedo, metallic); // reflectance equation vec3 Lo = vec3(0.0); + vec3 fog = vec3(0.0); + float shadow = 0.0f; + vec3 eyeDirection = normalize(u_EyePosition - worldPos); for (int i = 0; i < LightCount; i++) @@ -180,11 +258,14 @@ void main() float attenuation = 1.0 / (distance * distance); if (Lights[i].Type == 0) { - L = Lights[i].Direction; + L = normalize(Lights[i].Direction); attenuation = 1.0f; - } - float shadow = ShadowCalculation(Lights[i].LightTransform * vec4(worldPos, 1.0f), Lights[i].ShadowMap, N, Lights[i].Direction); + if (Lights[i].Volumetric == 1) + fog += ComputeVolumetric(worldPos, Lights[i]); + + shadow = ShadowCalculation(Lights[i], worldPos, N); + } vec3 H = normalize(V + L); vec3 radiance = Lights[i].Color * attenuation * (1.0f - shadow); @@ -200,22 +281,13 @@ void main() // kS is equal to Fresnel vec3 kS = F; - // for energy conservation, the diffuse and specular light can't - // be above 1.0 (unless the surface emits light); to preserve this - // relationship the diffuse component (kD) should equal 1.0 - kS. vec3 kD = vec3(1.0) - kS; - // multiply kD by the inverse metalness such that only non-metals - // have diffuse lighting, or a linear blend if partly metal (pure metals - // have no diffuse light). kD *= 1.0 - metallic; // scale light by NdotL float NdotL = max(dot(N, L), 0.0); - - // add to outgoing radiance Lo Lo += (kD * albedo / PI + specular) * radiance * NdotL;// note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again } - /// ambient lighting (we now use IBL as the ambient term) vec3 F = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness); @@ -224,7 +296,7 @@ void main() vec3 kD = 1.0 - kS; kD *= 1.0 - metallic; - vec3 irradiance = texture(u_IrradianceMap, N).rgb; + vec3 irradiance = mix(texture(u_IrradianceMap, N).rgb, vec3(0.1f), 0.9f); vec3 diffuse = irradiance * albedo; // sample both the pre-filter map and the BRDF lut and combine them together as per the Split-Sum approximation to get the IBL specular part. @@ -235,11 +307,13 @@ void main() vec3 ambient = (kD * diffuse + specular) * ao; vec3 color = ambient + Lo; - - // HDR tonemapping + color += fog; color = color / (color + vec3(1.0)); + const float gamma = 2.2; + // HDR tonemapping + color = vec3(1.0) - exp(-color * u_Exposure); // gamma correct - color = pow(color, vec3(1.0 / u_Exposure)); + color = pow(color, vec3(1.0 / gamma)); - FragColor = vec4(color, 1.0); + FragColor = mix(vec4(color, 1.0), vec4(albedo, 1.0), 0); } \ No newline at end of file diff --git a/Editor/resources/Shaders/gbuffer.shader b/Editor/resources/Shaders/gbuffer.shader index f8a04be8..65611a64 100644 --- a/Editor/resources/Shaders/gbuffer.shader +++ b/Editor/resources/Shaders/gbuffer.shader @@ -67,17 +67,18 @@ void main() vec3 normal = vec3(0.5, 0.5, 1.0); if (u_HasNormal == 1) normal = texture(m_Normal, UV).rgb; - normal = normal * 2.0 - 1.0; - normal = TBN * normalize(normal); - gNormal = vec4(normal, 1.0); + + normal = TBN * normalize(normal); + + gNormal = vec4(normal, 1.0) / 2.0 + 0.5; // Albedo gAlbedo = vec4(m_AlbedoColor, 1.0); if (u_HasAlbedo == 1) - gAlbedo = texture(m_Albedo, UV).rgba; + gAlbedo.rgb = texture(m_Albedo, UV).rgb; - gAlbedo.rgba = texture(m_Albedo, UV).rgba; + gAlbedo.rgb = texture(m_Albedo, UV).rgb; // Material float finalMetalness = u_MetalnessValue; diff --git a/Editor/resources/Shaders/pbr.shader b/Editor/resources/Shaders/pbr.shader index 422fd570..caad26d2 100644 --- a/Editor/resources/Shaders/pbr.shader +++ b/Editor/resources/Shaders/pbr.shader @@ -373,7 +373,6 @@ void main() shadow += ShadowCalculation(Lights[i], v_FragPos, N); } - vec3 H = normalize(V + L); vec3 radiance = Lights[i].Color * attenuation * (1.0f - shadow); diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index 74f29360..6e86d196 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -131,6 +131,16 @@ namespace Nuake { if (m_IsEntitySelected) { + if (ImGui::Begin("DEFERRED")) + { + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + Ref texture = Engine::GetCurrentWindow()->GetDeferredBuffer()->GetTexture(GL_COLOR_ATTACHMENT0); + ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + + } + ImGui::End(); + if (ImGui::Begin("GBUFFER")) { ImVec2 regionAvail = ImGui::GetContentRegionAvail(); diff --git a/Nuake/src/Rendering/Buffers/RenderBuffer.h b/Nuake/src/Rendering/Buffers/RenderBuffer.h new file mode 100644 index 00000000..f7b37743 --- /dev/null +++ b/Nuake/src/Rendering/Buffers/RenderBuffer.h @@ -0,0 +1,19 @@ +#pragma once +#include "src/Core/Core.h" +#include "src/Core/Maths.h" + +namespace Nuake { + class RenderBuffer + { + public: + RenderBuffer(Vector2 size); + ~RenderBuffer(); + + void Bind(); + void Unbind(); + + unsigned int GetRenderID() const { return m_RenderBuffer; } + private: + unsigned int m_RenderBuffer; + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index 16298eb3..4df4ca44 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -51,12 +51,12 @@ namespace Nuake }; float QuadVertices[] = { - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; @@ -159,25 +159,41 @@ namespace Nuake m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric); } - void Renderer::RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam) + void Renderer::RegisterDeferredLight(TransformComponent transform, LightComponent light) { + if (m_Lights.size() == 20) + return; + + Ref deferredShader = ShaderManager::GetShader("resources/Shaders/deferred.shader"); + deferredShader->Bind(); m_Lights.push_back({ transform , light }); int idx = m_Lights.size(); Vector3 direction = light.GetDirection(); - Vector3 pos = transform.Translation; - Matrix4 lightView = glm::lookAt(pos, pos - direction, Vector3(0.0f, 1.0f, 0.0f)); + Vector3 pos = transform.GlobalTranslation; + Matrix4 lightView = glm::lookAt(pos, pos - direction, glm::vec3(0.0f, 1.0f, 0.0f)); - light.m_Framebuffer->GetTexture()->Bind(11); + //light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); - m_DeferredShader->SetUniform1i("LightCount", idx); - m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type); - m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMap", 11); - m_DeferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView); - m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.Translation.x, transform.Translation.y, transform.Translation.z); - m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z); - m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); + if (light.CastShadows) + { + for (unsigned int i = 0; i < CSM_AMOUNT; i++) + { + light.m_Framebuffers[i]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17 + i); + deferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[" + std::to_string(i) + "]", 17 + i); + deferredShader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[" + std::to_string(i) + "]", light.mCascadeSplitDepth[i]); + deferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[" + std::to_string(i) + "]", light.mViewProjections[i]); + } + } + + deferredShader->SetUniform1i("LightCount", idx); + deferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type); + deferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView); + deferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z); + deferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z); + deferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); + deferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric); } void Renderer::DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color) diff --git a/Nuake/src/Rendering/Renderer.h b/Nuake/src/Rendering/Renderer.h index 42d9144b..141ed60b 100644 --- a/Nuake/src/Rendering/Renderer.h +++ b/Nuake/src/Rendering/Renderer.h @@ -46,7 +46,7 @@ namespace Nuake // Lights static std::vector m_Lights; static void RegisterLight(TransformComponent transform, LightComponent light); - static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam); + static void RegisterDeferredLight(TransformComponent transform, LightComponent light); diff --git a/Nuake/src/Scene/Components/LightComponent.cpp b/Nuake/src/Scene/Components/LightComponent.cpp index 88f7c43b..e331fdea 100644 --- a/Nuake/src/Scene/Components/LightComponent.cpp +++ b/Nuake/src/Scene/Components/LightComponent.cpp @@ -93,11 +93,6 @@ namespace Nuake { Renderer::m_ShadowmapShader->Bind(); } - void LightComponent::DrawDeferred(TransformComponent transformComponent, Camera* cam) - { - Renderer::RegisterDeferredLight(transformComponent, *this, cam); - } - void LightComponent::DrawEditor() { ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Light properties"); ImGui::ColorEdit3("Light Color", &Color.r); diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 3f989a25..ae80f06b 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -363,7 +363,6 @@ namespace Nuake { } glCullFace(GL_BACK); Renderer::Flush(pbrShader); - glCullFace(GL_FRONT); auto quakeView = m_Registry.view(); for (auto e : quakeView) @@ -430,12 +429,20 @@ namespace Nuake { void Scene::EditorDrawDeferred() { glEnable(GL_DEPTH_TEST); - + Ref gBufferShader = ShaderManager::GetShader("resources/Shaders/gbuffer.shader"); gBufferShader->Bind(); gBufferShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); gBufferShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + auto view = m_Registry.view(); + for (auto e : view) + { + auto [transform, mesh, parent] = view.get(e); + for (auto& m : mesh.meshes) + Renderer::SubmitMesh(m, transform.GetTransform()); + } + auto quakeView = m_Registry.view(); for (auto e : quakeView) { @@ -447,10 +454,41 @@ namespace Nuake { for (auto& b : model.Meshes) Renderer::SubmitMesh(b, transform.GetTransform()); } - + glCullFace(GL_FRONT); Renderer::Flush(gBufferShader, false); } + void Scene::EditorDrawDeferredShading() + { + glDisable(GL_DEPTH_TEST); + + Ref deferredShader = ShaderManager::GetShader("resources/Shaders/deferred.shader"); + deferredShader->Bind(); + deferredShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + deferredShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + + deferredShader->SetUniform1f("u_Exposure", 1.0); + + Vector3 camPosition = m_EditorCamera->GetTranslation(); + deferredShader->SetUniform3f("u_EyePosition", camPosition.x, camPosition.y, camPosition.z); + + Ref env = GetEnvironment(); + deferredShader->SetUniform1f("u_FogAmount", env->VolumetricFog); + deferredShader->SetUniform1f("u_FogStepCount", env->VolumetricStepCount); + + // Register the lights + auto view = m_Registry.view(); + for (auto l : view) + { + auto [transform, light, parent] = view.get(l); + + if (light.SyncDirectionWithSky) + light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); + + Renderer::RegisterDeferredLight(transform, light); + } + } + std::vector Scene::GetAllEntities() { std::vector allEntities; diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index 8b5b9f9e..6dc06c58 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -58,6 +58,7 @@ namespace Nuake { void DrawInterface(Vector2 screensize); void Draw(); void EditorDrawDeferred(); + void EditorDrawDeferredShading(); void EditorDraw(); std::vector GetAllEntities(); diff --git a/Nuake/src/Window.cpp b/Nuake/src/Window.cpp index 20325d9b..9df1e33d 100644 --- a/Nuake/src/Window.cpp +++ b/Nuake/src/Window.cpp @@ -83,6 +83,11 @@ namespace Nuake { return m_GBuffer; } + Ref Window::GetDeferredBuffer() const + { + return m_DeferredBuffer; + } + Vector2 Window::GetSize() { int w, h = 0; @@ -146,6 +151,9 @@ namespace Nuake { m_GBuffer->SetTexture(CreateRef(Vector2(1920, 1080), GL_RGB), GL_COLOR_ATTACHMENT1); m_GBuffer->SetTexture(CreateRef(Vector2(1920, 1080), GL_RGB), GL_COLOR_ATTACHMENT2); + m_DeferredBuffer = CreateRef(true, Vector2(1920, 1080)); + m_DeferredBuffer->SetTexture(CreateRef(Vector2(1920, 1080), GL_RGB)); + // Temporary quad vbo for deferred. glGenVertexArrays(1, &vao); glBindVertexArray(vao); @@ -262,8 +270,8 @@ namespace Nuake { { if (Engine::IsPlayMode) m_Scene->Draw(); - else - m_Scene->EditorDraw(); + //else + // m_Scene->EditorDraw(); m_Scene->DrawInterface(m_Framebuffer->GetSize()); } @@ -277,6 +285,31 @@ namespace Nuake { m_GBuffer->Unbind(); + m_DeferredBuffer->Bind(); + m_DeferredBuffer->Clear(); + { + glDisable(GL_CULL_FACE); + if (m_Scene->GetEnvironment()->ProceduralSkybox) + m_Scene->GetEnvironment()->ProceduralSkybox->Draw(m_Scene->m_EditorCamera); + + m_Scene->EditorDrawDeferredShading(); + + m_GBuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5); + m_GBuffer->GetTexture(GL_COLOR_ATTACHMENT0)->Bind(6); + m_GBuffer->GetTexture(GL_COLOR_ATTACHMENT1)->Bind(7); + m_GBuffer->GetTexture(GL_COLOR_ATTACHMENT2)->Bind(8); + + Ref deferredShader = ShaderManager::GetShader("resources/Shaders/deferred.shader"); + deferredShader->SetUniform1i("m_Depth", 5); + deferredShader->SetUniform1i("m_Albedo", 6); + deferredShader->SetUniform1i("m_Normal", 7); + deferredShader->SetUniform1i("m_Material", 8); + + Renderer::DrawQuad(Matrix4()); + + + } + m_DeferredBuffer->Unbind(); Renderer::EndDraw(); } diff --git a/Nuake/src/Window.h b/Nuake/src/Window.h index f834bae2..bd12e517 100644 --- a/Nuake/src/Window.h +++ b/Nuake/src/Window.h @@ -20,6 +20,7 @@ namespace Nuake Ref m_Framebuffer; Ref m_GBuffer; + Ref m_DeferredBuffer; Ref m_Scene; Vector2 m_FramebufferOffset; @@ -41,7 +42,7 @@ namespace Nuake Ref GetFrameBuffer() const; Ref GetGBuffer() const; - + Ref GetDeferredBuffer() const; Vector2 GetSize(); Ref GetScene();