Skip to content

Commit

Permalink
make the directional mapping frustum-dependent
Browse files Browse the repository at this point in the history
  • Loading branch information
laudominik committed Jun 21, 2024
1 parent 1298cd8 commit a8dc22f
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 82 deletions.
12 changes: 6 additions & 6 deletions examples/scene3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ int main(){
.quadratic = 0.0
}
}))
// .addLightSource(dirLight)
.addLightSource(light::make_dir({
.direction = {-1, -1, 0},
.color = {1, 1, 1},
.intensity = 1
}))
.addLightSource(dirLight)
// .addLightSource(light::make_dir({
// .direction = {-1, -1, 0},
// .color = {1, 1, 1},
// .intensity = 1
// }))
// .addLightSource(light::make_dir({
// .direction = {1, -1, 0},
// .color = {1, 1, 1},
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
small TODO list:
> add CSM
> add shadows from point lights
> add CSM
> add sprites
> add cel shader material
...
Expand Down
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions src/shaders/depth/omni/fs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
in vec4 FragPos;

uniform vec3 lightPos;
uniform float far_plane;

void main()
{
float lightDistance = length(FragPos.xyz - lightPos);
lightDistance = lightDistance / far_plane;
gl_FragDepth = lightDistance;
}
20 changes: 20 additions & 0 deletions src/shaders/depth/omni/gs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;

uniform mat4 shadowMatrices[6];

out vec4 FragPos;

void main()
{
for(int face = 0; face < 6; ++face)
{
gl_Layer = face;
for(int i = 0; i < 3; ++i){
FragPos = gl_in[i].gl_Position;
gl_Position = shadowMatrices[face] * FragPos;
EmitVertex();
}
EndPrimitive();
}
}
7 changes: 7 additions & 0 deletions src/shaders/depth/omni/vs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
uniform mat4 rotation;
uniform mat4 transform;
in vec3 vPos;

void main(){
gl_Position = transform * rotation * vec4(vPos, 1.0);
}
2 changes: 1 addition & 1 deletion src/shaders/solid/fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void main()
outColor += calcDirLight(uDirectionalLights[i], normal_val, viewDir, uShininess, specular_val, uDiffuse);
}

