diff options
-rw-r--r-- | intermediate/forward.h | 13 | ||||
-rw-r--r-- | intermediate/surface.glsl | 95 | ||||
-rw-r--r-- | lighting.cpp | 9 | ||||
-rw-r--r-- | lighting.hpp | 7 | ||||
-rw-r--r-- | renderer.cpp | 7 |
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); } |