summaryrefslogtreecommitdiff
path: root/lighting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lighting.cpp')
-rw-r--r--lighting.cpp78
1 files changed, 58 insertions, 20 deletions
diff --git a/lighting.cpp b/lighting.cpp
index 1eb4298..9f154cb 100644
--- a/lighting.cpp
+++ b/lighting.cpp
@@ -8,6 +8,8 @@ extern "C" {
#include "plat.h"
}
+#include <random>
+
/* needs to match surface shader */
struct GPU_Light {
v3f dir;
@@ -18,18 +20,19 @@ struct GPU_Light {
struct GPU_Caster {
m4f projection;
+ m4f jittered;
};
void Lighting::init(Device* dev, int w, int h) {
int i;
Sampler_State ss{};
- lights.init(
+ gpu_lights.init(
dev,
"Light buffer",
max_lights * sizeof(GPU_Light),
Buffer_Flags::storage_buffer
);
- casters.init(
+ gpu_casters.init(
dev,
"Caster buffer",
max_shadows * sizeof(GPU_Caster),
@@ -43,13 +46,14 @@ void Lighting::init(Device* dev, int w, int h) {
shadow_res,
1,
1,
- max_shadows,
+ shadowmap_count,
0
);
zero(ss_shadows, sizeof ss_shadows);
zero(ss_shadow_slices, sizeof ss_shadow_slices);
+ zero(occlusion, sizeof occlusion);
recreate(dev, w, h);
- for (i = 0; i < max_shadows; i++) {
+ for (i = 0; i < shadowmap_count; i++) {
cameras[i] = 0;
shadow_slices[i] = dev->alias_texture(
shadows,
@@ -80,10 +84,10 @@ void Lighting::init(Device* dev, int w, int h) {
void Lighting::destroy(Device* dev, Renderer& r) {
int i;
- lights.destroy(dev);
- casters.destroy(dev);
+ gpu_lights.destroy(dev);
+ gpu_casters.destroy(dev);
dev->destroy_sampler(shadow_sampler);
- for (i = 0; i < max_shadows; i++) {
+ for (i = 0; i < shadowmap_count; i++) {
dev->destroy_texture(shadow_slices[i]);
r.destroy_camera(cameras[i]);
}
@@ -99,6 +103,8 @@ void Lighting::destroy_ss(Device* dev) {
dev->destroy_texture(ss_shadow_slices[i][j]);
if (ss_shadows[i])
dev->destroy_texture(ss_shadows[i]);
+ if (occlusion[i])
+ dev->destroy_texture(occlusion[i]);
}
}
@@ -131,7 +137,28 @@ void Lighting::recreate(Device* dev, int w, int h) {
0,
j
);
+ occlusion[i] = dev->create_texture(
+ "Occlusion buffer",
+ texture_format_r32f,
+ Texture_Flags::sampleable | Texture_Flags::colour_target,
+ w,
+ h,
+ 1,
+ 1,
+ 1,
+ 0
+ );
+ }
+}
+
+Camera_Id Lighting::gm_cam(Renderer& r) {
+ int id = cam_count++;
+ Camera_Id cid = cameras[id];
+ if (!cid) {
+ cid = r.create_camera();
+ cameras[id] = cid;
}
+ return cid;
}
void Lighting::write_bufs(
@@ -144,6 +171,10 @@ void Lighting::write_bufs(
GPU_Light* ldst = (GPU_Light*)lptr;
GPU_Caster* cdst = (GPU_Caster*)cptr;
int count = 0, ccount = 0;
+ cam_count = 0;
+ std::random_device dev;
+ std::mt19937 rng(dev());
+ std::uniform_real_distribution<float> dist6(-0.01f, 0.01f);
for (auto v : w.view<Sun_Light>()) {
GPU_Light gl;
Sun_Light& l = v.get<Sun_Light>();
@@ -155,15 +186,22 @@ void Lighting::write_bufs(
gl.colour = l.colour;
gl.dir = l.dir;
if (l.caster && ccount < max_shadows) {
+ Camera* cam[2];
int cid = ccount++;
- GPU_Caster& c = cdst[cid];
- Camera_Id camid = cameras[cid];
- if (!camid)
- camid = r.create_camera();
- Camera& cam = r.get_camera(camid);
- cam.init_shadow(l.dir, s.bound.min, s.bound.max);
- c.projection = cam.get_proj() * cam.get_view();
- cameras[cid] = camid;
+ Caster& caster = casters[cid];
+ GPU_Caster& gc = cdst[cid];
+ v3f jitter(
+ dist6(rng),
+ dist6(rng),
+ dist6(rng)
+ );
+ caster = Caster { gm_cam(r), gm_cam(r) };
+ cam[0] = &r.get_camera(caster.reality);
+ cam[1] = &r.get_camera(caster.jittered);
+ cam[0]->init_shadow(l.dir, s.bound.min, s.bound.max);
+ cam[1]->init_shadow(l.dir + jitter, s.bound.min, s.bound.max);
+ gc.projection = cam[0]->get_proj() * cam[0]->get_view();
+ gc.jittered = cam[1]->get_proj() * cam[1]->get_view();
gl.caster_id = cid;
} else
gl.caster_id = -1;
@@ -181,10 +219,10 @@ void Lighting::update(
Model_Scene& s
) {
light_count = 0;
- write_bufs(lights.map(dev), casters.map(dev), w, r, s);
- casters.unmap(dev);
- lights.unmap(dev);
- lights.update(ctx);
- casters.update(ctx);
+ write_bufs(gpu_lights.map(dev), gpu_casters.map(dev), w, r, s);
+ gpu_casters.unmap(dev);
+ gpu_lights.unmap(dev);
+ gpu_lights.update(ctx);
+ gpu_casters.update(ctx);
}