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