diff options
author | Jack Andersen <someemail@gmail.com> | 2016-03-13 04:00:12 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2016-03-13 04:05:36 +0300 |
commit | 861616bf693b78b070ada6cbc6aa79eb807fdde8 (patch) | |
tree | 4626f295c739ea7fa689e4f56d6877845eb9adf1 /source/blender/gpu | |
parent | 989b0e472e74869be9f170e2dafbae76d6a4ce94 (diff) |
Full Inverse-Quadratic-Equation Lamp Falloff
This patch adds a new `falloff_type` ('Inverse Coefficients') for Lamps in
Blender-Internal and GLSL.
The current falloff modes use a formula like this inverse-square one:
`I = E × (D^2 / (D^2 + Q × r^2))`
While such a formula is simple for 3D-artists to use, it's algebraically
cumbersome to work with. Game-designers authoring their own shaders
could benefit much more by having direct control of falloff-coefficients:
`I = E × (1.0 / (coefC + coefL × r + coefQ × r^2))`
In this mode, the `distance` parameter is unused (except for 'Sphere'
mode); instead relying on the designer to mathematically-model the
falloff-behavior.
The UI has been patched like so:
{F153843}
Reviewers: brecht, psy-fi
Reviewed By: psy-fi
Subscribers: brita_, antidote, campbellbarton, psy-fi
Differential Revision: https://developer.blender.org/D1194
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_material.h | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 16 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 11 |
3 files changed, 31 insertions, 2 deletions
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3bcc7e23f06..f150b7215e1 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -166,6 +166,9 @@ typedef enum GPUDynamicType { GPU_DYNAMIC_LAMP_SPOTSIZE = 10 | GPU_DYNAMIC_GROUP_LAMP, GPU_DYNAMIC_LAMP_SPOTBLEND = 11 | GPU_DYNAMIC_GROUP_LAMP, GPU_DYNAMIC_LAMP_SPOTSCALE = 12 | GPU_DYNAMIC_GROUP_LAMP, + GPU_DYNAMIC_LAMP_COEFFCONST = 13 | GPU_DYNAMIC_GROUP_LAMP, + GPU_DYNAMIC_LAMP_COEFFLIN = 14 | GPU_DYNAMIC_GROUP_LAMP, + GPU_DYNAMIC_LAMP_COEFFQUAD = 15 | GPU_DYNAMIC_GROUP_LAMP, GPU_DYNAMIC_SAMPLER_2DBUFFER = 1 | GPU_DYNAMIC_GROUP_SAMPLER, GPU_DYNAMIC_SAMPLER_2DIMAGE = 2 | GPU_DYNAMIC_GROUP_SAMPLER, @@ -318,7 +321,8 @@ float *GPU_lamp_dynpersmat(GPULamp *lamp); void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]); void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); -void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2); +void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2, + float coeff_const, float coeff_lin, float coeff_quad); void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); int GPU_lamp_shadow_layer(GPULamp *lamp); GPUNodeLink *GPU_lamp_get_data( diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index cc401dc63c4..c32326889d1 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -148,6 +148,7 @@ struct GPULamp { float spotvec[2]; float dyndist, dynatt1, dynatt2; float dist, att1, att2; + float coeff_const, coeff_lin, coeff_quad; float shadow_color[3]; float bias, d, clipend; @@ -550,6 +551,12 @@ static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob), GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac); break; + case LA_FALLOFF_INVCOEFFICIENTS: + GPU_link(mat, "lamp_falloff_invcoefficients", + GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob), + GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob), + GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac); + break; case LA_FALLOFF_CURVE: { float *array; @@ -2209,11 +2216,15 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener lamp->col[2] = b; } -void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2) +void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2, + float coeff_const, float coeff_lin, float coeff_quad) { lamp->dist = distance; lamp->att1 = att1; lamp->att2 = att2; + lamp->coeff_const = coeff_const; + lamp->coeff_lin = coeff_lin; + lamp->coeff_quad = coeff_quad; } void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend) @@ -2254,6 +2265,9 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l lamp->falloff_type = la->falloff_type; lamp->att1 = la->att1; lamp->att2 = la->att2; + lamp->coeff_const = la->coeff_const; + lamp->coeff_lin = la->coeff_lin; + lamp->coeff_quad = la->coeff_quad; lamp->curfalloff = la->curfalloff; /* initshadowbuf */ diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 51d4706d91e..05853c3e2d3 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1627,6 +1627,17 @@ void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out visifac *= lampdistkw/(lampdistkw + ld2*dist*dist); } +void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coeff_quad, float dist, out float visifac) +{ + vec3 coeff = vec3(coeff_const, coeff_lin, coeff_quad); + vec3 d_coeff = vec3(1.0, dist, dist*dist); + float visifac_r = dot(coeff, d_coeff); + if (visifac_r > 0.0) + visifac = 1.0 / visifac_r; + else + visifac = 0.0; +} + void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac) { visifac = texture2D(curvemap, vec2(dist/lampdist, 0.0)).x; |