mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-15 20:08:54 +03:00
Fixed shading in deferred.
Added sky in deferred. Started render buffer abstraction
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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> 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();
|
||||
|
||||
19
Nuake/src/Rendering/Buffers/RenderBuffer.h
Normal file
19
Nuake/src/Rendering/Buffers/RenderBuffer.h
Normal file
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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<Shader> 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)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Nuake
|
||||
// Lights
|
||||
static std::vector<Light> 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);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -363,7 +363,6 @@ namespace Nuake {
|
||||
}
|
||||
glCullFace(GL_BACK);
|
||||
Renderer::Flush(pbrShader);
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
auto quakeView = m_Registry.view<TransformComponent, BSPBrushComponent, ParentComponent>();
|
||||
for (auto e : quakeView)
|
||||
@@ -430,12 +429,20 @@ namespace Nuake {
|
||||
void Scene::EditorDrawDeferred()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
||||
Ref<Shader> 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<TransformComponent, MeshComponent, ParentComponent>();
|
||||
for (auto e : view)
|
||||
{
|
||||
auto [transform, mesh, parent] = view.get<TransformComponent, MeshComponent, ParentComponent>(e);
|
||||
for (auto& m : mesh.meshes)
|
||||
Renderer::SubmitMesh(m, transform.GetTransform());
|
||||
}
|
||||
|
||||
auto quakeView = m_Registry.view<TransformComponent, BSPBrushComponent, ParentComponent>();
|
||||
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<Shader> 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<Environment> env = GetEnvironment();
|
||||
deferredShader->SetUniform1f("u_FogAmount", env->VolumetricFog);
|
||||
deferredShader->SetUniform1f("u_FogStepCount", env->VolumetricStepCount);
|
||||
|
||||
// Register the lights
|
||||
auto view = m_Registry.view<TransformComponent, LightComponent, ParentComponent>();
|
||||
for (auto l : view)
|
||||
{
|
||||
auto [transform, light, parent] = view.get<TransformComponent, LightComponent, ParentComponent>(l);
|
||||
|
||||
if (light.SyncDirectionWithSky)
|
||||
light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection();
|
||||
|
||||
Renderer::RegisterDeferredLight(transform, light);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Entity> Scene::GetAllEntities()
|
||||
{
|
||||
std::vector<Entity> allEntities;
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace Nuake {
|
||||
void DrawInterface(Vector2 screensize);
|
||||
void Draw();
|
||||
void EditorDrawDeferred();
|
||||
void EditorDrawDeferredShading();
|
||||
void EditorDraw();
|
||||
|
||||
std::vector<Entity> GetAllEntities();
|
||||
|
||||
@@ -83,6 +83,11 @@ namespace Nuake {
|
||||
return m_GBuffer;
|
||||
}
|
||||
|
||||
Ref<FrameBuffer> Window::GetDeferredBuffer() const
|
||||
{
|
||||
return m_DeferredBuffer;
|
||||
}
|
||||
|
||||
Vector2 Window::GetSize()
|
||||
{
|
||||
int w, h = 0;
|
||||
@@ -146,6 +151,9 @@ namespace Nuake {
|
||||
m_GBuffer->SetTexture(CreateRef<Texture>(Vector2(1920, 1080), GL_RGB), GL_COLOR_ATTACHMENT1);
|
||||
m_GBuffer->SetTexture(CreateRef<Texture>(Vector2(1920, 1080), GL_RGB), GL_COLOR_ATTACHMENT2);
|
||||
|
||||
m_DeferredBuffer = CreateRef<FrameBuffer>(true, Vector2(1920, 1080));
|
||||
m_DeferredBuffer->SetTexture(CreateRef<Texture>(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<Shader> 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();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Nuake
|
||||
|
||||
Ref<FrameBuffer> m_Framebuffer;
|
||||
Ref<FrameBuffer> m_GBuffer;
|
||||
Ref<FrameBuffer> m_DeferredBuffer;
|
||||
|
||||
Ref<Scene> m_Scene;
|
||||
Vector2 m_FramebufferOffset;
|
||||
@@ -41,7 +42,7 @@ namespace Nuake
|
||||
|
||||
Ref<FrameBuffer> GetFrameBuffer() const;
|
||||
Ref<FrameBuffer> GetGBuffer() const;
|
||||
|
||||
Ref<FrameBuffer> GetDeferredBuffer() const;
|
||||
Vector2 GetSize();
|
||||
|
||||
Ref<Scene> GetScene();
|
||||
|
||||
Reference in New Issue
Block a user