Cleanup: Nuke most of G.main from GPU code.
[blender.git] / source / blender / gpu / intern / gpu_material.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Brecht Van Lommel.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/gpu/intern/gpu_material.c
29  *  \ingroup gpu
30  *
31  * Manages materials, lights and textures.
32  */
33
34 #include <math.h>
35 #include <string.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_lamp_types.h"
40 #include "DNA_material_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_world_types.h"
44
45 #include "BLI_math.h"
46 #include "BLI_blenlib.h"
47 #include "BLI_utildefines.h"
48
49 #include "BKE_anim.h"
50 #include "BKE_colorband.h"
51 #include "BKE_colortools.h"
52 #include "BKE_global.h"
53 #include "BKE_image.h"
54 #include "BKE_main.h"
55 #include "BKE_node.h"
56 #include "BKE_scene.h"
57 #include "BKE_group.h"
58
59 #include "IMB_imbuf_types.h"
60
61 #include "GPU_extensions.h"
62 #include "GPU_framebuffer.h"
63 #include "GPU_material.h"
64 #include "GPU_shader.h"
65 #include "GPU_texture.h"
66
67 #include "gpu_codegen.h"
68
69 #ifdef WITH_OPENSUBDIV
70 #  include "BKE_DerivedMesh.h"
71 #endif
72
73 /* Structs */
74
75 typedef enum DynMatProperty {
76         DYN_LAMP_CO = 1,
77         DYN_LAMP_VEC = 2,
78         DYN_LAMP_IMAT = 4,
79         DYN_LAMP_PERSMAT = 8,
80 } DynMatProperty;
81
82 static struct GPUWorld {
83         float mistenabled;
84         float mistype;
85         float miststart;
86         float mistdistance;
87         float mistintensity;
88         float mistcol[4];
89         float horicol[3];
90         float ambcol[4];
91         float zencol[3];
92 } GPUWorld;
93
94 struct GPUMaterial {
95         Scene *scene;
96         Material *ma;
97
98         /* material for mesh surface, worlds or something else.
99          * some code generation is done differently depending on the use case */
100         int type;
101
102         /* for creating the material */
103         ListBase nodes;
104         GPUNodeLink *outlink;
105
106         /* for binding the material */
107         GPUPass *pass;
108         GPUVertexAttribs attribs;
109         int builtins;
110         int alpha, obcolalpha;
111         int dynproperty;
112
113         /* for passing uniforms */
114         int viewmatloc, invviewmatloc;
115         int obmatloc, invobmatloc;
116         int localtoviewmatloc, invlocaltoviewmatloc;
117         int obcolloc, obautobumpscaleloc;
118         int cameratexcofacloc;
119
120         int partscalarpropsloc;
121         int partcoloc;
122         int partvel;
123         int partangvel;
124
125         int objectinfoloc;
126
127         ListBase lamps;
128         bool bound;
129
130         bool is_opensubdiv;
131 };
132
133 struct GPULamp {
134         Scene *scene;
135         Object *ob;
136         Object *par;
137         Lamp *la;
138
139         int type, mode, lay, hide;
140
141         float dynenergy, dyncol[3];
142         float energy, col[3];
143
144         float co[3], vec[3];
145         float dynco[3], dynvec[3];
146         float obmat[4][4];
147         float imat[4][4];
148         float dynimat[4][4];
149
150         float spotsi, spotbl, k;
151         float spotvec[2];
152         float dyndist, dynatt1, dynatt2;
153         float dist, att1, att2;
154         float coeff_const, coeff_lin, coeff_quad;
155         float shadow_color[3];
156
157         float bias, d, clipend;
158         int size;
159
160         int falloff_type;
161         struct CurveMapping *curfalloff;
162
163         float winmat[4][4];
164         float viewmat[4][4];
165         float persmat[4][4];
166         float dynpersmat[4][4];
167
168         GPUFrameBuffer *fb;
169         GPUFrameBuffer *blurfb;
170         GPUTexture *tex;
171         GPUTexture *depthtex;
172         GPUTexture *blurtex;
173
174         ListBase materials;
175 };
176
177 /* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
178 static void texture_rgb_blend(
179         GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
180         int blendtype, GPUNodeLink **in);
181
182 /* Functions */
183
184 static GPUMaterial *GPU_material_construct_begin(Material *ma)
185 {
186         GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
187
188         material->ma = ma;
189
190         return material;
191 }
192
193 static void gpu_material_set_attrib_id(GPUMaterial *material)
194 {
195         GPUVertexAttribs *attribs = &material->attribs;
196         GPUPass *pass = material->pass;
197         if (!pass) {
198                 attribs->totlayer = 0;
199                 return;
200         }
201
202         GPUShader *shader = GPU_pass_shader(pass);
203         if (!shader) {
204                 attribs->totlayer = 0;
205                 return;
206         }
207
208         /* convert from attribute number to the actual id assigned by opengl,
209          * in case the attrib does not get a valid index back, it was probably
210          * removed by the glsl compiler by dead code elimination */
211
212         int b = 0;
213         for (int a = 0; a < attribs->totlayer; a++) {
214                 char name[32];
215                 BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid);
216                 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
217
218                 BLI_snprintf(name, sizeof(name), "att%d_info", attribs->layer[a].attribid);
219                 attribs->layer[a].glinfoindoex = GPU_shader_get_uniform(shader, name);
220
221                 if (attribs->layer[a].glindex >= 0) {
222                         attribs->layer[b] = attribs->layer[a];
223                         b++;
224                 }
225         }
226
227         attribs->totlayer = b;
228 }
229
230 static int gpu_material_construct_end(GPUMaterial *material, const char *passname)
231 {
232         if (material->outlink) {
233                 GPUNodeLink *outlink = material->outlink;
234                 material->pass = GPU_generate_pass(&material->nodes, outlink,
235                         &material->attribs, &material->builtins, material->type,
236                         passname,
237                         material->is_opensubdiv,
238                         GPU_material_use_new_shading_nodes(material));
239
240                 if (!material->pass)
241                         return 0;
242
243                 gpu_material_set_attrib_id(material);
244
245                 GPUShader *shader = GPU_pass_shader(material->pass);
246
247                 if (material->builtins & GPU_VIEW_MATRIX)
248                         material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX));
249                 if (material->builtins & GPU_INVERSE_VIEW_MATRIX)
250                         material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX));
251                 if (material->builtins & GPU_OBJECT_MATRIX)
252                         material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
253                 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX)
254                         material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
255                 if (material->builtins & GPU_LOC_TO_VIEW_MATRIX)
256                         material->localtoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_LOC_TO_VIEW_MATRIX));
257                 if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX)
258                         material->invlocaltoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_LOC_TO_VIEW_MATRIX));
259                 if (material->builtins & GPU_OBCOLOR)
260                         material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
261                 if (material->builtins & GPU_AUTO_BUMPSCALE)
262                         material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
263                 if (material->builtins & GPU_CAMERA_TEXCO_FACTORS)
264                         material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS));
265                 if (material->builtins & GPU_PARTICLE_SCALAR_PROPS)
266                         material->partscalarpropsloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_SCALAR_PROPS));
267                 if (material->builtins & GPU_PARTICLE_LOCATION)
268                         material->partcoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_LOCATION));
269                 if (material->builtins & GPU_PARTICLE_VELOCITY)
270                         material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY));
271                 if (material->builtins & GPU_PARTICLE_ANG_VELOCITY)
272                         material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY));
273                 if (material->builtins & GPU_OBJECT_INFO)
274                         material->objectinfoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_INFO));
275                 return 1;
276         }
277         else {
278                 GPU_pass_free_nodes(&material->nodes);
279         }
280
281         return 0;
282 }
283
284 void GPU_material_free(ListBase *gpumaterial)
285 {
286         for (LinkData *link = gpumaterial->first; link; link = link->next) {
287                 GPUMaterial *material = link->data;
288
289                 if (material->pass)
290                         GPU_pass_free(material->pass);
291
292                 for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) {
293                         GPULamp *lamp = nlink->data;
294
295                         if (material->ma) {
296                                 Material *ma = material->ma;
297
298                                 LinkData *next = NULL;
299                                 for (LinkData *mlink = lamp->materials.first; mlink; mlink = next) {
300                                         next = mlink->next;
301                                         if (mlink->data == ma)
302                                                 BLI_freelinkN(&lamp->materials, mlink);
303                                 }
304                         }
305                 }
306
307                 BLI_freelistN(&material->lamps);
308
309                 MEM_freeN(material);
310         }
311
312         BLI_freelistN(gpumaterial);
313 }
314
315 bool GPU_lamp_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
316 {
317         if (lamp->hide)
318                 return false;
319         else if (srl && srl->light_override)
320                 return BKE_group_object_exists(srl->light_override, lamp->ob);
321         else if (ma && ma->group)
322                 return BKE_group_object_exists(ma->group, lamp->ob);
323         else
324                 return true;
325 }
326
327 void GPU_material_bind(
328         GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
329         float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
330 {
331         if (material->pass) {
332                 GPUShader *shader = GPU_pass_shader(material->pass);
333                 SceneRenderLayer *srl = scenelock ? BLI_findlink(&material->scene->r.layers, material->scene->r.actlay) : NULL;
334
335                 if (srl)
336                         viewlay &= srl->lay;
337
338                 /* handle layer lamps */
339                 if (material->type == GPU_MATERIAL_TYPE_MESH) {
340                         for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) {
341                                 GPULamp *lamp = nlink->data;
342
343                                 if ((lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) &&
344                                     GPU_lamp_visible(lamp, srl, material->ma))
345                                 {
346                                         lamp->dynenergy = lamp->energy;
347                                         copy_v3_v3(lamp->dyncol, lamp->col);
348                                 }
349                                 else {
350                                         lamp->dynenergy = 0.0f;
351                                         lamp->dyncol[0] = lamp->dyncol[1] = lamp->dyncol[2] = 0.0f;
352                                 }
353
354                                 if (material->dynproperty & DYN_LAMP_VEC) {
355                                         copy_v3_v3(lamp->dynvec, lamp->vec);
356                                         normalize_v3(lamp->dynvec);
357                                         negate_v3(lamp->dynvec);
358                                         mul_mat3_m4_v3(viewmat, lamp->dynvec);
359                                 }
360
361                                 if (material->dynproperty & DYN_LAMP_CO) {
362                                         copy_v3_v3(lamp->dynco, lamp->co);
363                                         mul_m4_v3(viewmat, lamp->dynco);
364                                 }
365
366                                 if (material->dynproperty & DYN_LAMP_IMAT) {
367                                         mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
368                                 }
369
370                                 if (material->dynproperty & DYN_LAMP_PERSMAT) {
371                                         /* The lamp matrices are already updated if we're using shadow buffers */
372                                         if (!GPU_lamp_has_shadow_buffer(lamp)) {
373                                                 GPU_lamp_update_buffer_mats(lamp);
374                                         }
375                                         mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
376                                 }
377                         }
378                 }
379
380                 /* note material must be bound before setting uniforms */
381                 GPU_pass_bind(material->pass, time, mipmap);
382
383                 /* handle per material built-ins */
384                 if (material->builtins & GPU_VIEW_MATRIX) {
385                         GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float *)viewmat);
386                 }
387                 if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
388                         GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float *)viewinv);
389                 }
390                 if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) {
391                         if (camerafactors) {
392                                 GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float *)camerafactors);
393                         }
394                         else {
395                                 /* use default, no scaling no offset */
396                                 float borders[4] = {1.0f, 1.0f, 0.0f, 0.0f};
397                                 GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float *)borders);
398                         }
399                 }
400
401                 GPU_pass_update_uniforms(material->pass);
402
403                 material->bound = 1;
404         }
405 }
406
407 GPUBuiltin GPU_get_material_builtins(GPUMaterial *material)
408 {
409         return material->builtins;
410 }
411
412 void GPU_material_bind_uniforms(
413         GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
414         float autobumpscale, GPUParticleInfo *pi, float object_info[3])
415 {
416         if (material->pass) {
417                 GPUShader *shader = GPU_pass_shader(material->pass);
418                 float invmat[4][4], col[4];
419                 float localtoviewmat[4][4];
420                 float invlocaltoviewmat[4][4];
421
422                 /* handle per object builtins */
423                 if (material->builtins & GPU_OBJECT_MATRIX) {
424                         GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float *)obmat);
425                 }
426                 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
427                         invert_m4_m4(invmat, obmat);
428                         GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float *)invmat);
429                 }
430                 if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) {
431                         if (viewmat) {
432                                 mul_m4_m4m4(localtoviewmat, viewmat, obmat);
433                                 GPU_shader_uniform_vector(shader, material->localtoviewmatloc, 16, 1, (float *)localtoviewmat);
434                         }
435                 }
436                 if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
437                         if (viewmat) {
438                                 mul_m4_m4m4(localtoviewmat, viewmat, obmat);
439                                 invert_m4_m4(invlocaltoviewmat, localtoviewmat);
440                                 GPU_shader_uniform_vector(shader, material->invlocaltoviewmatloc, 16, 1, (float *)invlocaltoviewmat);
441                         }
442                 }
443                 if (material->builtins & GPU_OBCOLOR) {
444                         copy_v4_v4(col, obcol);
445                         CLAMP(col[3], 0.0f, 1.0f);
446                         GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
447                 }
448                 if (material->builtins & GPU_AUTO_BUMPSCALE) {
449                         GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
450                 }
451                 if (material->builtins & GPU_PARTICLE_SCALAR_PROPS) {
452                         GPU_shader_uniform_vector(shader, material->partscalarpropsloc, 4, 1, pi->scalprops);
453                 }
454                 if (material->builtins & GPU_PARTICLE_LOCATION) {
455                         GPU_shader_uniform_vector(shader, material->partcoloc, 4, 1, pi->location);
456                 }
457                 if (material->builtins & GPU_PARTICLE_VELOCITY) {
458                         GPU_shader_uniform_vector(shader, material->partvel, 3, 1, pi->velocity);
459                 }
460                 if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) {
461                         GPU_shader_uniform_vector(shader, material->partangvel, 3, 1, pi->angular_velocity);
462                 }
463                 if (material->builtins & GPU_OBJECT_INFO) {
464                         GPU_shader_uniform_vector(shader, material->objectinfoloc, 3, 1, object_info);
465                 }
466
467         }
468 }
469
470 void GPU_material_unbind(GPUMaterial *material)
471 {
472         if (material->pass) {
473                 material->bound = 0;
474                 GPU_pass_unbind(material->pass);
475         }
476 }
477
478 bool GPU_material_bound(GPUMaterial *material)
479 {
480         return material->bound;
481 }
482
483 Scene *GPU_material_scene(GPUMaterial *material)
484 {
485         return material->scene;
486 }
487
488 GPUMatType GPU_Material_get_type(GPUMaterial *material)
489 {
490         return material->type;
491 }
492
493
494 void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
495 {
496         *attribs = material->attribs;
497 }
498
499 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
500 {
501         if (!material->outlink)
502                 material->outlink = link;
503 }
504
505 void GPU_material_enable_alpha(GPUMaterial *material)
506 {
507         material->alpha = 1;
508 }
509
510 GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4])
511 {
512         if (material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
513                 return GPU_BLEND_ALPHA;
514         else
515                 return GPU_BLEND_SOLID;
516 }
517
518 void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
519 {
520         BLI_addtail(&material->nodes, node);
521 }
522
523 /* Code generation */
524
525 bool GPU_material_do_color_management(GPUMaterial *mat)
526 {
527         if (!BKE_scene_check_color_management_enabled(mat->scene))
528                 return false;
529
530         return true;
531 }
532
533 bool GPU_material_use_new_shading_nodes(GPUMaterial *mat)
534 {
535         return BKE_scene_use_new_shading_nodes(mat->scene);
536 }
537
538 bool GPU_material_use_world_space_shading(GPUMaterial *mat)
539 {
540         return BKE_scene_use_world_space_shading(mat->scene);
541 }
542
543 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
544 {
545         GPUNodeLink *visifac;
546
547         /* from get_lamp_visibility */
548         if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
549                 mat->dynproperty |= DYN_LAMP_VEC;
550                 GPU_link(mat, "lamp_visibility_sun_hemi",
551                          GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
552                 return visifac;
553         }
554         else {
555                 mat->dynproperty |= DYN_LAMP_CO;
556                 GPU_link(mat, "lamp_visibility_other",
557                          GPU_builtin(GPU_VIEW_POSITION),
558                          GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac);
559
560                 if (lamp->type == LA_AREA)
561                         return visifac;
562
563                 switch (lamp->falloff_type) {
564                         case LA_FALLOFF_CONSTANT:
565                                 break;
566                         case LA_FALLOFF_INVLINEAR:
567                                 GPU_link(mat, "lamp_falloff_invlinear",
568                                          GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
569                                 break;
570                         case LA_FALLOFF_INVSQUARE:
571                                 GPU_link(mat, "lamp_falloff_invsquare",
572                                          GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
573                                 break;
574                         case LA_FALLOFF_SLIDERS:
575                                 GPU_link(mat, "lamp_falloff_sliders",
576                                          GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
577                                          GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob),
578                                          GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
579                                 break;
580                         case LA_FALLOFF_INVCOEFFICIENTS:
581                                 GPU_link(mat, "lamp_falloff_invcoefficients",
582                                              GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob),
583                                              GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob),
584                                              GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac);
585                                 break;
586                         case LA_FALLOFF_CURVE:
587                         {
588                                 float *array;
589                                 int size;
590
591                                 curvemapping_initialize(lamp->curfalloff);
592                                 curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
593                                 GPU_link(mat, "lamp_falloff_curve",
594                                          GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
595                                          GPU_texture(size, array), *dist, &visifac);
596
597                                 break;
598                         }
599                 }
600
601                 if (lamp->mode & LA_SPHERE)
602                         GPU_link(mat, "lamp_visibility_sphere",
603                                  GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
604                                  *dist, visifac, &visifac);
605
606                 if (lamp->type == LA_SPOT) {
607                         GPUNodeLink *inpr;
608
609                         if (lamp->mode & LA_SQUARE) {
610                                 mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
611                                 GPU_link(mat, "lamp_visibility_spot_square",
612                                          GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
613                                          GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
614                                 GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
615                         }
616                         else {
617                                 mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
618                                 GPU_link(mat, "lamp_visibility_spot_circle",
619                                          GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
620                                 GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
621                                 GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
622                         }
623
624                         GPU_link(mat, "lamp_visibility_spot",
625                                  GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
626                                  GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTBLEND, lamp->ob),
627                                  inpr, visifac, &visifac);
628                 }
629
630                 GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
631
632                 return visifac;
633         }
634 }
635
636 #if 0
637 static void area_lamp_vectors(LampRen *lar)
638 {
639         float xsize = 0.5f * lar->area_size, ysize = 0.5f * lar->area_sizey;
640
641         /* make it smaller, so area light can be multisampled */
642         float multifac = 1.0f / sqrtf((float)lar->ray_totsamp);
643         xsize *= multifac;
644         ysize *= multifac;
645
646         /* corner vectors */
647         lar->area[0][0] = lar->co[0] - xsize * lar->mat[0][0] - ysize * lar->mat[1][0];
648         lar->area[0][1] = lar->co[1] - xsize * lar->mat[0][1] - ysize * lar->mat[1][1];
649         lar->area[0][2] = lar->co[2] - xsize * lar->mat[0][2] - ysize * lar->mat[1][2];
650
651         /* corner vectors */
652         lar->area[1][0] = lar->co[0] - xsize * lar->mat[0][0] + ysize * lar->mat[1][0];
653         lar->area[1][1] = lar->co[1] - xsize * lar->mat[0][1] + ysize * lar->mat[1][1];
654         lar->area[1][2] = lar->co[2] - xsize * lar->mat[0][2] + ysize * lar->mat[1][2];
655
656         /* corner vectors */
657         lar->area[2][0] = lar->co[0] + xsize * lar->mat[0][0] + ysize * lar->mat[1][0];
658         lar->area[2][1] = lar->co[1] + xsize * lar->mat[0][1] + ysize * lar->mat[1][1];
659         lar->area[2][2] = lar->co[2] + xsize * lar->mat[0][2] + ysize * lar->mat[1][2];
660
661         /* corner vectors */
662         lar->area[3][0] = lar->co[0] + xsize * lar->mat[0][0] - ysize * lar->mat[1][0];
663         lar->area[3][1] = lar->co[1] + xsize * lar->mat[0][1] - ysize * lar->mat[1][1];
664         lar->area[3][2] = lar->co[2] + xsize * lar->mat[0][2] - ysize * lar->mat[1][2];
665         /* only for correction button size, matrix size works on energy */
666         lar->areasize = lar->dist * lar->dist / (4.0f * xsize * ysize);
667 }
668 #endif
669
670 static void ramp_blend(
671         GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type,
672         GPUNodeLink **r_col)
673 {
674         static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
675                 "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
676                 "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
677                 "mix_val", "mix_color", "mix_soft", "mix_linear"};
678
679         GPU_link(mat, names[type], fac, col1, col2, r_col);
680 }
681
682 static void BKE_colorband_eval_blend(
683         GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type,
684         GPUNodeLink *incol, GPUNodeLink **r_col)
685 {
686         GPUNodeLink *tmp, *alpha, *col;
687         float *array;
688         int size;
689
690         /* do colorband */
691         BKE_colorband_evaluate_table_rgba(coba, &array, &size);
692         GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
693
694         /* use alpha in fac */
695         GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
696         GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
697
698         /* blending method */
699         ramp_blend(mat, fac, incol, col, type, r_col);
700 }
701
702 static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
703 {
704         Material *ma = shi->mat;
705         GPUMaterial *mat = shi->gpumat;
706
707         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS)) {
708                 if (ma->ramp_col) {
709                         if (ma->rampin_col == MA_RAMP_IN_RESULT) {
710                                 GPUNodeLink *fac;
711                                 GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
712
713                                 /* colorband + blend */
714                                 BKE_colorband_eval_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
715                         }
716                 }
717         }
718 }
719
720 static void add_to_diffuse(
721         GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb,
722         GPUNodeLink **r_diff)
723 {
724         GPUNodeLink *fac, *tmp, *addcol;
725
726         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
727             ma->ramp_col && (ma->mode & MA_RAMP_COL))
728         {
729                 /* MA_RAMP_IN_RESULT is exceptional */
730                 if (ma->rampin_col == MA_RAMP_IN_RESULT) {
731                         addcol = shi->rgb;
732                 }
733                 else {
734                         /* input */
735                         switch (ma->rampin_col) {
736                                 case MA_RAMP_IN_ENERGY:
737                                         GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
738                                         break;
739                                 case MA_RAMP_IN_SHADER:
740                                         fac = is;
741                                         break;
742                                 case MA_RAMP_IN_NOR:
743                                         GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
744                                         break;
745                                 default:
746                                         GPU_link(mat, "set_value_zero", &fac);
747                                         break;
748                         }
749
750                         /* colorband + blend */
751                         BKE_colorband_eval_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
752                 }
753         }
754         else
755                 addcol = shi->rgb;
756
757         /* output to */
758         GPU_link(mat, "shade_madd", *r_diff, rgb, addcol, r_diff);
759 }
760
761 static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
762 {
763         Material *ma = shi->mat;
764         GPUMaterial *mat = shi->gpumat;
765
766         if (!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) &&
767             ma->ramp_spec && ma->rampin_spec == MA_RAMP_IN_RESULT)
768         {
769                 GPUNodeLink *fac;
770                 GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
771
772                 /* colorband + blend */
773                 BKE_colorband_eval_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
774         }
775 }
776
777 static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
778 {
779         Material *ma = shi->mat;
780         GPUMaterial *mat = shi->gpumat;
781         GPUNodeLink *fac, *tmp;
782
783         *spec = shi->specrgb;
784
785         /* MA_RAMP_IN_RESULT is exception */
786         if (ma->ramp_spec && (ma->rampin_spec != MA_RAMP_IN_RESULT)) {
787
788                 /* input */
789                 switch (ma->rampin_spec) {
790                         case MA_RAMP_IN_ENERGY:
791                                 fac = t;
792                                 break;
793                         case MA_RAMP_IN_SHADER:
794                                 fac = is;
795                                 break;
796                         case MA_RAMP_IN_NOR:
797                                 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
798                                 break;
799                         default:
800                                 GPU_link(mat, "set_value_zero", &fac);
801                                 break;
802                 }
803
804                 /* colorband + blend */
805                 BKE_colorband_eval_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
806         }
807 }
808
809 static void add_user_list(ListBase *list, void *data)
810 {
811         LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData");
812         link->data = data;
813         BLI_addtail(list, link);
814 }
815
816 static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **rgb)
817 {
818         for (int i = 0; i < MAX_MTEX; ++i) {
819                 MTex *mtex = lamp->la->mtex[i];
820
821                 if (mtex && mtex->tex && (mtex->tex->type & TEX_IMAGE) && mtex->tex->ima) {
822                         mat->dynproperty |= DYN_LAMP_PERSMAT;
823
824                         float one = 1.0f;
825                         GPUNodeLink *tex_rgb;
826
827                         GPU_link(mat, "shade_light_texture",
828                                  GPU_builtin(GPU_VIEW_POSITION),
829                                  GPU_image(mtex->tex->ima, &mtex->tex->iuser, false),
830                                  GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
831                                  &tex_rgb);
832                         texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb);
833                 }
834         }
835 }
836
837 static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
838 {
839         Material *ma = shi->mat;
840         GPUMaterial *mat = shi->gpumat;
841         GPUNodeLink *lv, *dist, *is, *inp, *i;
842         GPUNodeLink *outcol, *specfac, *t, *shadfac = NULL, *lcol;
843         float one = 1.0f;
844
845         if ((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
846                 return;
847
848         GPUNodeLink *vn = shi->vn;
849         GPUNodeLink *view = shi->view;
850
851         GPUNodeLink *visifac = lamp_get_visibility(mat, lamp, &lv, &dist);
852
853 #if 0
854         if (ma->mode & MA_TANGENT_V)
855                 GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);
856 #endif
857
858         GPU_link(mat, "shade_inp", vn, lv, &inp);
859
860         if (lamp->mode & LA_NO_DIFF) {
861                 GPU_link(mat, "shade_is_no_diffuse", &is);
862         }
863         else if (lamp->type == LA_HEMI) {
864                 GPU_link(mat, "shade_is_hemi", inp, &is);
865         }
866         else {
867                 if (lamp->type == LA_AREA) {
868                         float area[4][4] = {{0.0f}}, areasize = 0.0f;
869
870                         mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_CO;
871                         GPU_link(mat, "shade_inp_area",
872                                  GPU_builtin(GPU_VIEW_POSITION),
873                                  GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob),
874                                  GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn,
875                                  GPU_uniform((float *)area),
876                                  GPU_uniform(&areasize),
877                                  GPU_uniform(&lamp->k), &inp);
878                 }
879
880                 is = inp; /* Lambert */
881
882                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) {
883                         if (ma->diff_shader == MA_DIFF_ORENNAYAR)
884                                 GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view,
885                                          GPU_uniform(&ma->roughness), &is);
886                         else if (ma->diff_shader == MA_DIFF_TOON)
887                                 GPU_link(mat, "shade_diffuse_toon", vn, lv, view,
888                                          GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
889                         else if (ma->diff_shader == MA_DIFF_MINNAERT)
890                                 GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view,
891                                          GPU_uniform(&ma->darkness), &is);
892                         else if (ma->diff_shader == MA_DIFF_FRESNEL)
893                                 GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view,
894                                          GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
895                 }
896         }
897
898         if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS))
899                 if (ma->shade_flag & MA_CUBIC)
900                         GPU_link(mat, "shade_cubic", is, &is);
901
902         i = is;
903         GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
904
905         GPU_link(mat, "set_rgb", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
906         shade_light_textures(mat, lamp, &lcol);
907         GPU_link(mat, "shade_mul_value_v3",
908                  GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), lcol, &lcol);
909
910 #if 0
911         if (ma->mode & MA_TANGENT_VN)
912                 GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);
913 #endif
914
915         /* this replaces if (i > 0.0) conditional until that is supported */
916         /* done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i); */
917
918         if ((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) {
919                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) {
920                         mat->dynproperty |= DYN_LAMP_PERSMAT;
921
922                         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
923                                 GPU_link(mat, "test_shadowbuf_vsm",
924                                          GPU_builtin(GPU_VIEW_POSITION),
925                                          GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
926                                          GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
927                                          GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac);
928                         }
929                         else {
930                                 GPU_link(mat, "test_shadowbuf",
931                                          GPU_builtin(GPU_VIEW_POSITION),
932                                          GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
933                                          GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
934                                          GPU_uniform(&lamp->bias), inp, &shadfac);
935                         }
936
937                         if (lamp->mode & LA_ONLYSHADOW) {
938                                 GPUNodeLink *shadrgb;
939                                 GPU_link(mat, "shade_only_shadow", i, shadfac,
940                                         GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob),
941                                         GPU_uniform(lamp->shadow_color), &shadrgb);
942
943                                 if (!(lamp->mode & LA_NO_DIFF)) {
944                                         GPU_link(mat, "shade_only_shadow_diffuse", shadrgb, shi->rgb,
945                                                  shr->diff, &shr->diff);
946                                 }
947
948                                 if (!(lamp->mode & LA_NO_SPEC)) {
949                                         GPU_link(mat, "shade_only_shadow_specular", shadrgb, shi->specrgb,
950                                                  shr->spec, &shr->spec);
951                                 }
952
953                                 add_user_list(&mat->lamps, lamp);
954                                 add_user_list(&lamp->materials, shi->gpumat->ma);
955                                 return;
956                         }
957                 }
958         }
959         else if ((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
960                 add_user_list(&mat->lamps, lamp);
961                 add_user_list(&lamp->materials, shi->gpumat->ma);
962                 return;
963         }
964         else
965                 GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
966
967         if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
968                 if (!(lamp->mode & LA_NO_DIFF)) {
969                         GPUNodeLink *rgb;
970                         GPU_link(mat, "shade_mul_value", i, lcol, &rgb);
971                         GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
972                         GPU_link(mat, "mix_mult",  shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb);
973                         GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
974                         add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
975                 }
976         }
977
978         if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS) {
979                 /* pass */
980         }
981         else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
982                  (GPU_link_changed(shi->spec) || ma->spec != 0.0f))
983         {
984                 if (lamp->type == LA_HEMI) {
985                         GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
986                         GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
987                         GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
988                 }
989                 else {
990                         if (ma->spec_shader == MA_SPEC_PHONG) {
991                                 GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac);
992                         }
993                         else if (ma->spec_shader == MA_SPEC_COOKTORR) {
994                                 GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac);
995                         }
996                         else if (ma->spec_shader == MA_SPEC_BLINN) {
997                                 GPU_link(mat, "shade_blinn_spec", vn, lv, view,
998                                          GPU_uniform(&ma->refrac), shi->har, &specfac);
999                         }
1000                         else if (ma->spec_shader == MA_SPEC_WARDISO) {
1001                                 GPU_link(mat, "shade_wardiso_spec", vn, lv, view,
1002                                          GPU_uniform(&ma->rms), &specfac);
1003                         }
1004                         else {
1005                                 GPU_link(mat, "shade_toon_spec", vn, lv, view,
1006                                          GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
1007                         }
1008
1009                         if (lamp->type == LA_AREA)
1010                                 GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
1011
1012                         GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t);
1013
1014                         if (ma->mode & MA_RAMP_SPEC) {
1015                                 GPUNodeLink *spec;
1016                                 do_specular_ramp(shi, specfac, t, &spec);
1017                                 GPU_link(mat, "shade_add_spec", t, lcol, spec, &outcol);
1018                                 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
1019                         }
1020                         else {
1021                                 GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
1022                                 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
1023                         }
1024                 }
1025         }
1026
1027         add_user_list(&mat->lamps, lamp);
1028         add_user_list(&lamp->materials, shi->gpumat->ma);
1029 }
1030
1031 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
1032 {
1033         Base *base;
1034         Scene *sce_iter;
1035
1036         for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
1037                 Object *ob = base->object;
1038
1039                 if (ob->type == OB_LAMP) {
1040                         GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
1041                         if (lamp)
1042                                 shade_one_light(shi, shr, lamp);
1043                 }
1044
1045                 if (ob->transflag & OB_DUPLI) {
1046                         ListBase *lb = object_duplilist(G.main, G.main->eval_ctx, shi->gpumat->scene, ob);
1047
1048                         for (DupliObject *dob = lb->first; dob; dob = dob->next) {
1049                                 Object *ob_iter = dob->ob;
1050
1051                                 if (ob_iter->type == OB_LAMP) {
1052                                         float omat[4][4];
1053                                         copy_m4_m4(omat, ob_iter->obmat);
1054                                         copy_m4_m4(ob_iter->obmat, dob->mat);
1055
1056                                         GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
1057                                         if (lamp)
1058                                                 shade_one_light(shi, shr, lamp);
1059
1060                                         copy_m4_m4(ob_iter->obmat, omat);
1061                                 }
1062                         }
1063
1064                         free_object_duplilist(lb);
1065                 }
1066         }
1067
1068         /* prevent only shadow lamps from producing negative colors.*/
1069         GPU_link(shi->gpumat, "shade_clamp_positive", shr->spec, &shr->spec);
1070         GPU_link(shi->gpumat, "shade_clamp_positive", shr->diff, &shr->diff);
1071 }
1072
1073 static void texture_rgb_blend(
1074         GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
1075         int blendtype, GPUNodeLink **in)
1076 {
1077         switch (blendtype) {
1078                 case MTEX_BLEND:
1079                         GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in);
1080                         break;
1081                 case MTEX_MUL:
1082                         GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in);
1083                         break;
1084                 case MTEX_SCREEN:
1085                         GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in);
1086                         break;
1087                 case MTEX_OVERLAY:
1088                         GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in);
1089                         break;
1090                 case MTEX_SUB:
1091                         GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in);
1092                         break;
1093                 case MTEX_ADD:
1094                         GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in);
1095                         break;
1096                 case MTEX_DIV:
1097                         GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in);
1098                         break;
1099                 case MTEX_DIFF:
1100                         GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in);
1101                         break;
1102                 case MTEX_DARK:
1103                         GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in);
1104                         break;
1105                 case MTEX_LIGHT:
1106                         GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in);
1107                         break;
1108                 case MTEX_BLEND_HUE:
1109                         GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in);
1110                         break;
1111                 case MTEX_BLEND_SAT:
1112                         GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in);
1113                         break;
1114                 case MTEX_BLEND_VAL:
1115                         GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in);
1116                         break;
1117                 case MTEX_BLEND_COLOR:
1118                         GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
1119                         break;
1120                 case MTEX_SOFT_LIGHT:
1121                         GPU_link(mat, "mtex_rgb_soft", out, tex, fact, facg, in);
1122                         break;
1123                 case MTEX_LIN_LIGHT:
1124                         GPU_link(mat, "mtex_rgb_linear", out, tex, fact, facg, in);
1125                         break;
1126                 default:
1127                         GPU_link(mat, "set_rgb_zero", &in);
1128                         break;
1129         }
1130 }
1131
1132 static void texture_value_blend(
1133         GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
1134         int blendtype, GPUNodeLink **in)
1135 {
1136         switch (blendtype) {
1137                 case MTEX_BLEND:
1138                         GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in);
1139                         break;
1140                 case MTEX_MUL:
1141                         GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in);
1142                         break;
1143                 case MTEX_SCREEN:
1144                         GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in);
1145                         break;
1146                 case MTEX_SUB:
1147                         GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in);
1148                         break;
1149                 case MTEX_ADD:
1150                         GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in);
1151                         break;
1152                 case MTEX_DIV:
1153                         GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in);
1154                         break;
1155                 case MTEX_DIFF:
1156                         GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in);
1157                         break;
1158                 case MTEX_DARK:
1159                         GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in);
1160                         break;
1161                 case MTEX_LIGHT:
1162                         GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in);
1163                         break;
1164                 default:
1165                         GPU_link(mat, "set_value_zero", &in);
1166                         break;
1167         }
1168 }
1169
1170 static void do_material_tex(GPUShadeInput *shi)
1171 {
1172         Material *ma = shi->mat;
1173         GPUMaterial *mat = shi->gpumat;
1174         MTex *mtex;
1175         Tex *tex;
1176         GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
1177         GPUNodeLink *texco_norm, *texco_orco, *texco_object;
1178         GPUNodeLink *texco_global, *texco_uv = NULL;
1179         GPUNodeLink *newnor, *orn;
1180         float one = 1.0f;
1181         int rgbnor, talpha;
1182         bool init_done = false;
1183         int iBumpSpacePrev = 0; /* Not necessary, quieting gcc warning. */
1184         GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude;
1185         int iFirstTimeNMap = 1;
1186         bool found_deriv_map = false;
1187
1188         GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
1189
1190         GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
1191         GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
1192         GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
1193                 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
1194                 GPU_builtin(GPU_VIEW_POSITION), &texco_object);
1195 #if 0
1196         GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
1197 #endif
1198         GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
1199                 GPU_builtin(GPU_VIEW_POSITION), &texco_global);
1200
1201         orn = texco_norm;
1202
1203         /* go over texture slots */
1204         for (int tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) {
1205                 /* separate tex switching */
1206                 if (ma->septex & (1 << tex_nr)) continue;
1207
1208                 if (ma->mtex[tex_nr]) {
1209                         mtex = ma->mtex[tex_nr];
1210
1211                         tex = mtex->tex;
1212                         if (tex == NULL) continue;
1213
1214                         /* which coords */
1215                         if (mtex->texco == TEXCO_ORCO)
1216                                 texco = texco_orco;
1217                         else if (mtex->texco == TEXCO_OBJECT)
1218                                 texco = texco_object;
1219                         else if (mtex->texco == TEXCO_NORM)
1220                                 texco = orn;
1221                         else if (mtex->texco == TEXCO_TANGENT)
1222                                 texco = texco_object;
1223                         else if (mtex->texco == TEXCO_GLOB)
1224                                 texco = texco_global;
1225                         else if (mtex->texco == TEXCO_REFL) {
1226                                 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1227                                 texco = shi->ref;
1228                         }
1229                         else if (mtex->texco == TEXCO_UV) {
1230                                 if (1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
1231                                         GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
1232                                         /*lastuvname = mtex->uvname;*/ /*UNUSED*/
1233                                 }
1234                                 texco = texco_uv;
1235                         }
1236                         else
1237                                 continue;
1238
1239                         /* in case of uv, this would just undo a multiplication in texco_uv */
1240                         if (mtex->texco != TEXCO_UV)
1241                                 GPU_link(mat, "mtex_2d_mapping", texco, &texco);
1242
1243                         if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
1244                                 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
1245
1246                         float ofs[3] = {
1247                                 mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0],
1248                                 mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1],
1249                                 0.0f
1250                         };
1251
1252                         if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
1253                                 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
1254
1255                         talpha = 0;
1256
1257                         if (tex && tex->ima &&
1258                             ((tex->type == TEX_IMAGE) ||
1259                              ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL))))
1260                         {
1261                                 if (tex->type == TEX_IMAGE) {
1262                                         GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
1263                                 }
1264                                 else {
1265                                         GPU_link(mat, "mtex_cube_map_refl",
1266                                                  GPU_cube_map(tex->ima, &tex->iuser, false), shi->view, shi->vn,
1267                                                  GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
1268                                                  GPU_builtin(GPU_VIEW_MATRIX), &tin, &trgb);
1269                                 }
1270                                 rgbnor = TEX_RGB;
1271
1272                                 talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0);
1273                         }
1274                         else {
1275                                 continue;
1276                         }
1277
1278                         /* texture output */
1279                         if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1280                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1281                                 rgbnor -= TEX_RGB;
1282                         }
1283
1284                         if (mtex->texflag & MTEX_NEGATIVE) {
1285                                 if (rgbnor & TEX_RGB)
1286                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
1287                                 else
1288                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
1289                         }
1290
1291                         if (mtex->texflag & MTEX_STENCIL) {
1292                                 if (rgbnor & TEX_RGB)
1293                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
1294                                 else
1295                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
1296                         }
1297
1298                         /* mapping */
1299                         if (mtex->mapto & (MAP_COL | MAP_COLSPEC | MAP_COLMIR)) {
1300                                 /* stencil maps on the texture control slider, not texture intensity value */
1301                                 if ((rgbnor & TEX_RGB) == 0) {
1302                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
1303                                 }
1304                                 else {
1305                                         GPU_link(mat, "set_rgba", trgb, &tcol);
1306
1307                                         if (mtex->mapto & MAP_ALPHA)
1308                                                 GPU_link(mat, "set_value", stencil, &tin);
1309                                         else if (talpha)
1310                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1311                                         else
1312                                                 GPU_link(mat, "set_value_one", &tin);
1313                                 }
1314
1315                                 if ((tex->type == TEX_IMAGE) ||
1316                                     ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL)))
1317                                 {
1318                                         if (GPU_material_do_color_management(mat)) {
1319                                                 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
1320                                         }
1321                                 }
1322
1323                                 if (mtex->mapto & MAP_COL) {
1324                                         GPUNodeLink *colfac;
1325
1326                                         if (mtex->colfac == 1.0f) colfac = stencil;
1327                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
1328
1329                                         texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
1330                                 }
1331
1332                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) {
1333                                         GPUNodeLink *colspecfac;
1334
1335                                         if (mtex->colspecfac == 1.0f) colspecfac = stencil;
1336                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
1337
1338                                         texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
1339                                 }
1340
1341                                 if (mtex->mapto & MAP_COLMIR) {
1342                                         GPUNodeLink *colmirfac;
1343
1344                                         if (mtex->mirrfac == 1.0f) colmirfac = stencil;
1345                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->mirrfac), stencil, &colmirfac);
1346
1347                                         /* exception for envmap only */
1348                                         if (tex->type == TEX_ENVMAP && mtex->blendtype == MTEX_BLEND) {
1349                                                 GPU_link(mat, "mtex_mirror", tcol, shi->refcol, tin, colmirfac, &shi->refcol);
1350                                         }
1351                                         else
1352                                                 texture_rgb_blend(mat, tcol, shi->mir, tin, colmirfac, mtex->blendtype, &shi->mir);
1353                                 }
1354                         }
1355
1356                         if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
1357                                 if (tex->type == TEX_IMAGE) {
1358                                         found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP;
1359
1360                                         if (tex->imaflag & TEX_NORMALMAP) {
1361                                                 /* normalmap image */
1362                                                 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor);
1363
1364                                                 if (mtex->norfac < 0.0f)
1365                                                         GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
1366
1367                                                 if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
1368                                                         if (iFirstTimeNMap != 0) {
1369                                                                 // use unnormalized normal (this is how we bake it - closer to gamedev)
1370                                                                 GPUNodeLink *vNegNorm;
1371                                                                 GPU_link(mat, "vec_math_negate",
1372                                                                          GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm);
1373                                                                 GPU_link(mat, "mtex_nspace_tangent",
1374                                                                          GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor);
1375                                                                 iFirstTimeNMap = 0;
1376                                                         }
1377                                                         else { /* otherwise use accumulated perturbations */
1378                                                                 GPU_link(mat, "mtex_nspace_tangent",
1379                                                                          GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
1380                                                         }
1381                                                 }
1382                                                 else if (mtex->normapspace == MTEX_NSPACE_OBJECT) {
1383                                                         /* transform normal by object then view matrix */
1384                                                         GPU_link(mat, "mtex_nspace_object", tnor, &newnor);
1385                                                 }
1386                                                 else if (mtex->normapspace == MTEX_NSPACE_WORLD) {
1387                                                         /* transform normal by view matrix */
1388                                                         GPU_link(mat, "mtex_nspace_world", GPU_builtin(GPU_VIEW_MATRIX), tnor, &newnor);
1389                                                 }
1390                                                 else {
1391                                                         /* no transform, normal in camera space */
1392                                                         newnor = tnor;
1393                                                 }
1394
1395                                                 float norfac = min_ff(fabsf(mtex->norfac), 1.0f);
1396
1397                                                 if (norfac == 1.0f && !GPU_link_changed(stencil)) {
1398                                                         shi->vn = newnor;
1399                                                 }
1400                                                 else {
1401                                                         tnorfac = GPU_uniform(&norfac);
1402
1403                                                         if (GPU_link_changed(stencil))
1404                                                                 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1405
1406                                                         GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
1407                                                 }
1408
1409                                         }
1410                                         else if (found_deriv_map ||
1411                                                  (mtex->texflag & (MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP)))
1412                                         {
1413                                                 /* ntap bumpmap image */
1414                                                 int iBumpSpace;
1415                                                 float ima_x, ima_y;
1416
1417                                                 float imag_tspace_dimension_x = 1024.0f; /* only used for texture space variant */
1418                                                 float aspect = 1.0f;
1419
1420                                                 GPUNodeLink *vR1, *vR2;
1421                                                 GPUNodeLink *dBs, *dBt, *fDet;
1422
1423                                                 float hScale = 0.1f; /* compatibility adjustment factor for all bumpspace types */
1424                                                 if (mtex->texflag & MTEX_BUMP_TEXTURESPACE)
1425                                                         hScale = 13.0f; /* factor for scaling texspace bumps */
1426                                                 else if (found_deriv_map)
1427                                                         hScale = 1.0f;
1428
1429                                                 /* resolve texture resolution */
1430                                                 if ((mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map) {
1431                                                         ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
1432                                                         ima_x = 512.0f; ima_y = 512.0f; /* prevent calling textureSize, glsl 1.3 only */
1433                                                         if (ibuf) {
1434                                                                 ima_x = ibuf->x;
1435                                                                 ima_y = ibuf->y;
1436                                                                 aspect = (float)ima_y / ima_x;
1437                                                         }
1438                                                         BKE_image_release_ibuf(tex->ima, ibuf, NULL);
1439                                                 }
1440
1441                                                 /* The negate on norfac is done because the
1442                                                  * normal in the renderer points inward which corresponds
1443                                                  * to inverting the bump map. Should this ever change
1444                                                  * this negate must be removed. */
1445                                                 float norfac = -hScale * mtex->norfac;
1446                                                 if (found_deriv_map) {
1447                                                         float fVirtDim = sqrtf(fabsf(ima_x * mtex->size[0] * ima_y * mtex->size[1]));
1448                                                         norfac /= MAX2(fVirtDim, FLT_EPSILON);
1449                                                 }
1450
1451                                                 tnorfac = GPU_uniform(&norfac);
1452
1453                                                 if (found_deriv_map)
1454                                                         GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac);
1455
1456                                                 if (GPU_link_changed(stencil))
1457                                                         GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
1458
1459                                                 if (!init_done) {
1460                                                         /* copy shi->vn to vNorg and vNacc, set magnitude to 1 */
1461                                                         GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
1462                                                         iBumpSpacePrev = 0;
1463                                                         init_done = true;
1464                                                 }
1465
1466                                                 // find current bump space
1467                                                 if (mtex->texflag & MTEX_BUMP_OBJECTSPACE)
1468                                                         iBumpSpace = 1;
1469                                                 else if (mtex->texflag & MTEX_BUMP_TEXTURESPACE)
1470                                                         iBumpSpace = 2;
1471                                                 else
1472                                                         iBumpSpace = 4; /* ViewSpace */
1473
1474                                                 /* re-initialize if bump space changed */
1475                                                 if (iBumpSpacePrev != iBumpSpace) {
1476                                                         GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
1477
1478                                                         if (mtex->texflag & MTEX_BUMP_OBJECTSPACE)
1479                                                                 GPU_link(mat, "mtex_bump_init_objspace",
1480                                                                          surf_pos, vNorg,
1481                                                                          GPU_builtin(GPU_VIEW_MATRIX),
1482                                                                          GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
1483                                                                          GPU_builtin(GPU_OBJECT_MATRIX),
1484                                                                          GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
1485                                                                          fPrevMagnitude, vNacc,
1486                                                                          &fPrevMagnitude, &vNacc,
1487                                                                          &vR1, &vR2, &fDet);
1488
1489                                                         else if (mtex->texflag & MTEX_BUMP_TEXTURESPACE)
1490                                                                 GPU_link(mat, "mtex_bump_init_texturespace",
1491                                                                          surf_pos, vNorg,
1492                                                                          fPrevMagnitude, vNacc,
1493                                                                          &fPrevMagnitude, &vNacc,
1494                                                                          &vR1, &vR2, &fDet);
1495
1496                                                         else
1497                                                                 GPU_link(mat, "mtex_bump_init_viewspace",
1498                                                                          surf_pos, vNorg,
1499                                                                          fPrevMagnitude, vNacc,
1500                                                                          &fPrevMagnitude, &vNacc,
1501                                                                          &vR1, &vR2, &fDet);
1502
1503                                                         iBumpSpacePrev = iBumpSpace;
1504                                                 }
1505
1506
1507                                                 if (found_deriv_map) {
1508                                                         GPU_link(mat, "mtex_bump_deriv",
1509                                                                  texco, GPU_image(tex->ima, &tex->iuser, true),
1510                                                                  GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
1511                                                                  &dBs, &dBt);
1512                                                 }
1513                                                 else if (mtex->texflag & MTEX_3TAP_BUMP)
1514                                                         GPU_link(mat, "mtex_bump_tap3",
1515                                                                  texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1516                                                                  &dBs, &dBt);
1517                                                 else if (mtex->texflag & MTEX_5TAP_BUMP)
1518                                                         GPU_link(mat, "mtex_bump_tap5",
1519                                                                  texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1520                                                                  &dBs, &dBt);
1521                                                 else if (mtex->texflag & MTEX_BICUBIC_BUMP) {
1522                                                         if (GPU_bicubic_bump_support()) {
1523                                                                 GPU_link(mat, "mtex_bump_bicubic",
1524                                                                          texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1525                                                                          &dBs, &dBt);
1526                                                         }
1527                                                         else {
1528                                                                 GPU_link(mat, "mtex_bump_tap5",
1529                                                                          texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
1530                                                                          &dBs, &dBt);
1531                                                         }
1532                                                 }
1533
1534
1535                                                 if (mtex->texflag & MTEX_BUMP_TEXTURESPACE) {
1536                                                         float imag_tspace_dimension_y = aspect * imag_tspace_dimension_x;
1537                                                         GPU_link(mat, "mtex_bump_apply_texspace",
1538                                                                  fDet, dBs, dBt, vR1, vR2,
1539                                                                  GPU_image(tex->ima, &tex->iuser, true), texco,
1540                                                                  GPU_uniform(&imag_tspace_dimension_x),
1541                                                                  GPU_uniform(&imag_tspace_dimension_y), vNacc,
1542                                                                  &vNacc, &shi->vn);
1543                                                 }
1544                                                 else
1545                                                         GPU_link(mat, "mtex_bump_apply",
1546                                                                  fDet, dBs, dBt, vR1, vR2, vNacc,
1547                                                                  &vNacc, &shi->vn);
1548
1549                                         }
1550                                 }
1551
1552                                 GPU_link(mat, "vec_math_negate", shi->vn, &orn);
1553                         }
1554
1555                         if ((mtex->mapto & MAP_VARS)) {
1556                                 if (rgbnor & TEX_RGB) {
1557                                         if (talpha)
1558                                                 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
1559                                         else
1560                                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1561                                 }
1562
1563                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
1564                                         GPUNodeLink *difffac;
1565
1566                                         if (mtex->difffac == 1.0f) difffac = stencil;
1567                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
1568
1569                                         texture_value_blend(
1570                                                 mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac,
1571                                                 mtex->blendtype, &shi->refl);
1572                                         GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
1573                                 }
1574                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
1575                                         GPUNodeLink *specfac;
1576
1577                                         if (mtex->specfac == 1.0f) specfac = stencil;
1578                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
1579
1580                                         texture_value_blend(
1581                                                 mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac,
1582                                                 mtex->blendtype, &shi->spec);
1583                                         GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
1584                                 }
1585                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
1586                                         GPUNodeLink *emitfac;
1587
1588                                         if (mtex->emitfac == 1.0f) emitfac = stencil;
1589                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
1590
1591                                         texture_value_blend(
1592                                                 mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac,
1593                                                 mtex->blendtype, &shi->emit);
1594                                         GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
1595                                 }
1596                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
1597                                         GPUNodeLink *hardfac;
1598
1599                                         if (mtex->hardfac == 1.0f) hardfac = stencil;
1600                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
1601
1602                                         GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
1603                                         texture_value_blend(
1604                                                 mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac,
1605                                                 mtex->blendtype, &shi->har);
1606                                         GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
1607                                 }
1608                                 if (mtex->mapto & MAP_ALPHA) {
1609                                         GPUNodeLink *alphafac;
1610
1611                                         if (mtex->alphafac == 1.0f) alphafac = stencil;
1612                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
1613
1614                                         texture_value_blend(
1615                                                 mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac,
1616                                                 mtex->blendtype, &shi->alpha);
1617                                         GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
1618                                 }
1619                                 if (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
1620                                         GPUNodeLink *ambfac;
1621
1622                                         if (mtex->ambfac == 1.0f) ambfac = stencil;
1623                                         else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
1624
1625                                         texture_value_blend(
1626                                                 mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac,
1627                                                 mtex->blendtype, &shi->amb);
1628                                         GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
1629                                 }
1630                         }
1631                 }
1632         }
1633 }
1634
1635 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
1636 {
1637         float one = 1.0f;
1638
1639         memset(shi, 0, sizeof(*shi));
1640
1641         shi->gpumat = mat;
1642         shi->mat = ma;
1643
1644         GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, ma), &shi->rgb);
1645         GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, ma), &shi->specrgb);
1646         GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->mirr, GPU_DYNAMIC_MAT_MIR, ma), &shi->mir);
1647         GPU_link(mat, "set_rgba_zero", &shi->refcol);
1648         GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
1649
1650         if (mat->alpha)
1651                 GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->alpha, GPU_DYNAMIC_MAT_ALPHA, ma), &shi->alpha);
1652         else
1653                 GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha);
1654
1655         GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->ref, GPU_DYNAMIC_MAT_REF, ma), &shi->refl);
1656         GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->spec, GPU_DYNAMIC_MAT_SPEC, ma), &shi->spec);
1657         GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->emit, GPU_DYNAMIC_MAT_EMIT, ma), &shi->emit);
1658         GPU_link(mat, "set_value", GPU_dynamic_uniform((float *)&ma->har, GPU_DYNAMIC_MAT_HARD, ma), &shi->har);
1659         GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, ma), &shi->amb);
1660         GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra);
1661         GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
1662         GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
1663         if (GPU_material_do_color_management(mat))
1664                 GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol);
1665         GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
1666 }
1667
1668 void GPU_mist_update_enable(short enable)
1669 {
1670         GPUWorld.mistenabled = (float)enable;
1671 }
1672
1673 void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3])
1674 {
1675         GPUWorld.mistype = (float)type;
1676         GPUWorld.miststart = start;
1677         GPUWorld.mistdistance = dist;
1678         GPUWorld.mistintensity = inten;
1679         copy_v3_v3(GPUWorld.mistcol, color);
1680         GPUWorld.mistcol[3] = 1.0f;
1681 }
1682
1683 void GPU_horizon_update_color(float color[3])
1684 {
1685         copy_v3_v3(GPUWorld.horicol, color);
1686 }
1687
1688 void GPU_ambient_update_color(float color[3])
1689 {
1690         copy_v3_v3(GPUWorld.ambcol, color);
1691         GPUWorld.ambcol[3] = 1.0f;
1692 }
1693
1694 void GPU_zenith_update_color(float color[3])
1695 {
1696         copy_v3_v3(GPUWorld.zencol, color);
1697 }
1698
1699 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
1700 {
1701         GPUMaterial *mat = shi->gpumat;
1702         GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
1703         Material *ma = shi->mat;
1704         World *world = mat->scene->world;
1705         float linfac, logfac;
1706
1707         memset(shr, 0, sizeof(*shr));
1708
1709         if (ma->mode & MA_VERTEXCOLP)
1710                 shi->rgb = shi->vcol;
1711
1712         do_material_tex(shi);
1713
1714         if ((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
1715                 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
1716                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1717                 GPU_link(mat, "set_value", shi->alpha, &shr->alpha);
1718                 shr->combined = shr->diff;
1719         }
1720         else {
1721                 if (GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
1722                         if ((ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == MA_VERTEXCOL) {
1723                                 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
1724                                 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
1725                         }
1726                         else
1727                                 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
1728                 }
1729                 else
1730                         GPU_link(mat, "set_rgb_zero", &shr->diff);
1731
1732                 GPU_link(mat, "set_rgb_zero", &shr->spec);
1733
1734                 material_lights(shi, shr);
1735
1736                 shr->combined = shr->diff;
1737
1738                 GPU_link(mat, "set_value", shi->alpha, &shr->alpha);
1739
1740                 if (world) {
1741                         /* exposure correction */
1742                         if (world->exp != 0.0f || world->range != 1.0f) {
1743                                 linfac = 1.0f + powf((2.0f * world->exp + 0.5f), -10);
1744                                 logfac = logf((linfac - 1.0f) / linfac) / world->range;
1745
1746                                 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
1747                                 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
1748
1749                                 GPU_link(mat, "shade_exposure_correct", shr->combined,
1750                                         ulinfac, ulogfac, &shr->combined);
1751                                 GPU_link(mat, "shade_exposure_correct", shr->spec,
1752                                         ulinfac, ulogfac, &shr->spec);
1753                         }
1754
1755                         /* environment lighting */
1756                         if (!(mat->scene->gm.flag & GAME_GLSL_NO_ENV_LIGHTING) &&
1757                             (world->mode & WO_ENV_LIGHT) &&
1758                             (mat->scene->r.mode & R_SHADOW) &&
1759                             !BKE_scene_use_new_shading_nodes(mat->scene))
1760                         {
1761                                 if ((world->ao_env_energy != 0.0f) && (GPU_link_changed(shi->amb) || ma->amb != 0.0f) &&
1762                                     (GPU_link_changed(shi->refl) || ma->ref != 0.0f))
1763                                 {
1764                                         if (world->aocolor != WO_AOPLAIN) {
1765                                                 if (!(is_zero_v3(&world->horr) & is_zero_v3(&world->zenr))) {
1766                                                         GPUNodeLink *fcol, *f;
1767                                                         GPU_link(mat, "math_multiply", shi->amb, shi->refl, &f);
1768                                                         GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f);
1769                                                         GPU_link(mat, "shade_mul_value", f, shi->rgb, &fcol);
1770                                                         GPU_link(mat, "env_apply", shr->combined,
1771                                                                  GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL),
1772                                                                  GPU_dynamic_uniform(GPUWorld.zencol, GPU_DYNAMIC_ZENITH_COLOR, NULL), fcol,
1773                                                                  GPU_builtin(GPU_VIEW_MATRIX), shi->vn, &shr->combined);
1774                                                 }
1775                                         }
1776                                         else {
1777                                                 GPUNodeLink *f;
1778                                                 GPU_link(mat, "math_multiply", shi->amb, shi->refl, &f);
1779                                                 GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f);
1780                                                 GPU_link(mat, "shade_maddf", shr->combined, f, shi->rgb, &shr->combined);
1781                                         }
1782                                 }
1783                         }
1784
1785                         /* ambient color */
1786                         if (GPU_link_changed(shi->amb) || ma->amb != 0.0f) {
1787                                 GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
1788                                          GPU_dynamic_uniform(GPUWorld.ambcol, GPU_DYNAMIC_AMBIENT_COLOR, NULL),
1789                                          &shr->combined);
1790                         }
1791                 }
1792
1793                 if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP | MA_RAYTRANSP))) {
1794                         if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f) {
1795                                 GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra,
1796                                          shi->alpha, &shr->alpha);
1797                         }
1798                 }
1799
1800                 if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
1801                 if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
1802
1803                 if (GPU_link_changed(shi->refcol))
1804                         GPU_link(mat, "shade_add_mirror", shi->mir, shi->refcol, shr->combined, &shr->combined);
1805
1806                 if (GPU_link_changed(shi->spec) || ma->spec != 0.0f)
1807                         GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
1808         }
1809
1810         GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
1811
1812         if (ma->shade_flag & MA_OBCOLOR)
1813                 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1814
1815         if (!(ma->mode & MA_NOMIST)) {
1816                 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
1817                          GPU_dynamic_uniform(&GPUWorld.mistenabled, GPU_DYNAMIC_MIST_ENABLE, NULL),
1818                          GPU_dynamic_uniform(&GPUWorld.miststart, GPU_DYNAMIC_MIST_START, NULL),
1819                          GPU_dynamic_uniform(&GPUWorld.mistdistance, GPU_DYNAMIC_MIST_DISTANCE, NULL),
1820                          GPU_dynamic_uniform(&GPUWorld.mistype, GPU_DYNAMIC_MIST_TYPE, NULL),
1821                          GPU_dynamic_uniform(&GPUWorld.mistintensity, GPU_DYNAMIC_MIST_INTENSITY, NULL), &mistfac);
1822
1823                 GPU_link(mat, "mix_blend", mistfac, shr->combined,
1824                          GPU_dynamic_uniform(GPUWorld.mistcol, GPU_DYNAMIC_MIST_COLOR, NULL), &shr->combined);
1825         }
1826
1827         if (!mat->alpha) {
1828                 if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
1829                         GPU_link(mat, "shade_world_mix", GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL),
1830                                  shr->combined, &shr->combined);
1831
1832                 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
1833         }
1834
1835         if (ma->shade_flag & MA_OBCOLOR) {
1836                 mat->obcolalpha = 1;
1837                 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
1838         }
1839 }
1840
1841 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
1842 {
1843         GPUShadeInput shi;
1844         GPUShadeResult shr;
1845
1846         GPU_shadeinput_set(mat, ma, &shi);
1847         GPU_shaderesult_set(&shi, &shr);
1848
1849         return shr.combined;
1850 }
1851
1852 static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
1853 {
1854         static float roughness = 0.0f;
1855         GPUNodeLink *outlink;
1856
1857         GPU_link(mat, "node_bsdf_diffuse",
1858                  GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
1859
1860         return outlink;
1861 }
1862
1863 static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
1864 {
1865         GPUNodeLink *outlink;
1866
1867         /* some explanations here:
1868          * matcap normal holds the normal remapped to the 0.0 - 1.0 range. To take advantage of flat shading, we abuse
1869          * the built in secondary color of opengl. Color is just the regular color, which should include mask value too.
1870          * This also needs flat shading so we use the primary opengl color built-in */
1871         GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview),
1872                  GPU_opengl_builtin(GPU_MATCAP_NORMAL), GPU_opengl_builtin(GPU_COLOR), &outlink);
1873
1874         return outlink;
1875 }
1876
1877 /* new solid draw mode with glsl matcaps */
1878 GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma, bool use_opensubdiv)
1879 {
1880         GPUMaterial *mat;
1881         GPUNodeLink *outlink;
1882         LinkData *link;
1883
1884         for (link = ma->gpumaterial.first; link; link = link->next) {
1885                 GPUMaterial *current_material = (GPUMaterial *)link->data;
1886                 if (current_material->scene == scene &&
1887                     current_material->is_opensubdiv == use_opensubdiv)
1888                 {
1889                         return current_material;
1890                 }
1891         }
1892
1893         /* allocate material */
1894         mat = GPU_material_construct_begin(ma);
1895         mat->scene = scene;
1896         mat->type = GPU_MATERIAL_TYPE_MESH;
1897         mat->is_opensubdiv = use_opensubdiv;
1898
1899         if (ma->preview && ma->preview->rect[0]) {
1900                 outlink = gpu_material_preview_matcap(mat, ma);
1901         }
1902         else {
1903                 outlink = gpu_material_diffuse_bsdf(mat, ma);
1904         }
1905
1906         GPU_material_output_link(mat, outlink);
1907
1908         gpu_material_construct_end(mat, "matcap_pass");
1909
1910         /* note that even if building the shader fails in some way, we still keep
1911          * it to avoid trying to compile again and again, and simple do not use
1912          * the actual shader on drawing */
1913
1914         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
1915         link->data = mat;
1916         BLI_addtail(&ma->gpumaterial, link);
1917
1918         return mat;
1919 }
1920
1921 static void do_world_tex(GPUShadeInput *shi, struct World *wo, GPUNodeLink **hor, GPUNodeLink **zen, GPUNodeLink **blend)
1922 {
1923         GPUMaterial *mat = shi->gpumat;
1924         GPUNodeLink *texco, *tin, *trgb, *stencil, *tcol, *zenfac;
1925         MTex *mtex;
1926         Tex *tex;
1927         float ofs[3], zero = 0.0f;
1928         int tex_nr, rgbnor;
1929
1930         GPU_link(mat, "set_value_one", &stencil);
1931         /* go over texture slots */
1932         for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) {
1933                 if (wo->mtex[tex_nr]) {
1934                         mtex = wo->mtex[tex_nr];
1935                         tex = mtex->tex;
1936                         if (tex == NULL || !tex->ima || (tex->type != TEX_IMAGE && tex->type != TEX_ENVMAP))
1937                                 continue;
1938                         /* which coords */
1939                         if (mtex->texco == TEXCO_VIEW || mtex->texco == TEXCO_GLOB) {
1940                                 if (tex->type == TEX_IMAGE)
1941                                         texco = GPU_builtin(GPU_VIEW_POSITION);
1942                                 else if (tex->type == TEX_ENVMAP)
1943                                         GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco);
1944                         }
1945                         else if (mtex->texco == TEXCO_EQUIRECTMAP || mtex->texco == TEXCO_ANGMAP) {
1946                                 if ((tex->type == TEX_IMAGE && wo->skytype & WO_SKYREAL) || tex->type == TEX_ENVMAP)
1947                                         GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco);
1948                                 else
1949                                         texco = GPU_builtin(GPU_VIEW_POSITION);
1950                         }
1951                         else
1952                                 continue;
1953                         GPU_link(mat, "texco_norm", texco, &texco);
1954                         if (tex->type == TEX_IMAGE && !(wo->skytype & WO_SKYREAL)) {
1955                                 GPU_link(mat, "mtex_2d_mapping", texco, &texco);
1956                         }
1957                         if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) {
1958                                 float size[3] = { mtex->size[0], mtex->size[1], mtex->size[2] };
1959                                 if (tex->type == TEX_ENVMAP) {
1960                                         size[1] = mtex->size[2];
1961                                         size[2] = mtex->size[1];
1962                                 }
1963                                 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(size), &texco);
1964                         }
1965                         ofs[0] = mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0];
1966                         if (tex->type == TEX_ENVMAP) {
1967                                 ofs[1] = -mtex->ofs[2] + 0.5f - 0.5f * mtex->size[2];
1968                                 ofs[2] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1];
1969                         }
1970                         else {
1971                                 ofs[1] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1];
1972                                 ofs[2] = 0.0;
1973                         }
1974                         if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
1975                                 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
1976                         if (mtex->texco == TEXCO_EQUIRECTMAP) {
1977                                 GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
1978                         }
1979                         else if (mtex->texco == TEXCO_ANGMAP) {
1980                                 GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
1981                         }
1982                         else {
1983                                 if (tex->type == TEX_ENVMAP)
1984                                         GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), &tin, &trgb);
1985                                 else if (tex->type == TEX_IMAGE)
1986                                         GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
1987                         }
1988                         rgbnor = TEX_RGB;
1989                         if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)
1990                                 if (GPU_material_do_color_management(mat))
1991                                         GPU_link(mat, "srgb_to_linearrgb", trgb, &trgb);
1992                         /* texture output */
1993                         if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1994                                 GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
1995                                 rgbnor -= TEX_RGB;
1996                         }
1997                         if (mtex->texflag & MTEX_NEGATIVE) {
1998                                 if (rgbnor & TEX_RGB)
1999                                         GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
2000                                 else
2001                                         GPU_link(mat, "mtex_value_invert", tin, &tin);
2002                         }
2003                         if (mtex->texflag & MTEX_STENCIL) {
2004                                 if (rgbnor & TEX_RGB)
2005                                         GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
2006                                 else
2007                                         GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
2008                         }
2009                         else {
2010                                 if (rgbnor & TEX_RGB)
2011                                         GPU_link(mat, "mtex_alpha_multiply_value", trgb, stencil, &trgb);
2012                                 else
2013                                         GPU_link(mat, "math_multiply", stencil, tin, &tin);
2014                         }
2015                         /* color mapping */
2016                         if (mtex->mapto & (WOMAP_HORIZ + WOMAP_ZENUP + WOMAP_ZENDOWN)) {
2017                                 if ((rgbnor & TEX_RGB) == 0)
2018                                         GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &trgb);
2019                                 else
2020                                         GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
2021                                 GPU_link(mat, "set_rgb", trgb, &tcol);
2022                                 if (mtex->mapto & WOMAP_HORIZ) {
2023                                         texture_rgb_blend(mat, tcol, *hor, tin, GPU_uniform(&mtex->colfac), mtex->blendtype, hor);
2024                                 }
2025                                 if (mtex->mapto & (WOMAP_ZENUP + WOMAP_ZENDOWN)) {
2026                                         GPU_link(mat, "set_value_zero", &zenfac);
2027                                         if (wo->skytype & WO_SKYREAL) {
2028                                                 if (mtex->mapto & WOMAP_ZENUP) {
2029                                                         if (mtex->mapto & WOMAP_ZENDOWN) {
2030                                                                 GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac),
2031                                                                          GPU_uniform(&mtex->zendownfac), &zenfac);
2032                                                         }
2033                                                         else {
2034                                                                 GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac),
2035                                                                          GPU_uniform(&zero), &zenfac);
2036                                                         }
2037                                                 }
2038                                                 else if (mtex->mapto & WOMAP_ZENDOWN) {
2039                                                         GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&zero),
2040                                                                  GPU_uniform(&mtex->zendownfac), &zenfac);
2041                                                 }
2042                                         }
2043                                         else {
2044                                                 if (mtex->mapto & WOMAP_ZENUP)
2045                                                         GPU_link(mat, "set_value", GPU_uniform(&mtex->zenupfac), &zenfac);
2046                                                 else if (mtex->mapto & WOMAP_ZENDOWN)
2047                                                         GPU_link(mat, "set_value", GPU_uniform(&mtex->zendownfac), &zenfac);
2048                                         }
2049                                         texture_rgb_blend(mat, tcol, *zen, tin, zenfac, mtex->blendtype, zen);
2050                                 }
2051                         }
2052                         if (mtex->mapto & WOMAP_BLEND && wo->skytype & WO_SKYBLEND) {
2053                                 if (rgbnor & TEX_RGB)
2054                                         GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
2055                                 texture_value_blend(mat, GPU_uniform(&mtex->def_var), *blend, tin, GPU_uniform(&mtex->blendfac), mtex->blendtype, blend);
2056                         }
2057                 }
2058         }
2059 }
2060
2061 static void gpu_material_old_world(struct GPUMaterial *mat, struct World *wo)
2062 {
2063         GPUShadeInput shi;
2064         GPUShadeResult shr;
2065         GPUNodeLink *hor, *zen, *ray, *blend;
2066
2067         shi.gpumat = mat;
2068
2069         for (int i = 0; i < MAX_MTEX; i++) {
2070                 if (wo->mtex[i] && wo->mtex[i]->tex) {
2071                         wo->skytype |= WO_SKYTEX;
2072                         break;
2073                 }
2074         }
2075         if ((wo->skytype & (WO_SKYBLEND + WO_SKYTEX)) == 0) {
2076                 GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &shr.combined);
2077         }
2078         else {
2079                 GPU_link(mat, "set_rgb_zero", &shi.rgb);
2080                 GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &ray);
2081                 if (wo->skytype & WO_SKYPAPER)
2082                         GPU_link(mat, "world_paper_view", GPU_builtin(GPU_VIEW_POSITION), &shi.view);
2083                 else
2084                         GPU_link(mat, "shade_view", ray, &shi.view);
2085                 if (wo->skytype & WO_SKYBLEND) {
2086                         if (wo->skytype & WO_SKYPAPER) {
2087                                 if (wo->skytype & WO_SKYREAL)
2088                                         GPU_link(mat, "world_blend_paper_real", GPU_builtin(GPU_VIEW_POSITION), &blend);
2089                                 else
2090                                         GPU_link(mat, "world_blend_paper", GPU_builtin(GPU_VIEW_POSITION), &blend);
2091                         }
2092                         else {
2093                                 if (wo->skytype & WO_SKYREAL)
2094                                         GPU_link(mat, "world_blend_real", ray, &blend);
2095                                 else
2096                                         GPU_link(mat, "world_blend", ray, &blend);
2097                         }
2098                 }
2099                 else {
2100                         GPU_link(mat, "set_value_zero", &blend);
2101                 }
2102                 GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &hor);
2103                 GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->zenr, GPU_DYNAMIC_ZENITH_COLOR, NULL), &zen);
2104                 do_world_tex(&shi, wo, &hor, &zen, &blend);
2105                 if (wo->skytype & WO_SKYBLEND)
2106                         GPU_link(mat, "node_mix_shader", blend, hor, zen, &shi.rgb);
2107                 else
2108                         GPU_link(mat, "set_rgb", hor, &shi.rgb);
2109                 GPU_link(mat, "set_rgb", shi.rgb, &shr.combined);
2110         }
2111         GPU_material_output_link(mat, shr.combined);
2112 }
2113
2114 GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
2115 {
2116         LinkData *link;
2117         GPUMaterial *mat;
2118
2119         for (link = wo->gpumaterial.first; link; link = link->next)
2120                 if (((GPUMaterial *)link->data)->scene == scene)
2121                         return link->data;
2122
2123         /* allocate material */
2124         mat = GPU_material_construct_begin(NULL);
2125         mat->scene = scene;
2126         mat->type = GPU_MATERIAL_TYPE_WORLD;
2127
2128         /* create nodes */
2129         if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes) {
2130                 ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
2131         }
2132         else {
2133                 gpu_material_old_world(mat, wo);
2134         }
2135
2136         if (GPU_material_do_color_management(mat))
2137                 if (mat->outlink)
2138                         GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
2139
2140         gpu_material_construct_end(mat, wo->id.name);
2141
2142         /* note that even if building the shader fails in some way, we still keep
2143          * it to avoid trying to compile again and again, and simple do not use
2144          * the actual shader on drawing */
2145
2146         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
2147         link->data = mat;
2148         BLI_addtail(&wo->gpumaterial, link);
2149
2150         return mat;
2151 }
2152
2153
2154 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv)
2155 {
2156         GPUMaterial *mat;
2157         GPUNodeLink *outlink;
2158         LinkData *link;
2159
2160         for (link = ma->gpumaterial.first; link; link = link->next) {
2161                 GPUMaterial *current_material = (GPUMaterial *)link->data;
2162                 if (current_material->scene == scene &&
2163                     current_material->is_opensubdiv == use_opensubdiv)
2164                 {
2165                         return current_material;
2166                 }
2167         }
2168
2169         /* allocate material */
2170         mat = GPU_material_construct_begin(ma);
2171         mat->scene = scene;
2172         mat->type = GPU_MATERIAL_TYPE_MESH;
2173         mat->is_opensubdiv = use_opensubdiv;
2174
2175         /* render pipeline option */
2176         bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
2177         if (!new_shading_nodes && (ma->mode & MA_TRANSP))
2178                 GPU_material_enable_alpha(mat);
2179         else if (new_shading_nodes && ma->alpha < 1.0f)
2180                 GPU_material_enable_alpha(mat);
2181
2182         if (!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
2183                 /* create nodes */
2184                 if (new_shading_nodes)
2185                         ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_NEW_SHADING);
2186                 else
2187                         ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_OLD_SHADING);
2188         }
2189         else {
2190                 if (new_shading_nodes) {
2191                         /* create simple diffuse material instead of nodes */
2192                         outlink = gpu_material_diffuse_bsdf(mat, ma);
2193                 }
2194                 else {
2195                         /* create blender material */
2196                         outlink = GPU_blender_material(mat, ma);
2197                 }
2198
2199                 GPU_material_output_link(mat, outlink);
2200         }
2201
2202         if (GPU_material_do_color_management(mat))
2203                 if (mat->outlink)
2204                         GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
2205
2206         gpu_material_construct_end(mat, ma->id.name);
2207
2208         /* note that even if building the shader fails in some way, we still keep
2209          * it to avoid trying to compile again and again, and simple do not use
2210          * the actual shader on drawing */
2211
2212         link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
2213         link->data = mat;
2214         BLI_addtail(&ma->gpumaterial, link);
2215
2216         return mat;
2217 }
2218
2219 void GPU_materials_free(Main *bmain)
2220 {
2221         Object *ob;
2222         Material *ma;
2223         World *wo;
2224         extern Material defmaterial;
2225
2226         for (ma = bmain->mat.first; ma; ma = ma->id.next)
2227                 GPU_material_free(&ma->gpumaterial);
2228
2229         for (wo = bmain->world.first; wo; wo = wo->id.next)
2230                 GPU_material_free(&wo->gpumaterial);
2231
2232         GPU_material_free(&defmaterial.gpumaterial);
2233
2234         for (ob = bmain->object.first; ob; ob = ob->id.next)
2235                 GPU_lamp_free(ob);
2236 }
2237
2238 /* Lamps and shadow buffers */
2239
2240 static void gpu_lamp_calc_winmat(GPULamp *lamp)
2241 {
2242         float temp, angle, pixsize, wsize;
2243
2244         if (lamp->type == LA_SUN) {
2245                 wsize = lamp->la->shadow_frustum_size;
2246                 orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
2247         }
2248         else if (lamp->type == LA_SPOT) {
2249                 angle = saacos(lamp->spotsi);
2250                 temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
2251                 pixsize = lamp->d / temp;
2252                 wsize = pixsize * 0.5f * lamp->size;
2253                 /* compute shadows according to X and Y scaling factors */
2254                 perspective_m4(
2255                         lamp->winmat,
2256                         -wsize * lamp->spotvec[0], wsize * lamp->spotvec[0],
2257                         -wsize * lamp->spotvec[1], wsize * lamp->spotvec[1],
2258                         lamp->d, lamp->clipend);
2259         }
2260 }
2261
2262 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4])
2263 {
2264         float mat[4][4];
2265         float obmat_scale[3];
2266
2267         lamp->lay = lay;
2268         lamp->hide = hide;
2269
2270         normalize_m4_m4_ex(mat, obmat, obmat_scale);
2271
2272         copy_v3_v3(lamp->vec, mat[2]);
2273         copy_v3_v3(lamp->co, mat[3]);
2274         copy_m4_m4(lamp->obmat, mat);
2275         invert_m4_m4(lamp->imat, mat);
2276
2277         if (lamp->type == LA_SPOT) {
2278                 /* update spotlamp scale on X and Y axis */
2279                 lamp->spotvec[0] = obmat_scale[0] / obmat_scale[2];
2280                 lamp->spotvec[1] = obmat_scale[1] / obmat_scale[2];
2281         }
2282
2283         if (GPU_lamp_has_shadow_buffer(lamp)) {
2284                 /* makeshadowbuf */
2285                 gpu_lamp_calc_winmat(lamp);
2286         }
2287 }
2288
2289 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy)
2290 {
2291         lamp->energy = energy;
2292         if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
2293
2294         lamp->col[0] = r;
2295         lamp->col[1] = g;
2296         lamp->col[2] = b;
2297 }
2298
2299 void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2,
2300                               float coeff_const, float coeff_lin, float coeff_quad)
2301 {
2302         lamp->dist = distance;
2303         lamp->att1 = att1;
2304         lamp->att2 = att2;
2305         lamp->coeff_const = coeff_const;
2306         lamp->coeff_lin = coeff_lin;
2307         lamp->coeff_quad = coeff_quad;
2308 }
2309
2310 void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
2311 {
2312         lamp->spotsi = cosf(spotsize * 0.5f);
2313         lamp->spotbl = (1.0f - lamp->spotsi) * spotblend;
2314 }
2315
2316 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
2317 {
2318         lamp->scene = scene;
2319         lamp->ob = ob;
2320         lamp->par = par;
2321         lamp->la = la;
2322
2323         /* add_render_lamp */
2324         lamp->mode = la->mode;
2325         lamp->type = la->type;
2326
2327         lamp->energy = la->energy;
2328         if (lamp->mode & LA_NEG) lamp->energy = -lamp->energy;
2329
2330         lamp->col[0] = la->r;
2331         lamp->col[1] = la->g;
2332         lamp->col[2] = la->b;
2333
2334         GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
2335
2336         lamp->spotsi = la->spotsize;
2337         if (lamp->mode & LA_HALO)
2338                 if (lamp->spotsi > DEG2RADF(170.0f))
2339                         lamp->spotsi = DEG2RADF(170.0f);
2340         lamp->spotsi = cosf(lamp->spotsi * 0.5f);
2341         lamp->spotbl = (1.0f - lamp->spotsi) * la->spotblend;
2342         lamp->k = la->k;
2343
2344         lamp->dist = la->dist;
2345         lamp->falloff_type = la->falloff_type;
2346         lamp->att1 = la->att1;
2347         lamp->att2 = la->att2;
2348         lamp->coeff_const = la->coeff_const;
2349         lamp->coeff_lin = la->coeff_lin;
2350         lamp->coeff_quad = la->coeff_quad;
2351         lamp->curfalloff = la->curfalloff;
2352
2353         /* initshadowbuf */
2354         lamp->bias = 0.02f * la->bias;
2355         lamp->size = la->bufsize;
2356         lamp->d = la->clipsta;
2357         lamp->clipend = la->clipend;
2358
2359         /* arbitrary correction for the fact we do no soft transition */
2360         lamp->bias *= 0.25f;
2361 }
2362
2363 static void gpu_lamp_shadow_free(GPULamp *lamp)
2364 {
2365         if (lamp->tex) {
2366                 GPU_texture_free(lamp->tex);
2367                 lamp->tex = NULL;
2368         }
2369         if (lamp->depthtex) {
2370                 GPU_texture_free(lamp->depthtex);
2371                 lamp->depthtex = NULL;
2372         }
2373         if (lamp->fb) {
2374                 GPU_framebuffer_free(lamp->fb);
2375                 lamp->fb = NULL;
2376         }
2377         if (lamp->blurtex) {
2378                 GPU_texture_free(lamp->blurtex);
2379                 lamp->blurtex = NULL;
2380         }
2381         if (lamp->blurfb) {
2382                 GPU_framebuffer_free(lamp->blurfb);
2383                 lamp->blurfb = NULL;
2384         }
2385 }
2386
2387 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
2388 {
2389         Lamp *la;
2390         GPULamp *lamp;
2391         LinkData *link;
2392
2393         for (link = ob->gpulamp.first; link; link = link->next) {
2394                 lamp = (GPULamp *)link->data;
2395
2396                 if (lamp->par == par && lamp->scene == scene)
2397                         return link->data;
2398         }
2399
2400         lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
2401
2402         link = MEM_callocN(sizeof(LinkData), "GPULampLink");
2403         link->data = lamp;
2404         BLI_addtail(&ob->gpulamp, link);
2405
2406         la = ob->data;
2407         gpu_lamp_from_blender(scene, ob, par, la, lamp);
2408
2409         if ((la->type == LA_SPOT && (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY))) ||
2410             (la->type == LA_SUN && (la->mode & LA_SHAD_RAY)))
2411         {
2412                 /* opengl */
2413                 lamp->fb = GPU_framebuffer_create();
2414                 if (!lamp->fb) {
2415                         gpu_lamp_shadow_free(lamp);
2416                         return lamp;
2417                 }
2418
2419                 if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
2420                         /* Shadow depth map */
2421                         lamp->depthtex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
2422                         if (!lamp->depthtex) {
2423                                 gpu_lamp_shadow_free(lamp);
2424                                 return lamp;
2425                         }
2426
2427                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) {
2428                                 gpu_lamp_shadow_free(lamp);
2429                                 return lamp;
2430                         }
2431
2432                         /* Shadow color map */
2433                         lamp->tex = GPU_texture_create_vsm_shadow_map(lamp->size, NULL);
2434                         if (!lamp->tex) {
2435                                 gpu_lamp_shadow_free(lamp);
2436                                 return lamp;
2437                         }
2438
2439                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
2440                                 gpu_lamp_shadow_free(lamp);
2441                                 return lamp;
2442                         }
2443
2444                         if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
2445                                 gpu_lamp_shadow_free(lamp);
2446                                 return lamp;
2447                         }
2448
2449                         /* FBO and texture for blurring */
2450                         lamp->blurfb = GPU_framebuffer_create();
2451                         if (!lamp->blurfb) {
2452                                 gpu_lamp_shadow_free(lamp);
2453                                 return lamp;
2454                         }
2455
2456                         lamp->blurtex = GPU_texture_create_vsm_shadow_map(lamp->size * 0.5, NULL);
2457                         if (!lamp->blurtex) {
2458                                 gpu_lamp_shadow_free(lamp);
2459                                 return lamp;
2460                         }
2461
2462                         if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) {
2463                                 gpu_lamp_shadow_free(lamp);
2464                                 return lamp;
2465                         }
2466
2467                         /* we need to properly bind to test for completeness */
2468                         GPU_texture_bind_as_framebuffer(lamp->blurtex);
2469
2470                         if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
2471                                 gpu_lamp_shadow_free(lamp);
2472                                 return lamp;
2473                         }
2474
2475                         GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
2476                 }
2477                 else {
2478                         lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
2479                         if (!lamp->tex) {
2480                                 gpu_lamp_shadow_free(lamp);
2481                                 return lamp;
2482                         }
2483
2484                         if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
2485                                 gpu_lamp_shadow_free(lamp);
2486                                 return lamp;
2487                         }
2488
2489                         if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
2490                                 gpu_lamp_shadow_free(lamp);
2491                                 return lamp;
2492                         }
2493                 }
2494
2495                 GPU_framebuffer_restore();
2496
2497                 lamp->shadow_color[0] = la->shdwr;
2498                 lamp->shadow_color[1] = la->shdwg;
2499                 lamp->shadow_color[2] = la->shdwb;
2500         }
2501         else {
2502                 lamp->shadow_color[0] = 1.0;
2503                 lamp->shadow_color[1] = 1.0;
2504                 lamp->shadow_color[2] = 1.0;
2505         }
2506
2507         return lamp;
2508 }
2509
2510 void GPU_lamp_free(Object *ob)
2511 {
2512         GPULamp *lamp;
2513         LinkData *link;
2514         LinkData *nlink;
2515         Material *ma;
2516
2517         for (link = ob->gpulamp.first; link; link = link->next) {
2518                 lamp = link->data;
2519
2520                 while (lamp->materials.first) {
2521                         nlink = lamp->materials.first;
2522                         ma = nlink->data;
2523                         BLI_freelinkN(&lamp->materials, nlink);
2524
2525                         if (ma->gpumaterial.first)
2526                                 GPU_material_free(&ma->gpumaterial);
2527                 }
2528
2529                 gpu_lamp_shadow_free(lamp);
2530
2531                 MEM_freeN(lamp);
2532         }
2533
2534         BLI_freelistN(&ob->gpulamp);
2535 }
2536
2537 bool GPU_lamp_has_shadow_buffer(GPULamp *lamp)
2538 {
2539         return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) &&
2540                 !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) &&
2541                 lamp->tex && lamp->fb);
2542 }
2543
2544 void GPU_lamp_update_buffer_mats(GPULamp *lamp)
2545 {
2546         float rangemat[4][4], persmat[4][4];
2547
2548         /* initshadowbuf */
2549         invert_m4_m4(lamp->viewmat, lamp->obmat);
2550         normalize_v3(lamp->viewmat[0]);
2551         normalize_v3(lamp->viewmat[1]);
2552         normalize_v3(lamp->viewmat[2]);
2553
2554         /* makeshadowbuf */
2555         mul_m4_m4m4(persmat, lamp->winmat, lamp->viewmat);
2556
2557         /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
2558         unit_m4(rangemat);
2559         rangemat[0][0] = 0.5f;
2560         rangemat[1][1] = 0.5f;
2561         rangemat[2][2] = 0.5f;
2562         rangemat[3][0] = 0.5f;
2563         rangemat[3][1] = 0.5f;
2564         rangemat[3][2] = 0.5f;
2565
2566         mul_m4_m4m4(lamp->persmat, rangemat, persmat);
2567 }
2568
2569 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4])
2570 {
2571         GPU_lamp_update_buffer_mats(lamp);
2572
2573         /* opengl */
2574         glDisable(GL_SCISSOR_TEST);
2575         GPU_texture_bind_as_framebuffer(lamp->tex);
2576         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
2577                 GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
2578
2579         /* set matrices */
2580         copy_m4_m4(viewmat, lamp->viewmat);
2581         copy_m4_m4(winmat, lamp->winmat);
2582         *winsize = lamp->size;
2583 }
2584
2585 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
2586 {
2587         if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
2588                 GPU_shader_unbind();
2589                 GPU_framebuffer_blur(lamp->fb, lamp->tex, lamp->blurfb, lamp->blurtex);
2590         }
2591
2592         GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
2593         GPU_framebuffer_restore();
2594         glEnable(GL_SCISSOR_TEST);
2595 }
2596
2597 int GPU_lamp_shadow_buffer_type(GPULamp *lamp)
2598 {
2599         return lamp->la->shadowmap_type;
2600 }
2601
2602 int GPU_lamp_shadow_bind_code(GPULamp *lamp)
2603 {
2604         return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1;
2605 }
2606
2607 float *GPU_lamp_dynpersmat(GPULamp *lamp)
2608 {
2609         return &lamp->dynpersmat[0][0];
2610 }
2611
2612 int GPU_lamp_shadow_layer(GPULamp *lamp)
2613 {
2614         if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW)))
2615                 return lamp->lay;
2616         else
2617                 return -1;
2618 }
2619
2620 GPUNodeLink *GPU_lamp_get_data(
2621         GPUMaterial *mat, GPULamp *lamp,
2622         GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy)
2623 {
2624         GPUNodeLink *visifac;
2625
2626         *r_col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob);
2627         *r_energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob);
2628         visifac = lamp_get_visibility(mat, lamp, r_lv, r_dist);
2629
2630         shade_light_textures(mat, lamp, r_col);
2631
2632         if (GPU_lamp_has_shadow_buffer(lamp)) {
2633                 GPUNodeLink *vn, *inp;
2634
2635                 GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &vn);
2636                 GPU_link(mat, "shade_inp", vn, *r_lv, &inp);
2637                 mat->dynproperty |= DYN_LAMP_PERSMAT;
2638
2639                 if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
2640                         GPU_link(mat, "shadows_only_vsm",
2641                                  GPU_builtin(GPU_VIEW_POSITION),
2642                                  GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
2643                                  GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
2644                                  GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias),
2645                                  GPU_uniform(lamp->shadow_color), inp, r_shadow);
2646                 }
2647                 else {
2648                         GPU_link(mat, "shadows_only",
2649                                  GPU_builtin(GPU_VIEW_POSITION),
2650                                  GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
2651                                  GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
2652                                  GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, r_shadow);
2653                 }
2654         }
2655         else {
2656                 GPU_link(mat, "set_rgb_one", r_shadow);
2657         }
2658
2659         /* ensure shadow buffer and lamp textures will be updated */
2660         add_user_list(&mat->lamps, lamp);
2661         add_user_list(&lamp->materials, mat->ma);
2662
2663         return visifac;
2664 }
2665
2666 /* export the GLSL shader */
2667
2668 GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
2669 {
2670         static struct {
2671                 GPUBuiltin gputype;
2672                 GPUDynamicType dynamictype;
2673                 GPUDataType datatype;
2674         } builtins[] = {
2675                 { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
2676                 { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
2677                 { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
2678                 { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
2679                 { GPU_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT, GPU_DATA_16F },
2680                 { GPU_INVERSE_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT, GPU_DATA_16F },
2681                 { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
2682                 { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
2683                 { 0 }
2684         };
2685
2686         GPUShaderExport *shader = NULL;
2687         GPUInput *input;
2688         int liblen, fraglen;
2689
2690         /* TODO(sergey): How to determine whether we need OSD or not here? */
2691         GPUMaterial *mat = GPU_material_from_blender(scene, ma, false);
2692         GPUPass *pass = (mat) ? mat->pass : NULL;
2693
2694         if (pass && pass->fragmentcode && pass->vertexcode) {
2695                 shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport");
2696
2697                 for (input = pass->inputs.first; input; input = input->next) {
2698                         GPUInputUniform *uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
2699
2700                         if (input->ima) {
2701                                 /* image sampler uniform */
2702                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE;
2703                                 uniform->datatype = GPU_DATA_1I;
2704                                 uniform->image = input->ima;
2705                                 uniform->texnumber = input->texid;
2706                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
2707                         }
2708                         else if (input->tex) {
2709                                 /* generated buffer */
2710                                 uniform->texnumber = input->texid;
2711                                 uniform->datatype = GPU_DATA_1I;
2712                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
2713
2714                                 switch (input->textype) {
2715                                         case GPU_SHADOW2D:
2716                                                 uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW;
2717                                                 uniform->lamp = input->dynamicdata;
2718                                                 break;
2719                                         case GPU_TEX2D:
2720                                                 if (GPU_texture_opengl_bindcode(input->tex)) {
2721                                                         uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
2722                                                         glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
2723                                                         uniform->texsize = GPU_texture_width(input->tex) * GPU_texture_height(input->tex);
2724                                                         uniform->texpixels = MEM_mallocN(uniform->texsize * 4, "RGBApixels");
2725                                                         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels);
2726                                                         glBindTexture(GL_TEXTURE_2D, 0);
2727                                                 }
2728                                                 break;
2729
2730                                         case GPU_NONE:
2731                                         case GPU_TEXCUBE:
2732                                         case GPU_FLOAT:
2733                                         case GPU_VEC2:
2734                                         case GPU_VEC3:
2735                                         case GPU_VEC4:
2736                                         case GPU_MAT3:
2737                                         case GPU_MAT4:
2738                                         case GPU_ATTRIB:
2739                                                 break;
2740                                 }
2741                         }
2742                         else {
2743                                 uniform->type = input->dynamictype;
2744                                 BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
2745                                 switch (input->type) {
2746                                         case GPU_FLOAT:
2747                                                 uniform->datatype = GPU_DATA_1F;
2748                                                 break;
2749                                         case GPU_VEC2:
2750                                                 uniform->datatype = GPU_DATA_2F;
2751                                                 break;
2752                                         case GPU_VEC3:
2753                                                 uniform->datatype = GPU_DATA_3F;
2754                                                 break;
2755                                         case GPU_VEC4:
2756                                                 uniform->datatype = GPU_DATA_4F;
2757                                                 break;
2758                                         case GPU_MAT3:
2759                                                 uniform->datatype = GPU_DATA_9F;
2760                                                 break;
2761                                         case GPU_MAT4:
2762                                                 uniform->datatype = GPU_DATA_16F;
2763                                                 break;
2764
2765                                         case GPU_NONE:
2766                                         case GPU_TEX2D:
2767                                         case GPU_TEXCUBE:
2768                                         case GPU_SHADOW2D:
2769                                         case GPU_ATTRIB:
2770                                                 break;
2771                                 }
2772
2773                                 if (GPU_DYNAMIC_GROUP_FROM_TYPE(uniform->type) == GPU_DYNAMIC_GROUP_LAMP)
2774                                         uniform->lamp = input->dynamicdata;
2775
2776                                 if (GPU_DYNAMIC_GROUP_FROM_TYPE(uniform->type) == GPU_DYNAMIC_GROUP_MAT)
2777                                         uniform->material = input->dynamicdata;
2778                         }
2779
2780                         if (uniform->type != GPU_DYNAMIC_NONE)
2781                                 BLI_addtail(&shader->uniforms, uniform);
2782                         else
2783                                 MEM_freeN(uniform);
2784                 }
2785
2786                 /* process builtin uniform */
2787                 for (int i = 0; builtins[i].gputype; i++) {
2788                         if (mat->builtins & builtins[i].gputype) {
2789                                 GPUInputUniform *uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
2790                                 uniform->type = builtins[i].dynamictype;
2791                                 uniform->datatype = builtins[i].datatype;
2792                                 BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname));
2793                                 BLI_addtail(&shader->uniforms, uniform);
2794                         }
2795                 }
2796
2797                 /* now link fragment shader with library shader */
2798                 /* TBD: remove the function that are not used in the main function */
2799                 liblen = (pass->libcode) ? strlen(pass->libcode) : 0;
2800                 fraglen = strlen(pass->fragmentcode);
2801                 shader->fragment = (char *)MEM_mallocN(liblen + fraglen + 1, "GPUFragShader");
2802                 if (pass->libcode)
2803                         memcpy(shader->fragment, pass->libcode, liblen);
2804                 memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen);
2805                 shader->fragment[liblen + fraglen] = 0;
2806
2807                 // export the attribute
2808                 for (int i = 0; i < mat->attribs.totlayer; i++) {
2809                         GPUInputAttribute *attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute");
2810                         attribute->type = mat->attribs.layer[i].type;
2811                         attribute->number = mat->attribs.layer[i].glindex;
2812                         BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid);
2813
2814                         switch (attribute->type) {
2815                                 case CD_TANGENT:
2816                                         attribute->datatype = GPU_DATA_4F;
2817                                         break;
2818                                 case CD_MTFACE:
2819                                         attribute->datatype = GPU_DATA_2F;
2820                                         attribute->name = mat->attribs.layer[i].name;
2821                                         break;
2822                                 case CD_MCOL:
2823                                         attribute->datatype = GPU_DATA_4UB;
2824                                         attribute->name = mat->attribs.layer[i].name;
2825                                         break;
2826                                 case CD_ORCO:
2827                                         attribute->datatype = GPU_DATA_3F;
2828                                         break;
2829                         }
2830
2831                         if (attribute->datatype != GPU_DATA_NONE)
2832                                 BLI_addtail(&shader->attributes, attribute);
2833                         else
2834                                 MEM_freeN(attribute);
2835                 }
2836
2837                 /* export the vertex shader */
2838                 shader->vertex = BLI_strdup(pass->vertexcode);
2839         }
2840
2841         return shader;
2842 }
2843
2844 void GPU_free_shader_export(GPUShaderExport *shader)
2845 {
2846         if (shader == NULL)