Skip to content

Commit

Permalink
EDAN35/Lab2: Improvements for 2020
Browse files Browse the repository at this point in the history
  • Loading branch information
pierremoreau committed Aug 24, 2020
1 parent 4ba00c3 commit d9706e5
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 24 deletions.
15 changes: 11 additions & 4 deletions shaders/EDAN35/fill_gbuffer.frag
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#version 410

uniform bool has_diffuse_texture;
uniform bool has_specular_texture;
uniform bool has_normals_texture;
uniform bool has_opacity_texture;
uniform sampler2D diffuse_texture;
uniform sampler2D specular_texture;
uniform sampler2D normals_texture;
uniform sampler2D opacity_texture;
uniform bool has_opacity_texture;
uniform mat4 normal_model_to_world;

in VS_OUT {
Expand All @@ -25,11 +28,15 @@ void main()
discard;

// Diffuse color
geometry_diffuse = texture(diffuse_texture, fs_in.texcoord);
geometry_diffuse = vec4(0.0f);
if (has_diffuse_texture)
geometry_diffuse = texture(diffuse_texture, fs_in.texcoord);

// Specular color
geometry_specular = texture(specular_texture, fs_in.texcoord);
geometry_specular = vec4(0.0f);
if (has_specular_texture)
geometry_specular = texture(specular_texture, fs_in.texcoord);

// Worldspace normal
geometry_normal.xyz = vec3(0.0, 0.0, 0.0);
geometry_normal.xyz = vec3(0.0);
}
3 changes: 0 additions & 3 deletions shaders/EDAN35/fill_shadowmap.frag
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#version 410

out vec4 frag_color;

void main()
{
frag_color = vec4(1.0, 0.0, 0.0, 1.0);
}
8 changes: 8 additions & 0 deletions shaders/EDAN35/render_light_cones.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 410

out vec3 frag_color;

void main()
{
frag_color = vec3(1.0f, 0.0f, 0.0f);
}
11 changes: 11 additions & 0 deletions shaders/EDAN35/render_light_cones.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version 410

uniform mat4 vertex_model_to_world;
uniform mat4 vertex_world_to_clip;

layout (location = 0) in vec3 vertex;

void main()
{
gl_Position = vertex_world_to_clip * vertex_model_to_world * vec4(vertex, 1.0);
}
86 changes: 69 additions & 17 deletions src/EDAN35/assignment2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "core/GLStateInspectionView.h"
#include "core/helpers.hpp"
#include "core/node.hpp"
#include "core/opengl.hpp"
#include "core/ShaderProgramManager.hpp"

#include <imgui.h>
Expand All @@ -28,18 +29,19 @@ namespace constant
constexpr uint32_t shadowmap_res_x = 1024;
constexpr uint32_t shadowmap_res_y = 1024;

constexpr float scale_lengths = 100.0f; // The scene is expressed in centimetres rather than metres, hence the x100.

constexpr size_t lights_nb = 4;
constexpr float light_intensity = 720000.0f;
constexpr float light_intensity = 72.0f * (scale_lengths * scale_lengths);
constexpr float light_angle_falloff = glm::radians(37.0f);
constexpr float light_cutoff = 0.05f;
}

static bonobo::mesh_data loadCone();

