diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-03-19 14:07:23 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-03-19 23:11:06 +0300 |
commit | 884f934a853f7043a7e5a6ea380d560c858a78b7 (patch) | |
tree | 14c4441579169bcc50de145d24dbff5ab206200a /source/blender/draw/engines/eevee/shaders | |
parent | fb3e5b7f986e7215c6488c2b93db8559e84cfb98 (diff) |
EEVEE: Lights: Add Volume and diffuse light power slider
This adds 2 new sliders for light objects that modulates the diffuse
light and the volume light intensities.
This also changes the way volume light is computed using point lamp
representation. We use "Point Light Attenuation Without Singularity"
from Cem Yuksel instead of the usual inverse square law.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
5 files changed, 35 insertions, 33 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl index c5996f5160a..4f9791ac95f 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl @@ -45,7 +45,8 @@ void closure_Diffuse_light_eval(ClosureInputDiffuse cl_in, float radiance = light_diffuse(light.data, cl_in.N, cl_common.V, light.L); /* TODO(fclem) We could try to shadow lights that are shadowless with the ambient_occlusion * factor here. */ - cl_out.radiance += light.data.l_color * (light.vis * light.contact_shadow * radiance); + cl_out.radiance += light.data.l_color * + (light.data.l_diff * light.vis * light.contact_shadow * radiance); } void closure_Diffuse_grid_eval(ClosureInputDiffuse cl_in, diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl index 66c467af29b..183219c9088 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl @@ -32,7 +32,7 @@ void closure_Translucent_light_eval(ClosureInputTranslucent cl_in, inout ClosureOutputTranslucent cl_out) { float radiance = light_diffuse(light.data, cl_in.N, cl_common.V, light.L); - cl_out.radiance += light.data.l_color * (light.vis * radiance); + cl_out.radiance += light.data.l_color * (light.data.l_diff * light.vis * radiance); } void closure_Translucent_grid_eval(ClosureInputTranslucent cl_in, diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl index 87934027361..d2daa5a1092 100644 --- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl @@ -14,18 +14,22 @@ struct LightData { vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */ - vec4 color_spec; /* w : Spec Intensity */ + vec4 color_influence_volume; /* w : InfluenceRadius but for Volume power */ vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */ vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */ vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */ vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */ + vec4 diff_spec_volume; /* xyz: Diffuse/Spec/Volume power, w: unused. */ }; /* convenience aliases */ -#define l_color color_spec.rgb -#define l_spec color_spec.a +#define l_color color_influence_volume.rgb +#define l_diff diff_spec_volume.x +#define l_spec diff_spec_volume.y +#define l_volume diff_spec_volume.z #define l_position position_influence.xyz #define l_influence position_influence.w +#define l_influence_volume color_influence_volume.w #define l_sizex rightvec_sizex.w #define l_sizey upvec_sizey.w #define l_right rightvec_sizex.xyz diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl index b1e3a40e8d2..5b747d66e4d 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl @@ -64,38 +64,35 @@ float phase_function(vec3 v, vec3 l, float g) vec3 light_volume(LightData ld, vec4 l_vector) { - float power; - /* TODO : Area lighting ? */ - /* XXX : Removing Area Power. */ - /* TODO : put this out of the shader. */ - /* See eevee_light_setup(). */ - if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { - power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0); - if (ld.l_type == AREA_ELLIPSE) { - power *= M_PI * 0.25; + float power = 1.0; + if (ld.l_type != SUN) { + /** + * Using "Point Light Attenuation Without Singularity" from Cem Yuksel + * http://www.cemyuksel.com/research/pointlightattenuation/pointlightattenuation.pdf + * http://www.cemyuksel.com/research/pointlightattenuation/ + **/ + float d = l_vector.w; + float d_sqr = sqr(d); + float r_sqr = sqr(ld.l_radius); + /* Using reformulation that has better numerical percision. */ + power = 2.0 / (d_sqr + r_sqr + d * sqrt(d_sqr + r_sqr)); + + if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) { + /* Modulate by light plane orientation / solid angle. */ + power *= saturate(dot(-ld.l_forward, l_vector.xyz / l_vector.w)); } - power *= 20.0 * - max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */ } - else if (ld.l_type == SUN) { - power = ld.l_radius * ld.l_radius * M_PI; /* Removing area light power*/ - power /= 1.0f + (ld.l_radius * ld.l_radius * 0.5f); - power *= M_PI * 0.5; /* Matching cycles. */ + return ld.l_color * ld.l_volume * power; +} + +vec3 light_volume_light_vector(LightData ld, vec3 P) +{ + if (ld.l_type == SUN) { + return -ld.l_forward; } else { - power = (4.0 * ld.l_radius * ld.l_radius) * (1.0 / 10.0); - power *= M_2PI; /* Matching cycles with point light. */ + return ld.l_position - P; } - - power /= (l_vector.w * l_vector.w); - - /* OPTI: find a better way than calculating this on the fly */ - float lum = dot(ld.l_color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ - vec3 tint = (lum > 0.0) ? ld.l_color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ - - lum = min(lum * power, volLightClamp); - - return tint * lum; } #define VOLUMETRIC_SHADOW_MAX_STEP 128.0 diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl index e72bf8b9150..f75108babe6 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl @@ -44,7 +44,7 @@ void main() LightData ld = lights_data[i]; vec4 l_vector; - l_vector.xyz = (ld.l_type == SUN) ? -ld.l_forward : ld.l_position - P; + l_vector.xyz = light_volume_light_vector(ld, P); l_vector.w = length(l_vector.xyz); float Vis = light_visibility(ld, P, l_vector); |