Commit 3806db9e authored by Johannes Braun's avatar Johannes Braun
Browse files

Removed camera resizing for explicit camera resolutions (e.g. Shadow Maps)

parent d110615e
......@@ -46,12 +46,23 @@ STD_BUFFER_R lightsBuffer
LightWithShadowmap b_lights[];
};
const vec2 poissonDisk[5] = vec2[](
vec2(0),
vec2(-0.94201624, -0.39906216),
vec2(0.94558609, -0.76890725),
vec2(-0.094184101, -0.92938870),
vec2(0.34495938, 0.29387760)
const vec2 poissonDisk[16] = vec2[](
vec2(0.1505688f, 0.9006551f),
vec2(-0.01351117f, 0.3535984f),
vec2(0.4001779f, 0.5178972f),
vec2(-0.440886f, 0.4302851f),
vec2(-0.4160731f, 0.8641366f),
vec2(0.9662936f, 0.02506917f),
vec2(0.4277292f, -0.007689635f),
vec2(0.794787f, 0.5989406f),
vec2(-0.7394559f, -0.1354285f),
vec2(-0.6448742f, -0.7343334f),
vec2(-0.2089914f, -0.6586035f),
vec2(-0.3510948f, 0.04614406f),
vec2(0.3864633f, -0.696366f),
vec2(0.6720468f, -0.3266357f),
vec2(-0.8208213f, 0.4652553f),
vec2(0.111697f, -0.2986286f)
);
float calculateShadowMapDarkening(const in vec3 position, const in vec3 to_light, const in vec3 normal, const in vec3 camera, const in LightWithShadowmap light) {
......@@ -62,11 +73,11 @@ float calculateShadowMapDarkening(const in vec3 position, const in vec3 to_light
vec3 shadow_coord_normalized = shadow_coord.xyz / shadow_coord.w; // normalized device coordinates, light space
//shadow_coord_normalized.xy = clamp(shadow_coord_normalized.xy, 0, 1);
float dst = pow(clamp(distance(camera, position.xyz) / 250.f, 0, 1), 3);
float dst = pow(clamp(distance(camera, position.xyz) / 175.f, 0, 1), 3);
float cos_theta = dot(normal.xyz, to_light);
if (dst==0 || !(shadow_coord_normalized.x <= 1.f && shadow_coord_normalized.x > 0.f && shadow_coord_normalized.y <= 1.f && shadow_coord_normalized.y > 0.f)) {
return max(cos_theta, 0);
return 1;
}
float bias = 0.005 * tan(acos(cos_theta));
......@@ -74,15 +85,15 @@ float calculateShadowMapDarkening(const in vec3 position, const in vec3 to_light
const vec2 size = vec2(light.shadow_map.map.textureSize(0));
const int num_samples = 5;
const int num_samples = 16;
float shadow_value = 0.f;
for (int i = 0; i<num_samples; i++) {
shadow_value += texture(light.shadow_map.map, vec3(shadow_coord_normalized.xy + (poissonDisk[i] / size.x), shadow_coord_normalized.z - bias));
shadow_value += texture(light.shadow_map.map, vec3(shadow_coord_normalized.xy + (3*poissonDisk[i] / size.x), shadow_coord_normalized.z - bias));
}
shadow_value /= num_samples;
darkening = mix(shadow_value * max(cos_theta, 0), max(cos_theta, 0), dst);
darkening = mix(shadow_value, 1, dst);
}
return darkening;
......
#include "game.h"
#include <array>
#include <util/files.h>
#include <pugixml/pugixml.hpp>
#include <core/res/resources.h>
#include "src/map.h"
Game::Game()
{
}
Game::~Game()
{
}
int mode = 0;
void Game::onKeyDown(controls::Key key, controls::KeyMods mods)
{
switch (key)
{
case controls::Key::e0:
//core::state::camera->setProjection(core::Camera::Projection::eOrthographic);
mode = 0;
break;
case controls::Key::e1:
mode = 1;
//core::state::camera->setProjection(core::Camera::Projection::ePerspective);
break;
case controls::Key::e2:
mode = 2;
//core::state::camera->setProjection(core::Camera::Projection::ePerspective);
break;
default:
break;
}
}
void Game::initialize()
{
pugi::xml_document preferences_file;
preferences_file.load_file(files::asset("/preferences/default.xml").c_str());
// BASIC CONFIG
const auto config_child = preferences_file.child("settings").find_child_by_attribute("group", "name", "config");
m_config.window_width = config_child.find_child_by_attribute("item", "name", "window_size_x").attribute("value").as_uint(1280);
m_config.window_height = config_child.find_child_by_attribute("item", "name", "window_size_y").attribute("value").as_uint(720);
m_config.window_title = config_child.find_child_by_attribute("item", "name", "window_title").attribute("value").as_string("GLARE");
m_config.vsync = VSync(config_child.find_child_by_attribute("item", "name", "vsync").attribute("value").as_uint(0));
m_config.sample_count = config_child.find_child_by_attribute("item", "name", "msaa").attribute("value").as_uint(4);
core::state::initialize(m_config.window_width, m_config.window_height, m_config.window_title);
m_skybox = std::make_shared<core::Skybox>(core::Skybox::collectFilesFrom(files::asset("/textures/ryfjallet/")));
std::vector<float> bla(2);
ImGui::glfw3::init(core::state::window->glfw(), false);
gl::setEnabled(gl::EnableParameter::eMultisample, true);
m_gbuffer = std::make_unique<core::GBuffer>(m_config.window_width, m_config.window_height, m_config.sample_count);
m_gbuffer->setSkybox(m_skybox);
core::state::window->setVSync(VSync::eOff);
core::Callbacks::addKeyDownCallback("main_application", std::bind(&Game::onKeyDown, this, std::placeholders::_1, std::placeholders::_2));
// Make Camera
auto cam_node = std::make_shared<core::GraphNode>("custom_camera");
cam_node->addComponent(core::state::camera);
cam_node->makeComponent<component::PlayerController>();
cam_node->makeComponent<component::FramerateCounter>();
//Ambient Light
auto ambient_node = std::make_shared<core::GraphNode>("light_ambient");
ambient_node->makeComponent<core::LightComponent>(color::rgba32f{ 0.02f, 0.07f, 0.3f, 1.f }, core::Attenuation{ 1,0,0 }, core::LightParameters::makeAmbientLight());
//Sun with ShadowMap
auto sun_node = std::make_shared<core::GraphNode>("light_sun");
auto light_sun = sun_node->makeComponent<core::LightComponent>(color::rgba32f{ 3.4f, 2.21f, 2.13f, 1.f }, core::Attenuation{ 1,0,0 }, core::LightParameters::makeDirectionalLight());
// Attach a shadow map renderer to the sun node.
//core::ShadowMapRenderer shadow_map_renderer(1024, 64, 4, sun_node);
// Make Environment lighting
auto environment_node = std::make_shared<core::GraphNode>("environment");
environment_node->attach(ambient_node);
environment_node->attach(sun_node);
// Make the terrain
game::Map map(files::asset("/maps/test01/map.xml"));
auto terrain_node = std::make_shared<core::GraphNode>("terrain");
terrain_node->addComponent(map.getMesh());
//Initialize root node
core::state::graph_root->attach(environment_node);
core::state::graph_root->attach(terrain_node);
core::state::graph_root->attach(cam_node);
//Attach plane as child in front of the camera.
auto plane = core::Resources::getInstance().getColladaMesh(files::asset("meshes/scenery/TY_Plane.dae"), "Cube_001");
cam_node->attach(plane);
plane->transform()->position = { 0, -2.f, -15 };
plane->transform()->rotate({ glm::radians(-90.f), glm::radians(90.f), 0.f });
auto texrend = core::DefaultTextureRenderers::makeSimpleRenderer();
sun_node->transform()->rotate({ glm::radians(50.f), 0, 0 });
glare::core::state::window->loop([&](double delta)
{
// General state updates (camera and so on)
ImGui::glfw3::newFrame();
glare::core::state::update();
//Simulate a sun for a day and night cycle.
if (controls::keyState(controls::Key::eF) == controls::ButtonAction::ePress) {
sun_node->transform()->rotate({ glm::radians(80.f)*core::Time::deltaTime(), 0, 0 });
}
/*else {
sun_node->transform()->rotate({ glm::radians(0.f)*core::Time::deltaTime(), 0, 0 });
}*/
//Build shadow map after setting the environment node position to the current camera one's as the shadow will be local.
environment_node->transform()->position = core::state::camera->getOwner()->transform()->position;
//shadow_map_renderer.build(glare::core::state::graph_root);
switch (mode) {
case 0: {
//Record and render gbuffer
m_gbuffer->activate();
m_skybox->draw();
glare::core::state::graph_root->draw();
m_gbuffer->deactivate();
m_gbuffer->draw();
} break;
case 1: {
gl::viewport(0, 0, 1024, 1024);
texrend->draw(light_sun->shadowMapRenderer().framebuffer().colorAttachment(gl::Attachment::eColor0));
gl::viewport(0, 0, unsigned(core::state::camera->getWidth()),
unsigned(core::state::camera->getWidth() / core::state::camera->getAspectRatio()));
} break;
case 2: {
gl::viewport(0, 0, 1024, 1024);
texrend->draw(light_sun->shadowMapRenderer().framebuffer().depthAttachment());
gl::viewport(0, 0, unsigned(core::state::camera->getWidth()),
unsigned(core::state::camera->getWidth() / core::state::camera->getAspectRatio()));
} break;
}
ImGui::Render();
core::LightManager::getInstance().clear();
});
}
\ No newline at end of file
#ifndef __GAME_H
#define __GAME_H
#include <glare_core>
#include <glare_gui>
#include <util/singleton.h>
//Components
#include <components/PlayerController.h>
#include <components/FramerateCounter.h>
using namespace glare;
namespace fs = std::experimental::filesystem;
class Game : public Singleton<Game>
{
public:
Game();
~Game();
void initialize();
private:
void onKeyDown(controls::Key key, controls::KeyMods mods);
struct
{
VSync vsync;
unsigned window_width;
unsigned window_height;
unsigned sample_count;
std::string window_title;
} m_config;
fs::path m_current_scene_root;
std::shared_ptr<core::Skybox> m_skybox;
std::unique_ptr<core::GBuffer> m_gbuffer;
};
#endif //__GAME_H
\ No newline at end of file
#include "game.h"
#include <util/files.h>
#include <core/state.h>
#include <core/rendering/gbuffer.h>
#include <core/objects/skybox.h>
#include <core/objects/light.h>
#include <core/res/resources.h>
#include <components/PlayerController.h>
#include <components/FramerateCounter.h>
#include "src/map.h"
using namespace glare;
const fs::path engine_settings_path = files::asset("/preferences/default.xml");
const fs::path skybox_files_path = files::asset("/textures/ryfjallet/");
int main(int argc, char* argv[])
{
Game::getInstance().initialize();
{
core::state::initialize(engine_settings_path);
core::state::skybox->reset(core::Skybox::collectFilesFrom(skybox_files_path));
// Load the map
game::Map map(files::asset("/maps/test01/map.xml"));
// Build node tree
{
// custom camera
auto cam_node = std::make_shared<core::GraphNode>("custom_camera");
cam_node->addComponent(core::state::camera);
cam_node->makeComponent<component::PlayerController>();
cam_node->makeComponent<component::FramerateCounter>();
//Attach plane as child in front of the camera.
auto plane = core::Resources::getInstance().getColladaMesh(files::asset("meshes/scenery/TY_Plane.dae"), "Cube_001");
cam_node->attach(plane);
plane->transform()->position = { 0, -2.f, -15 };
plane->transform()->rotate({ glm::radians(-90.f), glm::radians(90.f), 0.f });
// add the terrain
auto terrain_node = std::make_shared<core::GraphNode>("terrain");
terrain_node->addComponent(map.getMesh());
//Initialize root node
core::state::graph_root->attach(terrain_node);
core::state::graph_root->attach(cam_node);
}
// Sun light source
auto sun_node = std::make_shared<core::GraphNode>("light_sun");
sun_node->transform()->rotate({ glm::radians(80.f), 0, 0 });
auto light_sun = sun_node->makeComponent<core::LightComponent>(color::rgba32f{ 0.4f, 0.4f, 0.4f, 1.f }, core::Attenuation{ 1,0,0 }, core::LightParameters::makeDirectionalLight());
// Make Environment lighting node
auto lighting_node = std::make_shared<core::GraphNode>("environment");
lighting_node->attach(sun_node);
core::state::graph_root->attach(lighting_node);
// Start it up!
glare::core::state::mainLoop([&](double delta)
{
// Rotate the sun on keypress
if (controls::keyState(controls::Key::eF) == controls::ButtonAction::ePress) {
sun_node->transform()->rotate({ glm::radians(80.f)*delta, 0, 0 });
}
// Set the light position to the player camera position
lighting_node->transform()->position = core::state::camera->getOwner()->c_transform().position * glm::vec3(1, 0, 1);
core::state::gbuffer->activate();
glare::core::state::graph_root->draw();
core::state::gbuffer->draw();
});
return 0;
}
......@@ -256,10 +256,10 @@ namespace glare
material->color_diffuse = color::preset::white.rgb;
material->color_specular = 2 * color::preset::white.rgb;
material->specular_exponent = 80;
//material->map_diffuse = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048.png"));
//material->map_normal = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048_n.png"));
//material->map_displacement = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048_h.png"));
//material->map_specular = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048_s.png"));
material->map_diffuse = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048.png"));
material->map_normal = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048_n.png"));
material->map_displacement = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048_h.png"));
material->map_specular = core::Resources::getInstance().getTexture(files::asset("meshes/scenery/gravel_medium2048_s.png"));
return material;
}
......
#include <cinttypes>
#include <util/log.h>
#include <glm/glm.hpp>
#define in
#define ggxChi(a) (a > 0 ? 1 : 0)
using namespace glm;
float ggxDist(float roughness, float cosT)
{
//roughness += 1e-5f;
//float normal_dot_half = cosT;
//float roughness2 = roughness * roughness;
//float normal_dot_half2 = normal_dot_half * normal_dot_half;
//float tan2 = (1 - normal_dot_half2) / normal_dot_half2;
//float mult = roughness2 + tan2;
//mult *= mult;
//float denominator = 3.141592f * normal_dot_half2 * normal_dot_half2 * mult;
//return (ggxChi(cosT) * roughness2) / denominator;
float alphaSqr = max(roughness * roughness, 0.005f);
float denom = cosT * cosT * (alphaSqr - 1.0) + 1.0;
return alphaSqr / (denom * denom);
}
#include <iostream>
int main(int argc, char* argv[])
{
auto i = ggxDist(0, 1);
auto a = ggxDist(0, 0.5f);
auto r = ggxDist(0.5f, 1);
auto z = ggxDist(0.5f, 0.5f);
auto t = ggxDist(1, 1);
auto h = ggxDist(1, 0.5f);
system("pause");
}
\ No newline at end of file
......@@ -16,6 +16,12 @@ namespace glare
{
}
Camera::Camera()
: m_adapt_to_screen(true), m_width(state::window->getWidth()), m_height(state::window->getHeight()), m_projection(Projection::ePerspective)
{
}
Camera::~Camera()
{
}
......@@ -52,16 +58,25 @@ namespace glare
}
void Camera::update()
{
m_width = core::state::window->getWidth();
m_height = core::state::window->getHeight();
{
if (m_adapt_to_screen)
{
m_width = state::window->getWidth();
m_height = state::window->getHeight();
}
const glm::vec3 world_position = getOwner()->c_worldTransform().position;
const glm::vec3 world_forward = getOwner()->c_worldTransform().forward();
const glm::vec3 world_up = getOwner()->c_worldTransform().up();
m_view_matrix = glm::lookAt(world_position, world_position + world_forward, world_up);
m_projection_matrix = makeProjectionMatrix();
}
void Camera::resize(unsigned width, unsigned height)
{
m_width = width;
m_height = height;
}
glm::mat4 Camera::makeProjectionMatrix() const
......
......@@ -30,6 +30,10 @@ namespace glare
* \param height Screen height
*/
Camera(unsigned int width, unsigned int height, Projection projection = Projection::ePerspective);
Camera();
virtual ~Camera();
/**
......@@ -39,6 +43,8 @@ namespace glare
void gui() override;
void onTransformChanged() override;
void resize(unsigned width, unsigned height);
void setProjection(Projection projection);
glm::mat4 makeProjectionMatrix() const;
......@@ -57,6 +63,7 @@ namespace glare
float getDofSize() const;
private:
bool m_adapt_to_screen = false;
float m_focus_distance = 10.f;
float m_dof_size = 50.f;
......
......@@ -31,7 +31,7 @@ namespace glare
void LightComponent::update()
{
if (!m_shadow_map_renderer && getOwner() && m_data.light_type == LightType::eDirectional) {
m_shadow_map_renderer = std::make_unique<ShadowMap>(2048, 500, getOwner());
m_shadow_map_renderer = std::make_unique<ShadowMap>(4096, 350, getOwner());
}
}
......
......@@ -48,6 +48,8 @@ namespace glare
gl::bindFramebuffer(gl::FramebufferTarget::eDefault, current_fb);
m_matrix = m_bias_matrix * m_camera->getViewProjection();
gl::generateTextureMipmap(m_framebuffer->depthAttachment().id());
}
const core::Framebuffer<Texture> &ShadowMap::framebuffer() const
......
......@@ -726,12 +726,9 @@ namespace glare
{
Log_Debug << "Decoding cameras...";
const unsigned width = core::state::window->getWidth();
const unsigned height = core::state::window->getHeight();
for (const auto &camera_sub : cam_node.children())
{
auto camera = std::make_shared<core::Camera>(width, height, core::Camera::Projection::ePerspective);
auto camera = std::make_shared<core::Camera>();
//camera_sub is now a camera node.
auto perspective_node = camera_sub.child("optics").child("technique_common").child("perspective");
......
......@@ -171,7 +171,7 @@ namespace glare
constexpr static const gl::TextureInternalFormat gl_internal_format = InternalFormat;
constexpr static const gl::Type gl_type = T;
Texture(unsigned width, unsigned height, tex_type* data = nullptr, gl::TextureFilterMin min = gl::TextureFilterMin::eLinearMipmapLinear, gl::TextureFilterMag mag = gl::TextureFilterMag::eNearest);
Texture(unsigned width, unsigned height, tex_type* data = nullptr, gl::TextureFilterMin min = gl::TextureFilterMin::eLinearMipmapLinear, gl::TextureFilterMag mag = gl::TextureFilterMag::eLinear);
~Texture();
void setFiltering(gl::TextureFilterMin min, gl::TextureFilterMag mag);
......
......@@ -50,7 +50,7 @@ namespace glare
void initialize(unsigned width, unsigned height, unsigned samples, std::string title)
{
window->initialize(width, height, title);
camera = std::make_shared<Camera>(width, height, Camera::Projection::ePerspective);
camera = std::make_shared<Camera>();
gbuffer->initialize(width, height, samples);
gbuffer->setSkybox(skybox);
Callbacks::initialize(window->glfw());
......@@ -109,6 +109,7 @@ namespace glare
window->resize(width, height);
if (camera) {
// If camera is adaptive, the width and height will be updated, otherwise, it should stay the same size
camera->update();
messaging::Handler::getInstance().submit(messaging::make_message(tags::camera, 1));
}
......
......@@ -155,8 +155,6 @@ namespace glare
m_last_width = width;
m_last_height = height;
Log_Info << "RESIZED: " << width << ", " << height;
m_trace_buffer->reserve<Trace>(width * height, gl::BufferUsage::eDynamicCopy);
m_render_target = std::make_unique<core::TextureRGBA_32F>(width, height);
m_color_store = std::make_unique<core::TextureRGBA_32F>(width, height);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment