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