edan35::Assignment2::Assignment2(WindowManager& windowManager) :
mCamera(0.5f * glm::half_pi<float>(),
static_cast<float>(config::resolution_x) / static_cast<float>(config::resolution_y),
0.1f, 10000.0f),
0.01f * constant::scale_lengths, 30.0f * constant::scale_lengths),
inputHandler(), mWindowManager(windowManager), window(nullptr)
{
WindowManager::WindowDatum window_datum{ inputHandler, mCamera, config::resolution_x, config::resolution_y, 0, 0, 0, 0};
Expand Down Expand Up @@ -67,7 +69,7 @@ void
edan35::Assignment2::run()
{
// Load the geometry of Sponza
auto const sponza_geometry = bonobo::loadObjects(config::resources_path("crysponza/sponza.obj"));
auto const sponza_geometry = bonobo::loadObjects(config::resources_path("sponza/sponza.obj"));
if (sponza_geometry.empty()) {
LogError("Failed to load the Sponza model");
return;
Expand All @@ -87,9 +89,9 @@ edan35::Assignment2::run()
//
// Setup the camera
//
mCamera.mWorld.SetTranslate(glm::vec3(0.0f, 1.0f, 1.8f) * 100.0f); // the scene is expressed in centimetres rather than metres, hence the x100.
mCamera.mWorld.SetTranslate(glm::vec3(0.0f, 1.0f, 1.8f) * constant::scale_lengths);
mCamera.mMouseSensitivity = 0.003f;
mCamera.mMovementSpeed = 3.0f * 100.0f; // 3 m/s => 10.8 km/h; the scene is expressed in centimetres rather than metres, hence the x100.
mCamera.mMovementSpeed = 3.0f * constant::scale_lengths; // 3 m/s => 10.8 km/h.

//
// Load all the shader programs used
Expand Down Expand Up @@ -145,6 +147,16 @@ edan35::Assignment2::run()
return;
}

GLuint render_light_cones_shader = 0u;
program_manager.CreateAndRegisterProgram("Render light cones",
{ { ShaderType::vertex, "EDAN35/render_light_cones.vert" },
{ ShaderType::fragment, "EDAN35/render_light_cones.frag" } },
render_light_cones_shader);
if (render_light_cones_shader == 0u) {
LogError("Failed to load light cones rendering shader");
return;
}

auto const set_uniforms = [](GLuint /*program*/){};

int framebuffer_width, framebuffer_height;
Expand Down Expand Up @@ -211,26 +223,30 @@ edan35::Assignment2::run()
bool are_lights_paused = false;

for (size_t i = 0; i < static_cast<size_t>(lights_nb); ++i) {
lightTransforms[i].SetTranslate(glm::vec3(0.0f, 125.0f, 0.0f));
lightTransforms[i].SetTranslate(glm::vec3(0.0f, 1.25f, 0.0f) * constant::scale_lengths);
lightColors[i] = glm::vec3(0.5f + 0.5f * (static_cast<float>(rand()) / static_cast<float>(RAND_MAX)),
0.5f + 0.5f * (static_cast<float>(rand()) / static_cast<float>(RAND_MAX)),
0.5f + 0.5f * (static_cast<float>(rand()) / static_cast<float>(RAND_MAX)));
}

float const lightProjectionNearPlane = 0.01f * constant::scale_lengths;
float const lightProjectionFarPlane = 20.0f * constant::scale_lengths;
auto lightProjection = glm::perspective(0.5f * glm::pi<float>(),
static_cast<float>(constant::shadowmap_res_x) / static_cast<float>(constant::shadowmap_res_y),
lightProjectionNearPlane, lightProjectionFarPlane);

TRSTransformf coneScaleTransform;
coneScaleTransform.SetScale(glm::vec3(std::sqrt(constant::light_intensity / constant::light_cutoff)));
coneScaleTransform.SetScale(glm::vec3(lightProjectionFarPlane * 0.8f));

TRSTransformf lightOffsetTransform;
lightOffsetTransform.SetTranslate(glm::vec3(0.0f, 0.0f, -40.0f));

auto lightProjection = glm::perspective(0.5f * glm::pi<float>(),
static_cast<float>(constant::shadowmap_res_x) / static_cast<float>(constant::shadowmap_res_y),
1.0f, 10000.0f);
lightOffsetTransform.SetTranslate(glm::vec3(0.0f, 0.0f, -0.4f) * constant::scale_lengths);


auto seconds_nb = 0.0f;


glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

Expand Down Expand Up @@ -278,6 +294,11 @@ edan35::Assignment2::run()
//
// Pass 1: Render scene into the g-buffer
//
if (utils::opengl::debug::isSupported())
{
std::string const group_name = "Fill G-buffer";
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0u, group_name.size(), group_name.data());
}
glBindFramebuffer(GL_FRAMEBUFFER, deferred_fbo);
GLenum const deferred_draw_buffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, deferred_draw_buffers);
Expand All @@ -294,6 +315,10 @@ edan35::Assignment2::run()

for (auto const& element : sponza_elements)
element.render(mCamera.GetWorldToClipMatrix(), element.get_transform().GetMatrix(), fill_gbuffer_shader, set_uniforms);
if (utils::opengl::debug::isSupported())
{
glPopDebugGroup();
}



Expand All @@ -315,14 +340,23 @@ edan35::Assignment2::run()
//
// Pass 2.1: Generate shadow map for light i
//
if (utils::opengl::debug::isSupported())
{
std::string const group_name = "Create shadow map " + std::to_string(i);
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0u, group_name.size(), group_name.data());
}
glBindFramebuffer(GL_FRAMEBUFFER, shadowmap_fbo);
glViewport(0, 0, constant::shadowmap_res_x, constant::shadowmap_res_y);
// XXX: Is any clearing needed?

GLStateInspection::CaptureSnapshot("Shadow Map Generation");

