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