CD_PROP_COL datalayer
[blender.git] / source / blender / draw / engines / eevee / eevee_lights.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup DNA
21  */
22
23 #include "BLI_sys_types.h" /* bool */
24
25 #include "BKE_object.h"
26
27 #include "DEG_depsgraph_query.h"
28
29 #include "eevee_private.h"
30
31 /* Reconstruct local obmat from EEVEE_light. (normalized) */
32 void eevee_light_matrix_get(const EEVEE_Light *evli, float r_mat[4][4])
33 {
34   copy_v3_v3(r_mat[0], evli->rightvec);
35   copy_v3_v3(r_mat[1], evli->upvec);
36   negate_v3_v3(r_mat[2], evli->forwardvec);
37   copy_v3_v3(r_mat[3], evli->position);
38   r_mat[0][3] = 0.0f;
39   r_mat[1][3] = 0.0f;
40   r_mat[2][3] = 0.0f;
41   r_mat[3][3] = 1.0f;
42 }
43
44 static float light_attenuation_radius_get(const Light *la, float light_threshold)
45 {
46   if (la->mode & LA_CUSTOM_ATTENUATION) {
47     return la->att_dist;
48   }
49
50   /* Compute max light power. */
51   float power = max_fff(la->r, la->g, la->b);
52   power *= fabsf(la->energy / 100.0f);
53   power *= max_ff(1.0f, la->spec_fac);
54   /* Compute the distance (using the inverse square law)
55    * at which the light power reaches the light_threshold. */
56   float distance = sqrtf(max_ff(1e-16, power / max_ff(1e-16, light_threshold)));
57   return distance;
58 }
59
60 static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, const float scale[3])
61 {
62   if (la->type == LA_SPOT) {
63     /* Spot size & blend */
64     evli->sizex = scale[0] / scale[2];
65     evli->sizey = scale[1] / scale[2];
66     evli->spotsize = cosf(la->spotsize * 0.5f);
67     evli->spotblend = (1.0f - evli->spotsize) * la->spotblend;
68     evli->radius = max_ff(0.001f, la->area_size);
69   }
70   else if (la->type == LA_AREA) {
71     evli->sizex = max_ff(0.003f, la->area_size * scale[0] * 0.5f);
72     if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
73       evli->sizey = max_ff(0.003f, la->area_sizey * scale[1] * 0.5f);
74     }
75     else {
76       evli->sizey = max_ff(0.003f, la->area_size * scale[1] * 0.5f);
77     }
78   }
79   else if (la->type == LA_SUN) {
80     evli->radius = max_ff(0.001f, tanf(min_ff(la->sun_angle, DEG2RADF(179.9f)) / 2.0f));
81   }
82   else {
83     evli->radius = max_ff(0.001f, la->area_size);
84   }
85 }
86
87 static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
88 {
89   float power;
90   /* Make illumination power constant */
91   if (la->type == LA_AREA) {
92     power = 1.0f / (evli->sizex * evli->sizey * 4.0f * M_PI) * /* 1/(w*h*Pi) */
93             0.8f; /* XXX : Empirical, Fit cycles power */
94     if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
95       /* Scale power to account for the lower area of the ellipse compared to the surrounding
96        * rectangle. */
97       power *= 4.0f / M_PI;
98     }
99   }
100   else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
101     power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI); /* 1/(4*r²*Pi²) */
102
103     /* for point lights (a.k.a radius == 0.0) */
104     // power = M_PI * M_PI * 0.78; /* XXX : Empirical, Fit cycles power */
105   }
106   else {
107     power = 1.0f / (evli->radius * evli->radius * M_PI); /* 1/(r²*Pi) */
108     /* Make illumination power closer to cycles for bigger radii. Cycles uses a cos^3 term that we
109      * cannot reproduce so we account for that by scaling the light power. This function is the
110      * result of a rough manual fitting. */
111     power += 1.0f / (2.0f * M_PI); /* power *= 1 + r²/2 */
112   }
113   return power;
114 }
115
116 /* Update buffer with light data */
117 static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
118 {
119   Light *la = (Light *)ob->data;
120   float mat[4][4], scale[3], power, att_radius;
121
122   const DRWContextState *draw_ctx = DRW_context_state_get();
123   const float light_threshold = draw_ctx->scene->eevee.light_threshold;
124
125   /* Position */
126   copy_v3_v3(evli->position, ob->obmat[3]);
127
128   /* Color */
129   copy_v3_v3(evli->color, &la->r);
130
131   evli->spec = la->spec_fac;
132
133   /* Influence Radius */
134   att_radius = light_attenuation_radius_get(la, light_threshold);
135   /* Take the inverse square of this distance. */
136   evli->invsqrdist = 1.0 / max_ff(1e-4f, att_radius * att_radius);
137
138   /* Vectors */
139   normalize_m4_m4_ex(mat, ob->obmat, scale);
140   copy_v3_v3(evli->forwardvec, mat[2]);
141   normalize_v3(evli->forwardvec);
142   negate_v3(evli->forwardvec);
143
144   copy_v3_v3(evli->rightvec, mat[0]);
145   normalize_v3(evli->rightvec);
146
147   copy_v3_v3(evli->upvec, mat[1]);
148   normalize_v3(evli->upvec);
149
150   /* Make sure we have a consistent Right Hand coord frame.
151    * (in case of negatively scaled Z axis) */
152   float cross[3];
153   cross_v3_v3v3(cross, evli->rightvec, evli->forwardvec);
154   if (dot_v3v3(cross, evli->upvec) < 0.0) {
155     negate_v3(evli->upvec);
156   }
157
158   light_shape_parameters_set(evli, la, scale);
159
160   /* Light Type */
161   evli->light_type = (float)la->type;
162   if ((la->type == LA_AREA) && ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
163     evli->light_type = LAMPTYPE_AREA_ELLIPSE;
164   }
165
166   power = light_shape_power_get(la, evli);
167   mul_v3_fl(evli->color, power * la->energy);
168
169   /* No shadow by default */
170   evli->shadow_id = -1.0f;
171 }
172
173 void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
174 {
175   EEVEE_LightsInfo *linfo = sldata->lights;
176   linfo->num_light = 0;
177
178   EEVEE_shadows_cache_init(sldata, vedata);
179 }
180
181 void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
182 {
183   EEVEE_LightsInfo *linfo = sldata->lights;
184   const Light *la = (Light *)ob->data;
185
186   if (linfo->num_light >= MAX_LIGHT) {
187     printf("Too many lights in the scene !!!\n");
188     return;
189   }
190
191   /* Early out if light has no power. */
192   if (la->energy == 0.0f || is_zero_v3(&la->r)) {
193     return;
194   }
195
196   EEVEE_Light *evli = linfo->light_data + linfo->num_light;
197   eevee_light_setup(ob, evli);
198
199   if (la->mode & LA_SHADOW) {
200     if (la->type == LA_SUN) {
201       EEVEE_shadows_cascade_add(linfo, evli, ob);
202     }
203     else if (ELEM(la->type, LA_SPOT, LA_LOCAL, LA_AREA)) {
204       EEVEE_shadows_cube_add(linfo, evli, ob);
205     }
206   }
207
208   linfo->num_light++;
209 }
210
211 void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
212 {
213   EEVEE_LightsInfo *linfo = sldata->lights;
214
215   sldata->common_data.la_num_light = linfo->num_light;
216
217   DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data);
218 }