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