summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intermediate/forward.h13
-rw-r--r--intermediate/surface.glsl95
-rw-r--r--lighting.cpp9
-rw-r--r--lighting.hpp7
-rw-r--r--renderer.cpp7
5 files changed, 87 insertions, 44 deletions
diff --git a/intermediate/forward.h b/intermediate/forward.h
index 377a3cb..3bc2d50 100644
--- a/intermediate/forward.h
+++ b/intermediate/forward.h
@@ -17,9 +17,6 @@ type: vec3
name: caster_id
type: int
[variable]
-name: type
-type: int
-[variable]
name: range
type: float
@@ -40,6 +37,12 @@ type: int
[variable]
name: frame
type: int
+[variable]
+name: sun_irange
+type: ivec2
+[variable]
+name: point_irange
+type: ivec2
[cbuffer]
name: globals
@@ -48,8 +51,4 @@ stage: fragment
#endif
-/* match Light::Type in lighting.hpp */
-#define LT_SUN 0
-#define LT_POINT 1
-
#endif
diff --git a/intermediate/surface.glsl b/intermediate/surface.glsl
index 79f5f65..ce80259 100644
--- a/intermediate/surface.glsl
+++ b/intermediate/surface.glsl
@@ -215,8 +215,32 @@ float get_shadow(Light l, vec3 wpos) {
return d;
}
+vec3 apply_light(
+ Light l,
+ vec3 p,
+ vec2 uv,
+ vec3 base_diffuse,
+ vec3 spec_col,
+ vec3 ref,
+ vec3 light_dir,
+ vec3 view_dir,
+ vec3 nrm,
+ float cos_theta_i,
+ float atten
+) {
+ vec3 diffuse = base_diffuse * cos_theta_i;
+ vec3 spec =
+ spec_col *
+ specular_brdf(uv, ref, light_dir, view_dir, nrm) *
+ cos_theta_i;
+ float shadow = 1.0f;
+ if (l.caster_id >= 0)
+ shadow = get_shadow(l, p);
+ return (diffuse + spec) * atten * l.brightness * l.colour * shadow;
+}
+
void main() {
- int i;
+ int i, e;
vec2 uv = interpolator.uv;
vec3 p = interpolator.position.xyz;
@@ -242,34 +266,49 @@ void main() {
vec3 base_diffuse = diffuse_brdf(uv) * (1.0 - met);
vec3 light = 0.0.xxx;
- for (i = 0; i < globals.light_count; i++) {
+ e = globals.sun_irange.y;
+ for (i = globals.sun_irange.x; i < e; i++) {
+ Light l = lights[i];
+ vec3 light_dir = l.pos;
+ float cos_theta_i = max(dot(nrm, light_dir), 0.0);
+ float atten = 1.0;
+ light += apply_light(
+ l,
+ p,
+ uv,
+ base_diffuse,
+ spec_col,
+ ref,
+ light_dir,
+ view_dir,
+ nrm,
+ cos_theta_i,
+ atten
+ );
+ }
+ e = globals.point_irange.y;
+ for (i = globals.point_irange.x; i < e; i++) {
Light l = lights[i];
- vec3 light_dir;
- float cos_theta_i, atten;
- switch (l.type) {
- case LT_SUN:
- light_dir = l.pos;
- cos_theta_i = max(dot(nrm, light_dir), 0.0);
- atten = 1.0;
- break;
- case LT_POINT: {
- float d;
- light_dir = p - l.pos;
- d = length(light_dir);
- atten = max(d, 0.01);
- atten = 1.0 / (atten * atten);
- light_dir /= d;
- } break;
- }
- vec3 diffuse = base_diffuse * cos_theta_i;
- vec3 spec =
- spec_col *
- specular_brdf(uv, ref, light_dir, view_dir, nrm) *
- cos_theta_i;
- float shadow = 1.0f;
- if (l.caster_id >= 0)
- shadow = get_shadow(l, p);
- light += (diffuse + spec) * atten * l.brightness * l.colour * shadow;
+ float cos_theta_i;
+ vec3 light_dir = l.pos - p;
+ float d = length(light_dir);
+ float atten = max(d, 0.01);
+ atten = 1.0 / (atten * atten);
+ light_dir /= d;
+ cos_theta_i = max(dot(nrm, light_dir), 0.0);
+ light += apply_light(
+ l,
+ p,
+ uv,
+ base_diffuse,
+ spec_col,
+ ref,
+ light_dir,
+ view_dir,
+ nrm,
+ cos_theta_i,
+ atten
+ );
}
colour = vec4(ambient + light, 1.0);
diff --git a/lighting.cpp b/lighting.cpp
index bf01831..b140611 100644
--- a/lighting.cpp
+++ b/lighting.cpp
@@ -15,9 +15,8 @@ struct GPU_Light {
float brightness;
v3f colour;
int caster_id;
- int type;
float range;
- int pad[2];
+ int pad[3];
};
struct GPU_Caster {
@@ -101,6 +100,7 @@ void Lighting::write_bufs(
GPU_Light* ldst = (GPU_Light*)lptr;
GPU_Caster* cdst = (GPU_Caster*)cptr;
int count = 0, ccount = 0;
+ sun_range[0] = count;
for (auto v : w.view<Sun_Light>()) {
GPU_Light gl;
Sun_Light& l = v.get<Sun_Light>();
@@ -108,7 +108,6 @@ void Lighting::write_bufs(
print_war("Over light limit.\n");
goto cancel;
}
- gl.type = (int)Light::Type::sun;
gl.brightness = l.brightness;
gl.colour = l.colour;
gl.pos = l.dir;
@@ -127,6 +126,8 @@ void Lighting::write_bufs(
gl.caster_id = -1;
ldst[count++] = gl;
}
+ sun_range[1] = count;
+ point_range[0] = count;
for (auto v : w.view<Transform, Point_Light>()) {
GPU_Light gl;
Transform& t = v.get<Transform>();
@@ -135,7 +136,6 @@ void Lighting::write_bufs(
print_war("Over light limit.\n");
goto cancel;
}
- gl.type = (int)Light::Type::point;
gl.brightness = l.brightness;
gl.colour = l.colour;
gl.pos = v3f(
@@ -147,6 +147,7 @@ void Lighting::write_bufs(
gl.range = l.range;
ldst[count++] = gl;
}
+ point_range[1] = count;
cancel:
light_count = count;
caster_count = ccount;
diff --git a/lighting.hpp b/lighting.hpp
index 38e95ae..7c57bab 100644
--- a/lighting.hpp
+++ b/lighting.hpp
@@ -21,6 +21,8 @@ struct Lighting {
Texture_Id shadow_slices[max_shadows];
Sampler_Id shadow_sampler;
Camera_Id cameras[max_shadows];
+ int sun_range[2];
+ int point_range[2];
int light_count, caster_count;
void init(Device* dev);
void destroy(Device* dev, Renderer& r);
@@ -41,11 +43,6 @@ struct Lighting {
};
struct Light {
- enum class Type {
- sun,
- point
- };
-
v3f colour;
float brightness;
bool caster;
diff --git a/renderer.cpp b/renderer.cpp
index 64c3795..6208d3c 100644
--- a/renderer.cpp
+++ b/renderer.cpp
@@ -15,6 +15,9 @@ struct Global_Cbuffer {
v3f camera_pos;
int light_count;
int frame;
+ int pad;
+ int sun_irange[2];
+ int point_irange[2];
};
void init_drawlist(
@@ -119,6 +122,10 @@ void Renderer::update_globals(
cb->camera_pos = cp;
cb->frame = frame;
cb->light_count = l->light_count;
+ cb->sun_irange[0] = l->sun_range[0];
+ cb->sun_irange[1] = l->sun_range[1];
+ cb->point_irange[0] = l->point_range[0];
+ cb->point_irange[1] = l->point_range[1];
globals.unmap(d);
globals.update(ctx);
}