if(hasShadow == 1){
if(hasShadow == 1 && uNumDirLights != 0){
float sh = 0.0;
for(int i = 0; i < uNumDirLights; i++){
vec4 shadowSpacePos = shadowSpaceMatrix[i] * model * ogPos;
Expand Down
17 changes: 12 additions & 5 deletions src/tricore/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ using namespace tri::core;
using namespace tri::core::materials;


static constexpr auto DEPTH = "depth";
static constexpr auto DEPTH = "depth/map2d";

class ShadowProgram : public Program {
public:
ShadowProgram() : Program(
fmt::format("{}/{}/vs.glsl", SHADER_PATH, DEPTH),
fmt::format("{}/{}/fs.glsl", SHADER_PATH, DEPTH)){}
public:
ShadowProgram() : Program(
fmt::format("{}/{}/vs.glsl", SHADER_PATH, DEPTH),
fmt::format("{}/{}/fs.glsl", SHADER_PATH, DEPTH)){}
};

class OmniShadowProgram : public Program {
public:
OmniShadowProgram() : Program(
fmt::format("{}/{}/vs.glsl", SHADER_PATH, DEPTH),
fmt::format("{}/{}/fs.glsl", SHADER_PATH, DEPTH)){}
};

void Renderer::render(){
Expand Down
127 changes: 58 additions & 69 deletions src/tricore/light/LightSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <glm/mat4x4.hpp>
#include <memory>
#include <config.h>
#include <array>


namespace tri::core {
Expand Down Expand Up @@ -53,13 +54,21 @@ namespace tri::core {
return ptr;
}

inline glm::mat4x4 get_lightspace_matrix(PointLight point){
inline std::array<glm::mat4x4, 6> get_lightspace_matrices(PointLight point){
float near = 1.f;
float far = 25.f;
auto shadowWidth = config::SHADOW_RESOLUTION.w;
auto shadowHeight = config::SHADOW_RESOLUTION.h;
return glm::perspective(glm::radians(45.0f),
(GLfloat)shadowWidth / (GLfloat)shadowHeight,
config::CAMERA_NEAR_PLANE,
config::CAMERA_FAR_PLANE);
auto perspective = glm::perspective(glm::radians(45.0f), (GLfloat)shadowWidth / (GLfloat)shadowHeight, near, far);

return {
perspective * glm::lookAt(point.pos, point.pos + glm::vec3{1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}),
perspective * glm::lookAt(point.pos, point.pos + glm::vec3{-1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}),
perspective * glm::lookAt(point.pos, point.pos + glm::vec3{0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}),
perspective * glm::lookAt(point.pos, point.pos + glm::vec3{1.f, -1.f, 0.f}, {0.f, -1.f, -1.f}),
perspective * glm::lookAt(point.pos, point.pos + glm::vec3{1.f, 0.f, 1.f}, {0.f, -1.f, 0.f}),
perspective * glm::lookAt(point.pos, point.pos + glm::vec3{1.f, 0.f, -1.f}, {0.f, -1.f, 0.f})
};
}


Expand All @@ -79,72 +88,52 @@ namespace tri::core {
return frustumCorners;
}

inline glm::mat4x4 get_lightspace_matrix(DirectionalLight dir, Camera& camera){
// float farPlane = config::CAMERA_FAR_PLANE;
// float nearPlane = config::CAMERA_NEAR_PLANE;
// const auto corners = getFrustumCornersWorldSpace(camera.view());

// glm::vec3 center = glm::vec3(0, 0, 0);
// for (const auto& v : corners){
// center += glm::vec3(v);
// }
// center /= corners.size();

// const auto lightView = glm::lookAt(center + dir.direction, center, UP);

// float minX = std::numeric_limits<float>::max();
// float maxX = std::numeric_limits<float>::lowest();
// float minY = std::numeric_limits<float>::max();
// float maxY = std::numeric_limits<float>::lowest();
// float minZ = std::numeric_limits<float>::max();
// float maxZ = std::numeric_limits<float>::lowest();
// for (const auto& v : corners){
// const auto trf = lightView * v;
// minX = std::min(minX, trf.x);
// maxX = std::max(maxX, trf.x);
// minY = std::min(minY, trf.y);
// maxY = std::max(maxY, trf.y);
// minZ = std::min(minZ, trf.z);
// maxZ = std::max(maxZ, trf.z);
// }

// // Tune this parameter according to the scene
// constexpr float zMult = 1.0f;
// if (minZ < 0){
// minZ *= zMult;
// } else {
// minZ /= zMult;
// }
// if (maxZ < 0){
// maxZ /= zMult;
// } else
// {
// maxZ *= zMult;
// }

// const glm::mat4 lightProjection = glm::ortho(minX, maxX, minY, maxY, minZ, maxZ);
// return lightProjection * lightView;

static constexpr auto lightScale = 5.f;

auto shadowWidth = config::SHADOW_RESOLUTION.w;
auto shadowHeight = config::SHADOW_RESOLUTION.h;
auto lightProjection = glm::perspective(glm::radians(45.0f),
(GLfloat)shadowWidth / (GLfloat)shadowHeight,
config::CAMERA_NEAR_PLANE,
config::CAMERA_FAR_PLANE);

// TODO: make dependent on camera pos
lightProjection = glm::ortho(-30.0f, 30.0f, -30.0f, 30.0f, -30.0f, 30.f);
auto lightView = glm::lookAt(-dir.direction * lightScale, glm::vec3(0.0f), glm::vec3(0.0, 1.0, 0.0));
inline glm::mat4x4 get_lightspace_matrix(DirectionalLight dir, Camera& camera, float nearPlane=0.1, float farPlane=25.0){
auto pv = glm::perspective(glm::radians(camera.getFov()),
camera.getAspectRatio(), nearPlane, farPlane) * glm::lookAt(camera.getPos(), camera.getPos() + camera.getDir(), UP);

const auto corners = getFrustumCornersWorldSpace(pv);

glm::vec3 center = glm::vec3(0, 0, 0);
for (const auto& v : corners){
center += glm::vec3(v);
}
center /= corners.size();

const auto lightView = glm::lookAt(center - dir.direction, center, UP);

float minX = std::numeric_limits<float>::max();
float maxX = std::numeric_limits<float>::lowest();
float minY = std::numeric_limits<float>::max();
float maxY = std::numeric_limits<float>::lowest();
float minZ = std::numeric_limits<float>::max();
float maxZ = std::numeric_limits<float>::lowest();
for (const auto& v : corners){
const auto trf = lightView * v;
minX = std::min(minX, trf.x);
maxX = std::max(maxX, trf.x);
minY = std::min(minY, trf.y);
maxY = std::max(maxY, trf.y);
minZ = std::min(minZ, trf.z);
maxZ = std::max(maxZ, trf.z);
}

// Tune this parameter according to the scene
constexpr float zMult = 1.f;
if (minZ < 0){
minZ *= zMult;
} else {
minZ /= zMult;
}
if (maxZ < 0){
maxZ /= zMult;
} else {
maxZ *= zMult;
}

const glm::mat4 lightProjection = glm::ortho(minX, maxX, minY, maxY, minZ, maxZ);
return lightProjection * lightView;
}






}
}

Expand Down

0 comments on commit a8dc22f

Please sign in to comment.