for (auto const& element : sponza_elements)
element.render(light_matrix, glm::mat4(1.0f), fill_gbuffer_shader, set_uniforms);
element.render(light_matrix, glm::mat4(1.0f), fill_shadowmap_shader, set_uniforms);
if (utils::opengl::debug::isSupported())
{
glPopDebugGroup();
}


glEnable(GL_BLEND);
Expand All @@ -332,6 +366,11 @@ edan35::Assignment2::run()
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
//
// Pass 2.2: Accumulate light i contribution
if (utils::opengl::debug::isSupported())
{
std::string const group_name = "Accumulate light " + std::to_string(i);
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0u, group_name.size(), group_name.data());
}
glBindFramebuffer(GL_FRAMEBUFFER, light_fbo);
glDrawBuffers(2, light_draw_buffers);
glUseProgram(accumulate_lights_shader);
Expand Down Expand Up @@ -375,6 +414,10 @@ edan35::Assignment2::run()
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
glDisable(GL_BLEND);
if (utils::opengl::debug::isSupported())
{
glPopDebugGroup();
}
}


Expand All @@ -383,6 +426,11 @@ edan35::Assignment2::run()
//
// Pass 3: Compute final image using both the g-buffer and the light accumulation buffer
//
if (utils::opengl::debug::isSupported())
{
std::string const group_name = "Resolve";
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0u, group_name.size(), group_name.data());
}
glBindFramebuffer(GL_FRAMEBUFFER, 0u);
glUseProgram(resolve_deferred_shader);
glViewport(0, 0, framebuffer_width, framebuffer_height);
Expand All @@ -402,6 +450,10 @@ edan35::Assignment2::run()
glBindSampler(1, 0u);
glBindSampler(0, 0u);
glUseProgram(0u);
if (utils::opengl::debug::isSupported())
{
glPopDebugGroup();
}
}


Expand All @@ -413,7 +465,7 @@ edan35::Assignment2::run()
for (size_t i = 0; i < lights_nb; ++i) {
cone.render(mCamera.GetWorldToClipMatrix(),
lightTransforms[i].GetMatrix() * lightOffsetTransform.GetMatrix() * coneScaleTransform.GetMatrix(),
fill_shadowmap_shader, set_uniforms);
render_light_cones_shader, set_uniforms);
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
Expand All @@ -426,8 +478,8 @@ edan35::Assignment2::run()
bonobo::displayTexture({-0.95f, -0.95f}, {-0.55f, -0.55f}, diffuse_texture, default_sampler, {0, 1, 2, -1}, glm::uvec2(framebuffer_width, framebuffer_height));
bonobo::displayTexture({-0.45f, -0.95f}, {-0.05f, -0.55f}, specular_texture, default_sampler, {0, 1, 2, -1}, glm::uvec2(framebuffer_width, framebuffer_height));
bonobo::displayTexture({ 0.05f, -0.95f}, { 0.45f, -0.55f}, normal_texture, default_sampler, {0, 1, 2, -1}, glm::uvec2(framebuffer_width, framebuffer_height));
bonobo::displayTexture({ 0.55f, -0.95f}, { 0.95f, -0.55f}, depth_texture, default_sampler, {0, 0, 0, -1}, glm::uvec2(framebuffer_width, framebuffer_height), &mCamera);
bonobo::displayTexture({-0.95f, 0.55f}, {-0.55f, 0.95f}, shadowmap_texture, default_sampler, {0, 0, 0, -1}, glm::uvec2(framebuffer_width, framebuffer_height), &mCamera);
bonobo::displayTexture({ 0.55f, -0.95f}, { 0.95f, -0.55f}, depth_texture, default_sampler, {0, 0, 0, -1}, glm::uvec2(framebuffer_width, framebuffer_height), true, mCamera.mNear, mCamera.mFar);
bonobo::displayTexture({-0.95f, 0.55f}, {-0.55f, 0.95f}, shadowmap_texture, default_sampler, {0, 0, 0, -1}, glm::uvec2(framebuffer_width, framebuffer_height), true, lightProjectionNearPlane, lightProjectionFarPlane);
bonobo::displayTexture({-0.45f, 0.55f}, {-0.05f, 0.95f}, light_diffuse_contribution_texture, default_sampler, {0, 1, 2, -1}, glm::uvec2(framebuffer_width, framebuffer_height));
bonobo::displayTexture({ 0.05f, 0.55f}, { 0.45f, 0.95f}, light_specular_contribution_texture, default_sampler, {0, 1, 2, -1}, glm::uvec2(framebuffer_width, framebuffer_height));
}
Expand Down

0 comments on commit d9706e5

Please sign in to comment.