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