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