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