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