Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_material.c')
-rw-r--r--source/blender/gpu/intern/gpu_material.c2284
1 files changed, 2 insertions, 2282 deletions
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index eddd2b85829..d5f4f3269ed 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -62,7 +62,6 @@
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
-#include "GPU_lamp.h"
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -71,7 +70,6 @@
#include "DRW_engine.h"
#include "gpu_codegen.h"
-#include "gpu_lamp_private.h"
#ifdef WITH_OPENSUBDIV
# include "BKE_DerivedMesh.h"
@@ -79,25 +77,6 @@
/* Structs */
-typedef enum DynMatProperty {
- DYN_LAMP_CO = 1,
- DYN_LAMP_VEC = 2,
- DYN_LAMP_IMAT = 4,
- DYN_LAMP_PERSMAT = 8,
-} DynMatProperty;
-
-static struct GPUWorld {
- float mistenabled;
- float mistype;
- float miststart;
- float mistdistance;
- float mistintensity;
- float mistcol[4];
- float horicol[3];
- float ambcol[4];
- float zencol[3];
-} GPUWorld;
-
struct GPUMaterial {
Scene *scene; /* DEPRECATED was only usefull for lamps */
Material *ma;
@@ -136,9 +115,6 @@ struct GPUMaterial {
int objectinfoloc;
- ListBase lamps;
- bool bound;
-
bool is_opensubdiv;
/* XXX: Should be in Material. But it depends on the output node
@@ -165,115 +141,8 @@ enum {
GPU_DOMAIN_SSS = (1 << 2)
};
-/* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */
-static void texture_rgb_blend(
- GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
- int blendtype, GPUNodeLink **in);
-
/* Functions */
-static GPUMaterial *GPU_material_construct_begin(Material *ma)
-{
- GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
-
- material->ma = ma;
-
- return material;
-}
-
-static void gpu_material_set_attrib_id(GPUMaterial *material)
-{
- GPUVertexAttribs *attribs = &material->attribs;
- GPUPass *pass = material->pass;
- if (!pass) {
- attribs->totlayer = 0;
- return;
- }
-
- GPUShader *shader = GPU_pass_shader(pass);
- if (!shader) {
- attribs->totlayer = 0;
- return;
- }
-
- /* convert from attribute number to the actual id assigned by opengl,
- * in case the attrib does not get a valid index back, it was probably
- * removed by the glsl compiler by dead code elimination */
-
- int b = 0;
- for (int a = 0; a < attribs->totlayer; a++) {
- char name[32];
- BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attribid);
- attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
-
- BLI_snprintf(name, sizeof(name), "att%d_info", attribs->layer[a].attribid);
- attribs->layer[a].glinfoindoex = GPU_shader_get_uniform(shader, name);
-
- if (attribs->layer[a].glindex >= 0) {
- attribs->layer[b] = attribs->layer[a];
- b++;
- }
- }
-
- attribs->totlayer = b;
-}
-
-static int gpu_material_construct_end(GPUMaterial *material, const char *passname)
-{
- if (material->outlink) {
- GPUNodeLink *outlink = material->outlink;
- material->pass = GPU_generate_pass(&material->nodes, &material->inputs, outlink,
- &material->attribs, &material->builtins, material->type,
- passname,
- material->is_opensubdiv,
- GPU_material_use_new_shading_nodes(material));
-
- material->status = (material->pass) ? GPU_MAT_SUCCESS : GPU_MAT_FAILED;
-
- if (!material->pass)
- return 0;
-
- gpu_material_set_attrib_id(material);
-
- GPUShader *shader = GPU_pass_shader(material->pass);
-
- if (material->builtins & GPU_VIEW_MATRIX)
- material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX));
- if (material->builtins & GPU_INVERSE_VIEW_MATRIX)
- material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX));
- if (material->builtins & GPU_OBJECT_MATRIX)
- material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
- if (material->builtins & GPU_INVERSE_OBJECT_MATRIX)
- material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
- if (material->builtins & GPU_LOC_TO_VIEW_MATRIX)
- material->localtoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_LOC_TO_VIEW_MATRIX));
- if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX)
- material->invlocaltoviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_LOC_TO_VIEW_MATRIX));
- if (material->builtins & GPU_OBCOLOR)
- material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
- if (material->builtins & GPU_AUTO_BUMPSCALE)
- material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
- if (material->builtins & GPU_CAMERA_TEXCO_FACTORS)
- material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS));
- if (material->builtins & GPU_PARTICLE_SCALAR_PROPS)
- material->partscalarpropsloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_SCALAR_PROPS));
- if (material->builtins & GPU_PARTICLE_LOCATION)
- material->partcoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_LOCATION));
- if (material->builtins & GPU_PARTICLE_VELOCITY)
- material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY));
- if (material->builtins & GPU_PARTICLE_ANG_VELOCITY)
- material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY));
- if (material->builtins & GPU_OBJECT_INFO)
- material->objectinfoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_INFO));
- return 1;
- }
- else {
- GPU_pass_free_nodes(&material->nodes);
- }
-
- return 0;
-}
-
void GPU_material_free(ListBase *gpumaterial)
{
for (LinkData *link = gpumaterial->first; link; link = link->next) {
@@ -300,166 +169,17 @@ void GPU_material_free(ListBase *gpumaterial)
GPU_uniformbuffer_free(material->sss_profile);
}
- BLI_freelistN(&material->lamps);
-
MEM_freeN(material);
}
BLI_freelistN(gpumaterial);
}
-void GPU_material_bind(
- GPUMaterial *material, int oblay, int viewlay, double time, int mipmap,
- float viewmat[4][4], float viewinv[4][4], float camerafactors[4])
-{
- if (material->pass) {
- GPUShader *shader = GPU_pass_shader(material->pass);
-
- /* handle layer lamps */
- if (material->type == GPU_MATERIAL_TYPE_MESH) {
- for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) {
- GPULamp *lamp = nlink->data;
-
- if ((lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) &&
- GPU_lamp_visible(lamp, material->ma))
- {
- lamp->dynenergy = lamp->energy;
- copy_v3_v3(lamp->dyncol, lamp->col);
- }
- else {
- lamp->dynenergy = 0.0f;
- lamp->dyncol[0] = lamp->dyncol[1] = lamp->dyncol[2] = 0.0f;
- }
-
- if (material->dynproperty & DYN_LAMP_VEC) {
- copy_v3_v3(lamp->dynvec, lamp->vec);
- normalize_v3(lamp->dynvec);
- negate_v3(lamp->dynvec);
- mul_mat3_m4_v3(viewmat, lamp->dynvec);
- }
-
- if (material->dynproperty & DYN_LAMP_CO) {
- copy_v3_v3(lamp->dynco, lamp->co);
- mul_m4_v3(viewmat, lamp->dynco);
- }
-
- if (material->dynproperty & DYN_LAMP_IMAT) {
- mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
- }
-
- if (material->dynproperty & DYN_LAMP_PERSMAT) {
- /* The lamp matrices are already updated if we're using shadow buffers */
- if (!GPU_lamp_has_shadow_buffer(lamp)) {
- GPU_lamp_update_buffer_mats(lamp);
- }
- mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
- }
- }
- }
-
- /* note material must be bound before setting uniforms */
- GPU_pass_bind(material->pass, &material->inputs, time, mipmap);
-
- /* handle per material built-ins */
- if (material->builtins & GPU_VIEW_MATRIX) {
- GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float *)viewmat);
- }
- if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
- GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float *)viewinv);
- }
- if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) {
- if (camerafactors) {
- GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float *)camerafactors);
- }
- else {
- /* use default, no scaling no offset */
- float borders[4] = {1.0f, 1.0f, 0.0f, 0.0f};
- GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float *)borders);
- }
- }
-
- GPU_pass_update_uniforms(material->pass, &material->inputs);
-
- material->bound = 1;
- }
-}
-
GPUBuiltin GPU_get_material_builtins(GPUMaterial *material)
{
return material->builtins;
}
-void GPU_material_bind_uniforms(
- GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
- float autobumpscale, GPUParticleInfo *pi, float object_info[3])
-{
- if (material->pass) {
- GPUShader *shader = GPU_pass_shader(material->pass);
- float invmat[4][4], col[4];
- float localtoviewmat[4][4];
- float invlocaltoviewmat[4][4];
-
- /* handle per object builtins */
- if (material->builtins & GPU_OBJECT_MATRIX) {
- GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float *)obmat);
- }
- if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
- invert_m4_m4(invmat, obmat);
- GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float *)invmat);
- }
- if (material->builtins & GPU_LOC_TO_VIEW_MATRIX) {
- if (viewmat) {
- mul_m4_m4m4(localtoviewmat, viewmat, obmat);
- GPU_shader_uniform_vector(shader, material->localtoviewmatloc, 16, 1, (float *)localtoviewmat);
- }
- }
- if (material->builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
- if (viewmat) {
- mul_m4_m4m4(localtoviewmat, viewmat, obmat);
- invert_m4_m4(invlocaltoviewmat, localtoviewmat);
- GPU_shader_uniform_vector(shader, material->invlocaltoviewmatloc, 16, 1, (float *)invlocaltoviewmat);
- }
- }
- if (material->builtins & GPU_OBCOLOR) {
- copy_v4_v4(col, obcol);
- CLAMP(col[3], 0.0f, 1.0f);
- GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
- }
- if (material->builtins & GPU_AUTO_BUMPSCALE) {
- GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
- }
- if (material->builtins & GPU_PARTICLE_SCALAR_PROPS) {
- GPU_shader_uniform_vector(shader, material->partscalarpropsloc, 4, 1, pi->scalprops);
- }
- if (material->builtins & GPU_PARTICLE_LOCATION) {
- GPU_shader_uniform_vector(shader, material->partcoloc, 4, 1, pi->location);
- }
- if (material->builtins & GPU_PARTICLE_VELOCITY) {
- GPU_shader_uniform_vector(shader, material->partvel, 3, 1, pi->velocity);
- }
- if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) {
- GPU_shader_uniform_vector(shader, material->partangvel, 3, 1, pi->angular_velocity);
- }
- if (material->builtins & GPU_OBJECT_INFO) {
- GPU_shader_uniform_vector(shader, material->objectinfoloc, 3, 1, object_info);
- }
-
- }
-}
-
-void GPU_material_unbind(GPUMaterial *material)
-{
- if (material->pass) {
- material->bound = 0;
- GPU_pass_unbind(material->pass, &material->inputs);
- }
-}
-
-bool GPU_material_bound(GPUMaterial *material)
-{
- return material->bound;
-}
-
Scene *GPU_material_scene(GPUMaterial *material)
{
return material->scene;
@@ -831,19 +551,6 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
material->outlink = link;
}
-void GPU_material_enable_alpha(GPUMaterial *material)
-{
- material->alpha = 1;
-}
-
-GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4])
-{
- if (material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
- return GPU_BLEND_ALPHA;
- else
- return GPU_BLEND_SOLID;
-}
-
void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
{
BLI_addtail(&material->nodes, node);
@@ -865,16 +572,6 @@ bool GPU_material_do_color_management(GPUMaterial *mat)
return true;
}
-bool GPU_material_use_new_shading_nodes(GPUMaterial *mat)
-{
- return BKE_scene_use_new_shading_nodes(mat->scene);
-}
-
-bool GPU_material_use_world_space_shading(GPUMaterial *mat)
-{
- return BKE_scene_use_world_space_shading(mat->scene);
-}
-
bool GPU_material_use_domain_surface(GPUMaterial *mat)
{
return (mat->domain & GPU_DOMAIN_SURFACE);
@@ -885,1607 +582,6 @@ bool GPU_material_use_domain_volume(GPUMaterial *mat)
return (mat->domain & GPU_DOMAIN_VOLUME);
}
-static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
-{
- GPUNodeLink *visifac;
-
- /* from get_lamp_visibility */
- if (lamp->type == LA_SUN || lamp->type == LA_HEMI) {
- mat->dynproperty |= DYN_LAMP_VEC;
- GPU_link(mat, "lamp_visibility_sun_hemi",
- GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac);
- return visifac;
- }
- else {
- mat->dynproperty |= DYN_LAMP_CO;
- GPU_link(mat, "lamp_visibility_other",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, dist, &visifac);
-
- if (lamp->type == LA_AREA)
- return visifac;
-
- switch (lamp->falloff_type) {
- case LA_FALLOFF_CONSTANT:
- break;
- case LA_FALLOFF_INVLINEAR:
- GPU_link(mat, "lamp_falloff_invlinear",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_INVSQUARE:
- GPU_link(mat, "lamp_falloff_invsquare",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_SLIDERS:
- GPU_link(mat, "lamp_falloff_sliders",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
- GPU_dynamic_uniform(&lamp->att1, GPU_DYNAMIC_LAMP_ATT1, lamp->ob),
- GPU_dynamic_uniform(&lamp->att2, GPU_DYNAMIC_LAMP_ATT2, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_INVCOEFFICIENTS:
- GPU_link(mat, "lamp_falloff_invcoefficients",
- GPU_dynamic_uniform(&lamp->coeff_const, GPU_DYNAMIC_LAMP_COEFFCONST, lamp->ob),
- GPU_dynamic_uniform(&lamp->coeff_lin, GPU_DYNAMIC_LAMP_COEFFLIN, lamp->ob),
- GPU_dynamic_uniform(&lamp->coeff_quad, GPU_DYNAMIC_LAMP_COEFFQUAD, lamp->ob), *dist, &visifac);
- break;
- case LA_FALLOFF_CURVE:
- {
- float *array;
- int size;
-
- curvemapping_initialize(lamp->curfalloff);
- curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
- GPU_link(mat, "lamp_falloff_curve",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
- GPU_texture(size, array), *dist, &visifac);
-
- break;
- }
- }
-
- if (lamp->mode & LA_SPHERE)
- GPU_link(mat, "lamp_visibility_sphere",
- GPU_dynamic_uniform(&lamp->dist, GPU_DYNAMIC_LAMP_DISTANCE, lamp->ob),
- *dist, visifac, &visifac);
-
- if (lamp->type == LA_SPOT) {
- GPUNodeLink *inpr;
-
- if (lamp->mode & LA_SQUARE) {
- mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
- GPU_link(mat, "lamp_visibility_spot_square",
- GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
- }
- else {
- mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_IMAT;
- GPU_link(mat, "lamp_visibility_spot_circle",
- GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->spotvec, GPU_DYNAMIC_LAMP_SPOTSCALE, lamp->ob), *lv, &inpr);
- }
-
- GPU_link(mat, "lamp_visibility_spot",
- GPU_dynamic_uniform(&lamp->spotsi, GPU_DYNAMIC_LAMP_SPOTSIZE, lamp->ob),
- GPU_dynamic_uniform(&lamp->spotbl, GPU_DYNAMIC_LAMP_SPOTBLEND, lamp->ob),
- inpr, visifac, &visifac);
- }
-
- GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
-
- return visifac;
- }
-}
-
-#if 0
-static void area_lamp_vectors(LampRen *lar)
-{
- float xsize = 0.5f * lar->area_size, ysize = 0.5f * lar->area_sizey;
-
- /* make it smaller, so area light can be multisampled */
- float multifac = 1.0f / sqrtf((float)lar->ray_totsamp);
- xsize *= multifac;
- ysize *= multifac;
-
- /* corner vectors */
- lar->area[0][0] = lar->co[0] - xsize * lar->mat[0][0] - ysize * lar->mat[1][0];
- lar->area[0][1] = lar->co[1] - xsize * lar->mat[0][1] - ysize * lar->mat[1][1];
- lar->area[0][2] = lar->co[2] - xsize * lar->mat[0][2] - ysize * lar->mat[1][2];
-
- /* corner vectors */
- lar->area[1][0] = lar->co[0] - xsize * lar->mat[0][0] + ysize * lar->mat[1][0];
- lar->area[1][1] = lar->co[1] - xsize * lar->mat[0][1] + ysize * lar->mat[1][1];
- lar->area[1][2] = lar->co[2] - xsize * lar->mat[0][2] + ysize * lar->mat[1][2];
-
- /* corner vectors */
- lar->area[2][0] = lar->co[0] + xsize * lar->mat[0][0] + ysize * lar->mat[1][0];
- lar->area[2][1] = lar->co[1] + xsize * lar->mat[0][1] + ysize * lar->mat[1][1];
- lar->area[2][2] = lar->co[2] + xsize * lar->mat[0][2] + ysize * lar->mat[1][2];
-
- /* corner vectors */
- lar->area[3][0] = lar->co[0] + xsize * lar->mat[0][0] - ysize * lar->mat[1][0];
- lar->area[3][1] = lar->co[1] + xsize * lar->mat[0][1] - ysize * lar->mat[1][1];
- lar->area[3][2] = lar->co[2] + xsize * lar->mat[0][2] - ysize * lar->mat[1][2];
- /* only for correction button size, matrix size works on energy */
- lar->areasize = lar->dist * lar->dist / (4.0f * xsize * ysize);
-}
-#endif
-
-static void ramp_blend(
- GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type,
- GPUNodeLink **r_col)
-{
- static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
- "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
- "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
- "mix_val", "mix_color", "mix_soft", "mix_linear"};
-
- GPU_link(mat, names[type], fac, col1, col2, r_col);
-}
-
-static void BKE_colorband_eval_blend(
- GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type,
- GPUNodeLink *incol, GPUNodeLink **r_col)
-{
- GPUNodeLink *tmp, *alpha, *col;
- float *array;
- int size;
-
- /* do colorband */
- BKE_colorband_evaluate_table_rgba(coba, &array, &size);
- GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
-
- /* use alpha in fac */
- GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
- GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
-
- /* blending method */
- ramp_blend(mat, fac, incol, col, type, r_col);
-}
-
-static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
-{
- Material *ma = shi->mat;
- GPUMaterial *mat = shi->gpumat;
-
- {
- if (ma->ramp_col) {
- if (ma->rampin_col == MA_RAMP_IN_RESULT) {
- GPUNodeLink *fac;
- GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
-
- /* colorband + blend */
- BKE_colorband_eval_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
- }
- }
- }
-}
-
-static void add_to_diffuse(
- GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb,
- GPUNodeLink **r_diff)
-{
- GPUNodeLink *fac, *tmp, *addcol;
-
- if (ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
- /* MA_RAMP_IN_RESULT is exceptional */
- if (ma->rampin_col == MA_RAMP_IN_RESULT) {
- addcol = shi->rgb;
- }
- else {
- /* input */
- switch (ma->rampin_col) {
- case MA_RAMP_IN_ENERGY:
- GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
- break;
- case MA_RAMP_IN_SHADER:
- fac = is;
- break;
- case MA_RAMP_IN_NOR:
- GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
- break;
- default:
- GPU_link(mat, "set_value_zero", &fac);
- break;
- }
-
- /* colorband + blend */
- BKE_colorband_eval_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
- }
- }
- else
- addcol = shi->rgb;
-
- /* output to */
- GPU_link(mat, "shade_madd", *r_diff, rgb, addcol, r_diff);
-}
-
-static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
-{
- Material *ma = shi->mat;
- GPUMaterial *mat = shi->gpumat;
-
- if (ma->ramp_spec && ma->rampin_spec == MA_RAMP_IN_RESULT) {
- GPUNodeLink *fac;
- GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
-
- /* colorband + blend */
- BKE_colorband_eval_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
- }
-}
-
-static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
-{
- Material *ma = shi->mat;
- GPUMaterial *mat = shi->gpumat;
- GPUNodeLink *fac, *tmp;
-
- *spec = shi->specrgb;
-
- /* MA_RAMP_IN_RESULT is exception */
- if (ma->ramp_spec && (ma->rampin_spec != MA_RAMP_IN_RESULT)) {
-
- /* input */
- switch (ma->rampin_spec) {
- case MA_RAMP_IN_ENERGY:
- fac = t;
- break;
- case MA_RAMP_IN_SHADER:
- fac = is;
- break;
- case MA_RAMP_IN_NOR:
- GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
- break;
- default:
- GPU_link(mat, "set_value_zero", &fac);
- break;
- }
-
- /* colorband + blend */
- BKE_colorband_eval_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
- }
-}
-
-static void add_user_list(ListBase *list, void *data)
-{
- LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData");
- link->data = data;
- BLI_addtail(list, link);
-}
-
-static void shade_light_textures(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **rgb)
-{
- for (int i = 0; i < MAX_MTEX; ++i) {
- MTex *mtex = lamp->la->mtex[i];
-
- if (mtex && mtex->tex && (mtex->tex->type & TEX_IMAGE) && mtex->tex->ima) {
- mat->dynproperty |= DYN_LAMP_PERSMAT;
-
- float one = 1.0f;
- GPUNodeLink *tex_rgb;
-
- GPU_link(mat, "shade_light_texture",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_image(mtex->tex->ima, &mtex->tex->iuser, false),
- GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- &tex_rgb);
- texture_rgb_blend(mat, tex_rgb, *rgb, GPU_uniform(&one), GPU_uniform(&mtex->colfac), mtex->blendtype, rgb);
- }
- }
-}
-
-static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
-{
- Material *ma = shi->mat;
- GPUMaterial *mat = shi->gpumat;
- GPUNodeLink *lv, *dist, *is, *inp, *i;
- GPUNodeLink *outcol, *specfac, *t, *shadfac = NULL, *lcol;
- float one = 1.0f;
-
- if ((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
- return;
-
- GPUNodeLink *vn = shi->vn;
- GPUNodeLink *view = shi->view;
-
- GPUNodeLink *visifac = lamp_get_visibility(mat, lamp, &lv, &dist);
-
-#if 0
- if (ma->mode & MA_TANGENT_V)
- GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);
-#endif
-
- GPU_link(mat, "shade_inp", vn, lv, &inp);
-
- if (lamp->mode & LA_NO_DIFF) {
- GPU_link(mat, "shade_is_no_diffuse", &is);
- }
- else if (lamp->type == LA_HEMI) {
- GPU_link(mat, "shade_is_hemi", inp, &is);
- }
- else {
- if (lamp->type == LA_AREA) {
- float area[4][4] = {{0.0f}}, areasize = 0.0f;
-
- mat->dynproperty |= DYN_LAMP_VEC | DYN_LAMP_CO;
- GPU_link(mat, "shade_inp_area",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob),
- GPU_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn,
- GPU_uniform((float *)area),
- GPU_uniform(&areasize),
- GPU_uniform(&lamp->k), &inp);
- }
-
- is = inp; /* Lambert */
-
- {
- if (ma->diff_shader == MA_DIFF_ORENNAYAR)
- GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view,
- GPU_uniform(&ma->roughness), &is);
- else if (ma->diff_shader == MA_DIFF_TOON)
- GPU_link(mat, "shade_diffuse_toon", vn, lv, view,
- GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
- else if (ma->diff_shader == MA_DIFF_MINNAERT)
- GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view,
- GPU_uniform(&ma->darkness), &is);
- else if (ma->diff_shader == MA_DIFF_FRESNEL)
- GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view,
- GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
- }
- }
-
- if (ma->shade_flag & MA_CUBIC)
- GPU_link(mat, "shade_cubic", is, &is);
-
- i = is;
- GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
-
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
- shade_light_textures(mat, lamp, &lcol);
- GPU_link(mat, "shade_mul_value_v3",
- GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), lcol, &lcol);
-
-#if 0
- if (ma->mode & MA_TANGENT_VN)
- GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);
-#endif
-
- /* this replaces if (i > 0.0) conditional until that is supported */
- /* done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i); */
-
- if (ma->mode & MA_SHADOW) {
- {
- mat->dynproperty |= DYN_LAMP_PERSMAT;
-
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
- GPU_link(mat, "test_shadowbuf_vsm",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), inp, &shadfac);
- }
- else {
- GPU_link(mat, "test_shadowbuf",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- GPU_uniform(&lamp->bias), inp, &shadfac);
- }
-
- if (lamp->mode & LA_ONLYSHADOW) {
- GPUNodeLink *shadrgb;
- GPU_link(mat, "shade_only_shadow", i, shadfac,
- GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob),
- GPU_uniform(lamp->shadow_color), &shadrgb);
-
- if (!(lamp->mode & LA_NO_DIFF)) {
- GPU_link(mat, "shade_only_shadow_diffuse", shadrgb, shi->rgb,
- shr->diff, &shr->diff);
- }
-
- if (!(lamp->mode & LA_NO_SPEC)) {
- GPU_link(mat, "shade_only_shadow_specular", shadrgb, shi->specrgb,
- shr->spec, &shr->spec);
- }
-
- add_user_list(&mat->lamps, lamp);
- return;
- }
- }
- }
- else if (lamp->mode & LA_ONLYSHADOW) {
- add_user_list(&mat->lamps, lamp);
- return;
- }
- else
- GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
-
- if (GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
- if (!(lamp->mode & LA_NO_DIFF)) {
- GPUNodeLink *rgb;
- GPU_link(mat, "shade_mul_value", i, lcol, &rgb);
- GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
- GPU_link(mat, "mix_mult", shadfac, rgb, GPU_uniform(lamp->shadow_color), &rgb);
- GPU_link(mat, "mtex_value_invert", shadfac, &shadfac);
- add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
- }
- }
-
- if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
- (GPU_link_changed(shi->spec) || ma->spec != 0.0f))
- {
- if (lamp->type == LA_HEMI) {
- GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
- GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
- GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
- }
- else {
- if (ma->spec_shader == MA_SPEC_PHONG) {
- GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac);
- }
- else if (ma->spec_shader == MA_SPEC_COOKTORR) {
- GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac);
- }
- else if (ma->spec_shader == MA_SPEC_BLINN) {
- GPU_link(mat, "shade_blinn_spec", vn, lv, view,
- GPU_uniform(&ma->refrac), shi->har, &specfac);
- }
- else if (ma->spec_shader == MA_SPEC_WARDISO) {
- GPU_link(mat, "shade_wardiso_spec", vn, lv, view,
- GPU_uniform(&ma->rms), &specfac);
- }
- else {
- GPU_link(mat, "shade_toon_spec", vn, lv, view,
- GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
- }
-
- if (lamp->type == LA_AREA)
- GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
-
- GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t);
-
- if (ma->mode & MA_RAMP_SPEC) {
- GPUNodeLink *spec;
- do_specular_ramp(shi, specfac, t, &spec);
- GPU_link(mat, "shade_add_spec", t, lcol, spec, &outcol);
- GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
- }
- else {
- GPU_link(mat, "shade_add_spec", t, lcol, shi->specrgb, &outcol);
- GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec);
- }
- }
- }
-
- add_user_list(&mat->lamps, lamp);
-}
-
-static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
-{
- Base *base;
- Scene *sce_iter;
-
- for (SETLOOPER(shi->gpumat->scene, sce_iter, base)) {
- Object *ob = base->object;
-
- if (ob->type == OB_LAMP) {
- GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
- if (lamp)
- shade_one_light(shi, shr, lamp);
- }
-
- /* TODO: won't fix because will be removed. */
-#if 0
- if (ob->transflag & OB_DUPLI) {
- ListBase *lb = object_duplilist(G.main->depsgraph, shi->gpumat->scene, ob);
-
- for (DupliObject *dob = lb->first; dob; dob = dob->next) {
- Object *ob_iter = dob->ob;
-
- if (ob_iter->type == OB_LAMP) {
- float omat[4][4];
- copy_m4_m4(omat, ob_iter->obmat);
- copy_m4_m4(ob_iter->obmat, dob->mat);
-
- GPULamp *lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
- if (lamp)
- shade_one_light(shi, shr, lamp);
-
- copy_m4_m4(ob_iter->obmat, omat);
- }
- }
-
- free_object_duplilist(lb);
- }
-#endif
- }
-
- /* prevent only shadow lamps from producing negative colors.*/
- GPU_link(shi->gpumat, "shade_clamp_positive", shr->spec, &shr->spec);
- GPU_link(shi->gpumat, "shade_clamp_positive", shr->diff, &shr->diff);
-}
-
-static void texture_rgb_blend(
- GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
- int blendtype, GPUNodeLink **in)
-{
- switch (blendtype) {
- case MTEX_BLEND:
- GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in);
- break;
- case MTEX_MUL:
- GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in);
- break;
- case MTEX_SCREEN:
- GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in);
- break;
- case MTEX_OVERLAY:
- GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in);
- break;
- case MTEX_SUB:
- GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in);
- break;
- case MTEX_ADD:
- GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in);
- break;
- case MTEX_DIV:
- GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in);
- break;
- case MTEX_DIFF:
- GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in);
- break;
- case MTEX_DARK:
- GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in);
- break;
- case MTEX_LIGHT:
- GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in);
- break;
- case MTEX_BLEND_HUE:
- GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in);
- break;
- case MTEX_BLEND_SAT:
- GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in);
- break;
- case MTEX_BLEND_VAL:
- GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in);
- break;
- case MTEX_BLEND_COLOR:
- GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
- break;
- case MTEX_SOFT_LIGHT:
- GPU_link(mat, "mtex_rgb_soft", out, tex, fact, facg, in);
- break;
- case MTEX_LIN_LIGHT:
- GPU_link(mat, "mtex_rgb_linear", out, tex, fact, facg, in);
- break;
- default:
- GPU_link(mat, "set_rgb_zero", &in);
- break;
- }
-}
-
-static void texture_value_blend(
- GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg,
- int blendtype, GPUNodeLink **in)
-{
- switch (blendtype) {
- case MTEX_BLEND:
- GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in);
- break;
- case MTEX_MUL:
- GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in);
- break;
- case MTEX_SCREEN:
- GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in);
- break;
- case MTEX_SUB:
- GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in);
- break;
- case MTEX_ADD:
- GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in);
- break;
- case MTEX_DIV:
- GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in);
- break;
- case MTEX_DIFF:
- GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in);
- break;
- case MTEX_DARK:
- GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in);
- break;
- case MTEX_LIGHT:
- GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in);
- break;
- default:
- GPU_link(mat, "set_value_zero", &in);
- break;
- }
-}
-
-static void do_material_tex(GPUShadeInput *shi)
-{
- Material *ma = shi->mat;
- GPUMaterial *mat = shi->gpumat;
- MTex *mtex;
- Tex *tex;
- GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
- GPUNodeLink *texco_norm, *texco_orco, *texco_object;
- GPUNodeLink *texco_global, *texco_uv = NULL;
- GPUNodeLink *newnor, *orn;
- float one = 1.0f;
- int rgbnor, talpha;
- bool init_done = false;
- int iBumpSpacePrev = 0; /* Not necessary, quieting gcc warning. */
- GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude;
- int iFirstTimeNMap = 1;
- bool found_deriv_map = false;
-
- GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
-
- GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
- GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
- GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
- GPU_builtin(GPU_VIEW_POSITION), &texco_object);
-#if 0
- GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
-#endif
- GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- GPU_builtin(GPU_VIEW_POSITION), &texco_global);
-
- orn = texco_norm;
-
- /* go over texture slots */
- for (int tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) {
- /* separate tex switching */
- if (ma->septex & (1 << tex_nr)) continue;
-
- if (ma->mtex[tex_nr]) {
- mtex = ma->mtex[tex_nr];
-
- tex = mtex->tex;
- if (tex == NULL) continue;
-
- /* which coords */
- if (mtex->texco == TEXCO_ORCO)
- texco = texco_orco;
- else if (mtex->texco == TEXCO_OBJECT)
- texco = texco_object;
- else if (mtex->texco == TEXCO_NORM)
- texco = orn;
- else if (mtex->texco == TEXCO_TANGENT)
- texco = texco_object;
- else if (mtex->texco == TEXCO_GLOB)
- texco = texco_global;
- else if (mtex->texco == TEXCO_REFL) {
- GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
- texco = shi->ref;
- }
- else if (mtex->texco == TEXCO_UV) {
- if (1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
- GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
- /*lastuvname = mtex->uvname;*/ /*UNUSED*/
- }
- texco = texco_uv;
- }
- else
- continue;
-
- /* in case of uv, this would just undo a multiplication in texco_uv */
- if (mtex->texco != TEXCO_UV)
- GPU_link(mat, "mtex_2d_mapping", texco, &texco);
-
- if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
- GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
-
- float ofs[3] = {
- mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0],
- mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1],
- 0.0f
- };
-
- if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
- GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
-
- talpha = 0;
-
- if (tex && tex->ima &&
- ((tex->type == TEX_IMAGE) ||
- ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL))))
- {
- if (tex->type == TEX_IMAGE) {
- GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
- }
- else {
- GPU_link(mat, "mtex_cube_map_refl",
- GPU_cube_map(tex->ima, &tex->iuser, false), shi->view, shi->vn,
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- GPU_builtin(GPU_VIEW_MATRIX), &tin, &trgb);
- }
- rgbnor = TEX_RGB;
-
- talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0);
- }
- else {
- continue;
- }
-
- /* texture output */
- if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
- GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
- rgbnor -= TEX_RGB;
- }
-
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgbnor & TEX_RGB)
- GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
- else
- GPU_link(mat, "mtex_value_invert", tin, &tin);
- }
-
- if (mtex->texflag & MTEX_STENCIL) {
- if (rgbnor & TEX_RGB)
- GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
- else
- GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
- }
-
- /* mapping */
- if (mtex->mapto & (MAP_COL | MAP_COLSPEC | MAP_COLMIR)) {
- /* stencil maps on the texture control slider, not texture intensity value */
- if ((rgbnor & TEX_RGB) == 0) {
- GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
- }
- else {
- GPU_link(mat, "set_rgba", trgb, &tcol);
-
- if (mtex->mapto & MAP_ALPHA)
- GPU_link(mat, "set_value", stencil, &tin);
- else if (talpha)
- GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
- else
- GPU_link(mat, "set_value_one", &tin);
- }
-
- if ((tex->type == TEX_IMAGE) ||
- ((tex->type == TEX_ENVMAP) && (mtex->texco == TEXCO_REFL)))
- {
- if (GPU_material_do_color_management(mat)) {
- GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol);
- }
- }
-
- if (mtex->mapto & MAP_COL) {
- GPUNodeLink *colfac;
-
- if (mtex->colfac == 1.0f) colfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
-
- texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
- }
-
- if (mtex->mapto & MAP_COLSPEC) {
- GPUNodeLink *colspecfac;
-
- if (mtex->colspecfac == 1.0f) colspecfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac);
-
- texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb);
- }
-
- if (mtex->mapto & MAP_COLMIR) {
- GPUNodeLink *colmirfac;
-
- if (mtex->mirrfac == 1.0f) colmirfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->mirrfac), stencil, &colmirfac);
-
- /* exception for envmap only */
- if (tex->type == TEX_ENVMAP && mtex->blendtype == MTEX_BLEND) {
- GPU_link(mat, "mtex_mirror", tcol, shi->refcol, tin, colmirfac, &shi->refcol);
- }
- else
- texture_rgb_blend(mat, tcol, shi->mir, tin, colmirfac, mtex->blendtype, &shi->mir);
- }
- }
-
- if (mtex->mapto & MAP_NORM) {
- if (tex->type == TEX_IMAGE) {
- found_deriv_map = tex->imaflag & TEX_DERIVATIVEMAP;
-
- if (tex->imaflag & TEX_NORMALMAP) {
- /* normalmap image */
- GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser, true), &tnor);
-
- if (mtex->norfac < 0.0f)
- GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
-
- if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
- if (iFirstTimeNMap != 0) {
- // use unnormalized normal (this is how we bake it - closer to gamedev)
- GPUNodeLink *vNegNorm;
- GPU_link(mat, "vec_math_negate",
- GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm);
- GPU_link(mat, "mtex_nspace_tangent",
- GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor);
- iFirstTimeNMap = 0;
- }
- else { /* otherwise use accumulated perturbations */
- GPU_link(mat, "mtex_nspace_tangent",
- GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
- }
- }
- else if (mtex->normapspace == MTEX_NSPACE_OBJECT) {
- /* transform normal by object then view matrix */
- GPU_link(mat, "mtex_nspace_object", tnor, &newnor);
- }
- else if (mtex->normapspace == MTEX_NSPACE_WORLD) {
- /* transform normal by view matrix */
- GPU_link(mat, "mtex_nspace_world", GPU_builtin(GPU_VIEW_MATRIX), tnor, &newnor);
- }
- else {
- /* no transform, normal in camera space */
- newnor = tnor;
- }
-
- float norfac = min_ff(fabsf(mtex->norfac), 1.0f);
-
- if (norfac == 1.0f && !GPU_link_changed(stencil)) {
- shi->vn = newnor;
- }
- else {
- tnorfac = GPU_uniform(&norfac);
-
- if (GPU_link_changed(stencil))
- GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
-
- GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
- }
-
- }
- else if (found_deriv_map ||
- (mtex->texflag & (MTEX_3TAP_BUMP | MTEX_5TAP_BUMP | MTEX_BICUBIC_BUMP)))
- {
- /* ntap bumpmap image */
- int iBumpSpace;
- float ima_x, ima_y;
-
- float imag_tspace_dimension_x = 1024.0f; /* only used for texture space variant */
- float aspect = 1.0f;
-
- GPUNodeLink *vR1, *vR2;
- GPUNodeLink *dBs, *dBt, *fDet;
-
- float hScale = 0.1f; /* compatibility adjustment factor for all bumpspace types */
- if (mtex->texflag & MTEX_BUMP_TEXTURESPACE)
- hScale = 13.0f; /* factor for scaling texspace bumps */
- else if (found_deriv_map)
- hScale = 1.0f;
-
- /* resolve texture resolution */
- if ((mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
- ima_x = 512.0f; ima_y = 512.0f; /* prevent calling textureSize, glsl 1.3 only */
- if (ibuf) {
- ima_x = ibuf->x;
- ima_y = ibuf->y;
- aspect = (float)ima_y / ima_x;
- }
- BKE_image_release_ibuf(tex->ima, ibuf, NULL);
- }
-
- /* The negate on norfac is done because the
- * normal in the renderer points inward which corresponds
- * to inverting the bump map. Should this ever change
- * this negate must be removed. */
- float norfac = -hScale * mtex->norfac;
- if (found_deriv_map) {
- float fVirtDim = sqrtf(fabsf(ima_x * mtex->size[0] * ima_y * mtex->size[1]));
- norfac /= MAX2(fVirtDim, FLT_EPSILON);
- }
-
- tnorfac = GPU_uniform(&norfac);
-
- if (found_deriv_map)
- GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac);
-
- if (GPU_link_changed(stencil))
- GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
-
- if (!init_done) {
- /* copy shi->vn to vNorg and vNacc, set magnitude to 1 */
- GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude);
- iBumpSpacePrev = 0;
- init_done = true;
- }
-
- // find current bump space
- if (mtex->texflag & MTEX_BUMP_OBJECTSPACE)
- iBumpSpace = 1;
- else if (mtex->texflag & MTEX_BUMP_TEXTURESPACE)
- iBumpSpace = 2;
- else
- iBumpSpace = 4; /* ViewSpace */
-
- /* re-initialize if bump space changed */
- if (iBumpSpacePrev != iBumpSpace) {
- GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
-
- if (mtex->texflag & MTEX_BUMP_OBJECTSPACE)
- GPU_link(mat, "mtex_bump_init_objspace",
- surf_pos, vNorg,
- GPU_builtin(GPU_VIEW_MATRIX),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
- GPU_builtin(GPU_OBJECT_MATRIX),
- GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
- fPrevMagnitude, vNacc,
- &fPrevMagnitude, &vNacc,
- &vR1, &vR2, &fDet);
-
- else if (mtex->texflag & MTEX_BUMP_TEXTURESPACE)
- GPU_link(mat, "mtex_bump_init_texturespace",
- surf_pos, vNorg,
- fPrevMagnitude, vNacc,
- &fPrevMagnitude, &vNacc,
- &vR1, &vR2, &fDet);
-
- else
- GPU_link(mat, "mtex_bump_init_viewspace",
- surf_pos, vNorg,
- fPrevMagnitude, vNacc,
- &fPrevMagnitude, &vNacc,
- &vR1, &vR2, &fDet);
-
- iBumpSpacePrev = iBumpSpace;
- }
-
-
- if (found_deriv_map) {
- GPU_link(mat, "mtex_bump_deriv",
- texco, GPU_image(tex->ima, &tex->iuser, true),
- GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac,
- &dBs, &dBt);
- }
- else if (mtex->texflag & MTEX_3TAP_BUMP)
- GPU_link(mat, "mtex_bump_tap3",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
- &dBs, &dBt);
- else if (mtex->texflag & MTEX_5TAP_BUMP)
- GPU_link(mat, "mtex_bump_tap5",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
- &dBs, &dBt);
- else if (mtex->texflag & MTEX_BICUBIC_BUMP) {
- if (GPU_bicubic_bump_support()) {
- GPU_link(mat, "mtex_bump_bicubic",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
- &dBs, &dBt);
- }
- else {
- GPU_link(mat, "mtex_bump_tap5",
- texco, GPU_image(tex->ima, &tex->iuser, true), tnorfac,
- &dBs, &dBt);
- }
- }
-
-
- if (mtex->texflag & MTEX_BUMP_TEXTURESPACE) {
- float imag_tspace_dimension_y = aspect * imag_tspace_dimension_x;
- GPU_link(mat, "mtex_bump_apply_texspace",
- fDet, dBs, dBt, vR1, vR2,
- GPU_image(tex->ima, &tex->iuser, true), texco,
- GPU_uniform(&imag_tspace_dimension_x),
- GPU_uniform(&imag_tspace_dimension_y), vNacc,
- &vNacc, &shi->vn);
- }
- else
- GPU_link(mat, "mtex_bump_apply",
- fDet, dBs, dBt, vR1, vR2, vNacc,
- &vNacc, &shi->vn);
-
- }
- }
-
- GPU_link(mat, "vec_math_negate", shi->vn, &orn);
- }
-
- if ((mtex->mapto & MAP_VARS)) {
- if (rgbnor & TEX_RGB) {
- if (talpha)
- GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
- else
- GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
- }
-
- if (mtex->mapto & MAP_REF) {
- GPUNodeLink *difffac;
-
- if (mtex->difffac == 1.0f) difffac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac);
-
- texture_value_blend(
- mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac,
- mtex->blendtype, &shi->refl);
- GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
- }
- if (mtex->mapto & MAP_SPEC) {
- GPUNodeLink *specfac;
-
- if (mtex->specfac == 1.0f) specfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac);
-
- texture_value_blend(
- mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac,
- mtex->blendtype, &shi->spec);
- GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
- }
- if (mtex->mapto & MAP_EMIT) {
- GPUNodeLink *emitfac;
-
- if (mtex->emitfac == 1.0f) emitfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac);
-
- texture_value_blend(
- mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac,
- mtex->blendtype, &shi->emit);
- GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
- }
- if (mtex->mapto & MAP_HAR) {
- GPUNodeLink *hardfac;
-
- if (mtex->hardfac == 1.0f) hardfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac);
-
- GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
- texture_value_blend(
- mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac,
- mtex->blendtype, &shi->har);
- GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
- }
- if (mtex->mapto & MAP_ALPHA) {
- GPUNodeLink *alphafac;
-
- if (mtex->alphafac == 1.0f) alphafac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac);
-
- texture_value_blend(
- mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac,
- mtex->blendtype, &shi->alpha);
- GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
- }
- if (mtex->mapto & MAP_AMB) {
- GPUNodeLink *ambfac;
-
- if (mtex->ambfac == 1.0f) ambfac = stencil;
- else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac);
-
- texture_value_blend(
- mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac,
- mtex->blendtype, &shi->amb);
- GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
- }
- }
- }
- }
-}
-
-void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
-{
- float one = 1.0f;
-
- memset(shi, 0, sizeof(*shi));
-
- shi->gpumat = mat;
- shi->mat = ma;
-
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, ma), &shi->rgb);
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, ma), &shi->specrgb);
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->mirr, GPU_DYNAMIC_MAT_MIR, ma), &shi->mir);
- GPU_link(mat, "set_rgba_zero", &shi->refcol);
- GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
-
- if (mat->alpha)
- GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->alpha, GPU_DYNAMIC_MAT_ALPHA, ma), &shi->alpha);
- else
- GPU_link(mat, "set_value", GPU_uniform(&one), &shi->alpha);
-
- GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->ref, GPU_DYNAMIC_MAT_REF, ma), &shi->refl);
- GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->spec, GPU_DYNAMIC_MAT_SPEC, ma), &shi->spec);
- GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->emit, GPU_DYNAMIC_MAT_EMIT, ma), &shi->emit);
- GPU_link(mat, "set_value", GPU_dynamic_uniform((float *)&ma->har, GPU_DYNAMIC_MAT_HARD, ma), &shi->har);
- GPU_link(mat, "set_value", GPU_dynamic_uniform(&ma->amb, GPU_DYNAMIC_MAT_AMB, ma), &shi->amb);
- GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra);
- GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
- GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
- if (GPU_material_do_color_management(mat))
- GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol);
- GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
-}
-
-void GPU_mist_update_enable(short enable)
-{
- GPUWorld.mistenabled = (float)enable;
-}
-
-void GPU_mist_update_values(int type, float start, float dist, float inten, float color[3])
-{
- GPUWorld.mistype = (float)type;
- GPUWorld.miststart = start;
- GPUWorld.mistdistance = dist;
- GPUWorld.mistintensity = inten;
- copy_v3_v3(GPUWorld.mistcol, color);
- GPUWorld.mistcol[3] = 1.0f;
-}
-
-void GPU_horizon_update_color(float color[3])
-{
- copy_v3_v3(GPUWorld.horicol, color);
-}
-
-void GPU_ambient_update_color(float color[3])
-{
- copy_v3_v3(GPUWorld.ambcol, color);
- GPUWorld.ambcol[3] = 1.0f;
-}
-
-void GPU_zenith_update_color(float color[3])
-{
- copy_v3_v3(GPUWorld.zencol, color);
-}
-
-void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
-{
- GPUMaterial *mat = shi->gpumat;
- GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
- Material *ma = shi->mat;
- World *world = mat->scene->world;
- float linfac, logfac;
-
- memset(shr, 0, sizeof(*shr));
-
- if (ma->mode & MA_VERTEXCOLP)
- shi->rgb = shi->vcol;
-
- do_material_tex(shi);
-
- if (ma->mode & MA_SHLESS) {
- GPU_link(mat, "set_rgb", shi->rgb, &shr->diff);
- GPU_link(mat, "set_rgb_zero", &shr->spec);
- GPU_link(mat, "set_value", shi->alpha, &shr->alpha);
- shr->combined = shr->diff;
- }
- else {
- if (GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
- if ((ma->mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == MA_VERTEXCOL) {
- GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
- GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
- }
- else
- GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
- }
- else
- GPU_link(mat, "set_rgb_zero", &shr->diff);
-
- GPU_link(mat, "set_rgb_zero", &shr->spec);
-
- material_lights(shi, shr);
-
- shr->combined = shr->diff;
-
- GPU_link(mat, "set_value", shi->alpha, &shr->alpha);
-
- if (world) {
- /* exposure correction */
- if (world->exp != 0.0f || world->range != 1.0f) {
- linfac = 1.0f + powf((2.0f * world->exp + 0.5f), -10);
- logfac = logf((linfac - 1.0f) / linfac) / world->range;
-
- GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
- GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
-
- GPU_link(mat, "shade_exposure_correct", shr->combined,
- ulinfac, ulogfac, &shr->combined);
- GPU_link(mat, "shade_exposure_correct", shr->spec,
- ulinfac, ulogfac, &shr->spec);
- }
-
- /* environment lighting */
- if ((world->mode & WO_ENV_LIGHT) &&
- (mat->scene->r.mode & R_SHADOW) &&
- !BKE_scene_use_new_shading_nodes(mat->scene))
- {
- if ((world->ao_env_energy != 0.0f) && (GPU_link_changed(shi->amb) || ma->amb != 0.0f) &&
- (GPU_link_changed(shi->refl) || ma->ref != 0.0f))
- {
- if (world->aocolor != WO_AOPLAIN) {
- if (!(is_zero_v3(&world->horr) & is_zero_v3(&world->zenr))) {
- GPUNodeLink *fcol, *f;
- GPU_link(mat, "math_multiply", shi->amb, shi->refl, &f);
- GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f);
- GPU_link(mat, "shade_mul_value", f, shi->rgb, &fcol);
- GPU_link(mat, "env_apply", shr->combined,
- GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL),
- GPU_dynamic_uniform(GPUWorld.zencol, GPU_DYNAMIC_ZENITH_COLOR, NULL), fcol,
- GPU_builtin(GPU_VIEW_MATRIX), shi->vn, &shr->combined);
- }
- }
- else {
- GPUNodeLink *f;
- GPU_link(mat, "math_multiply", shi->amb, shi->refl, &f);
- GPU_link(mat, "math_multiply", f, GPU_uniform(&world->ao_env_energy), &f);
- GPU_link(mat, "shade_maddf", shr->combined, f, shi->rgb, &shr->combined);
- }
- }
- }
-
- /* ambient color */
- if (GPU_link_changed(shi->amb) || ma->amb != 0.0f) {
- GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
- GPU_dynamic_uniform(GPUWorld.ambcol, GPU_DYNAMIC_AMBIENT_COLOR, NULL),
- &shr->combined);
- }
- }
-
- if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP | MA_RAYTRANSP))) {
- if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f) {
- GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra,
- shi->alpha, &shr->alpha);
- }
- }
-
- if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
- if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
-
- if (GPU_link_changed(shi->refcol))
- GPU_link(mat, "shade_add_mirror", shi->mir, shi->refcol, shr->combined, &shr->combined);
-
- if (GPU_link_changed(shi->spec) || ma->spec != 0.0f)
- GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
- }
-
- GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
-
- if (ma->shade_flag & MA_OBCOLOR)
- GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
-
- if (!(ma->mode & MA_NOMIST)) {
- GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_uniform(&GPUWorld.mistenabled, GPU_DYNAMIC_MIST_ENABLE, NULL),
- GPU_dynamic_uniform(&GPUWorld.miststart, GPU_DYNAMIC_MIST_START, NULL),
- GPU_dynamic_uniform(&GPUWorld.mistdistance, GPU_DYNAMIC_MIST_DISTANCE, NULL),
- GPU_dynamic_uniform(&GPUWorld.mistype, GPU_DYNAMIC_MIST_TYPE, NULL),
- GPU_dynamic_uniform(&GPUWorld.mistintensity, GPU_DYNAMIC_MIST_INTENSITY, NULL), &mistfac);
-
- GPU_link(mat, "mix_blend", mistfac, shr->combined,
- GPU_dynamic_uniform(GPUWorld.mistcol, GPU_DYNAMIC_MIST_COLOR, NULL), &shr->combined);
- }
-
- if (!mat->alpha) {
- if (world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
- GPU_link(mat, "shade_world_mix", GPU_dynamic_uniform(GPUWorld.horicol, GPU_DYNAMIC_HORIZON_COLOR, NULL),
- shr->combined, &shr->combined);
-
- GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
- }
-
- if (ma->shade_flag & MA_OBCOLOR) {
- mat->obcolalpha = 1;
- GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
- }
-}
-
-static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
-{
- GPUShadeInput shi;
- GPUShadeResult shr;
-
- GPU_shadeinput_set(mat, ma, &shi);
- GPU_shaderesult_set(&shi, &shr);
-
- return shr.combined;
-}
-
-static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
-{
- static float roughness = 0.0f;
- GPUNodeLink *outlink;
-
- GPU_link(mat, "node_bsdf_diffuse",
- GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
-
- return outlink;
-}
-
-static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
-{
- GPUNodeLink *outlink;
-
- /* some explanations here:
- * matcap normal holds the normal remapped to the 0.0 - 1.0 range. To take advantage of flat shading, we abuse
- * the built in secondary color of opengl. Color is just the regular color, which should include mask value too.
- * This also needs flat shading so we use the primary opengl color built-in */
- GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview),
- GPU_opengl_builtin(GPU_MATCAP_NORMAL), GPU_opengl_builtin(GPU_COLOR), &outlink);
-
- return outlink;
-}
-
-/* new solid draw mode with glsl matcaps */
-GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma, bool use_opensubdiv)
-{
- GPUMaterial *mat;
- GPUNodeLink *outlink;
- LinkData *link;
-
- for (link = ma->gpumaterial.first; link; link = link->next) {
- GPUMaterial *current_material = (GPUMaterial *)link->data;
- if (current_material->scene == scene &&
- current_material->is_opensubdiv == use_opensubdiv)
- {
- return current_material;
- }
- }
-
- /* allocate material */
- mat = GPU_material_construct_begin(ma);
- mat->scene = scene;
- mat->type = GPU_MATERIAL_TYPE_MESH;
- mat->is_opensubdiv = use_opensubdiv;
-
- if (ma->preview && ma->preview->rect[0]) {
- outlink = gpu_material_preview_matcap(mat, ma);
- }
- else {
- outlink = gpu_material_diffuse_bsdf(mat, ma);
- }
-
- GPU_material_output_link(mat, outlink);
-
- gpu_material_construct_end(mat, "matcap_pass");
-
- /* note that even if building the shader fails in some way, we still keep
- * it to avoid trying to compile again and again, and simple do not use
- * the actual shader on drawing */
-
- link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
- link->data = mat;
- BLI_addtail(&ma->gpumaterial, link);
-
- return mat;
-}
-
-static void do_world_tex(GPUShadeInput *shi, struct World *wo, GPUNodeLink **hor, GPUNodeLink **zen, GPUNodeLink **blend)
-{
- GPUMaterial *mat = shi->gpumat;
- GPUNodeLink *texco, *tin, *trgb, *stencil, *tcol, *zenfac;
- MTex *mtex;
- Tex *tex;
- float ofs[3], zero = 0.0f;
- int tex_nr, rgbnor;
-
- GPU_link(mat, "set_value_one", &stencil);
- /* go over texture slots */
- for (tex_nr = 0; tex_nr < MAX_MTEX; tex_nr++) {
- if (wo->mtex[tex_nr]) {
- mtex = wo->mtex[tex_nr];
- tex = mtex->tex;
- if (tex == NULL || !tex->ima || (tex->type != TEX_IMAGE && tex->type != TEX_ENVMAP))
- continue;
- /* which coords */
- if (mtex->texco == TEXCO_VIEW || mtex->texco == TEXCO_GLOB) {
- if (tex->type == TEX_IMAGE)
- texco = GPU_builtin(GPU_VIEW_POSITION);
- else if (tex->type == TEX_ENVMAP)
- GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco);
- }
- else if (mtex->texco == TEXCO_EQUIRECTMAP || mtex->texco == TEXCO_ANGMAP) {
- if ((tex->type == TEX_IMAGE && wo->skytype & WO_SKYREAL) || tex->type == TEX_ENVMAP)
- GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &texco);
- else
- texco = GPU_builtin(GPU_VIEW_POSITION);
- }
- else
- continue;
- GPU_link(mat, "texco_norm", texco, &texco);
- if (tex->type == TEX_IMAGE && !(wo->skytype & WO_SKYREAL)) {
- GPU_link(mat, "mtex_2d_mapping", texco, &texco);
- }
- if (mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) {
- float size[3] = { mtex->size[0], mtex->size[1], mtex->size[2] };
- if (tex->type == TEX_ENVMAP) {
- size[1] = mtex->size[2];
- size[2] = mtex->size[1];
- }
- GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(size), &texco);
- }
- ofs[0] = mtex->ofs[0] + 0.5f - 0.5f * mtex->size[0];
- if (tex->type == TEX_ENVMAP) {
- ofs[1] = -mtex->ofs[2] + 0.5f - 0.5f * mtex->size[2];
- ofs[2] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1];
- }
- else {
- ofs[1] = mtex->ofs[1] + 0.5f - 0.5f * mtex->size[1];
- ofs[2] = 0.0;
- }
- if (ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
- GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
- if (mtex->texco == TEXCO_EQUIRECTMAP) {
- GPU_link(mat, "node_tex_environment_equirectangular", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
- }
- else if (mtex->texco == TEXCO_ANGMAP) {
- GPU_link(mat, "node_tex_environment_mirror_ball", texco, GPU_image(tex->ima, &tex->iuser, false), &trgb);
- }
- else {
- if (tex->type == TEX_ENVMAP)
- GPU_link(mat, "mtex_cube_map", texco, GPU_cube_map(tex->ima, &tex->iuser, false), &tin, &trgb);
- else if (tex->type == TEX_IMAGE)
- GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, false), &tin, &trgb);
- }
- rgbnor = TEX_RGB;
- if (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)
- if (GPU_material_do_color_management(mat))
- GPU_link(mat, "srgb_to_linearrgb", trgb, &trgb);
- /* texture output */
- if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
- GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
- rgbnor -= TEX_RGB;
- }
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgbnor & TEX_RGB)
- GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
- else
- GPU_link(mat, "mtex_value_invert", tin, &tin);
- }
- if (mtex->texflag & MTEX_STENCIL) {
- if (rgbnor & TEX_RGB)
- GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
- else
- GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
- }
- else {
- if (rgbnor & TEX_RGB)
- GPU_link(mat, "mtex_alpha_multiply_value", trgb, stencil, &trgb);
- else
- GPU_link(mat, "math_multiply", stencil, tin, &tin);
- }
- /* color mapping */
- if (mtex->mapto & (WOMAP_HORIZ + WOMAP_ZENUP + WOMAP_ZENDOWN)) {
- if ((rgbnor & TEX_RGB) == 0)
- GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &trgb);
- else
- GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
- GPU_link(mat, "set_rgb", trgb, &tcol);
- if (mtex->mapto & WOMAP_HORIZ) {
- texture_rgb_blend(mat, tcol, *hor, tin, GPU_uniform(&mtex->colfac), mtex->blendtype, hor);
- }
- if (mtex->mapto & (WOMAP_ZENUP + WOMAP_ZENDOWN)) {
- GPU_link(mat, "set_value_zero", &zenfac);
- if (wo->skytype & WO_SKYREAL) {
- if (mtex->mapto & WOMAP_ZENUP) {
- if (mtex->mapto & WOMAP_ZENDOWN) {
- GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac),
- GPU_uniform(&mtex->zendownfac), &zenfac);
- }
- else {
- GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&mtex->zenupfac),
- GPU_uniform(&zero), &zenfac);
- }
- }
- else if (mtex->mapto & WOMAP_ZENDOWN) {
- GPU_link(mat, "world_zen_mapping", shi->view, GPU_uniform(&zero),
- GPU_uniform(&mtex->zendownfac), &zenfac);
- }
- }
- else {
- if (mtex->mapto & WOMAP_ZENUP)
- GPU_link(mat, "set_value", GPU_uniform(&mtex->zenupfac), &zenfac);
- else if (mtex->mapto & WOMAP_ZENDOWN)
- GPU_link(mat, "set_value", GPU_uniform(&mtex->zendownfac), &zenfac);
- }
- texture_rgb_blend(mat, tcol, *zen, tin, zenfac, mtex->blendtype, zen);
- }
- }
- if (mtex->mapto & WOMAP_BLEND && wo->skytype & WO_SKYBLEND) {
- if (rgbnor & TEX_RGB)
- GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
- texture_value_blend(mat, GPU_uniform(&mtex->def_var), *blend, tin, GPU_uniform(&mtex->blendfac), mtex->blendtype, blend);
- }
- }
- }
-}
-
-static void gpu_material_old_world(struct GPUMaterial *mat, struct World *wo)
-{
- GPUShadeInput shi;
- GPUShadeResult shr;
- GPUNodeLink *hor, *zen, *ray, *blend;
-
- shi.gpumat = mat;
-
- for (int i = 0; i < MAX_MTEX; i++) {
- if (wo->mtex[i] && wo->mtex[i]->tex) {
- wo->skytype |= WO_SKYTEX;
- break;
- }
- }
- if ((wo->skytype & (WO_SKYBLEND + WO_SKYTEX)) == 0) {
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &shr.combined);
- }
- else {
- GPU_link(mat, "set_rgb_zero", &shi.rgb);
- GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &ray);
- if (wo->skytype & WO_SKYPAPER)
- GPU_link(mat, "world_paper_view", GPU_builtin(GPU_VIEW_POSITION), &shi.view);
- else
- GPU_link(mat, "shade_view", ray, &shi.view);
- if (wo->skytype & WO_SKYBLEND) {
- if (wo->skytype & WO_SKYPAPER) {
- if (wo->skytype & WO_SKYREAL)
- GPU_link(mat, "world_blend_paper_real", GPU_builtin(GPU_VIEW_POSITION), &blend);
- else
- GPU_link(mat, "world_blend_paper", GPU_builtin(GPU_VIEW_POSITION), &blend);
- }
- else {
- if (wo->skytype & WO_SKYREAL)
- GPU_link(mat, "world_blend_real", ray, &blend);
- else
- GPU_link(mat, "world_blend", ray, &blend);
- }
- }
- else {
- GPU_link(mat, "set_value_zero", &blend);
- }
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->horr, GPU_DYNAMIC_HORIZON_COLOR, NULL), &hor);
- GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&wo->zenr, GPU_DYNAMIC_ZENITH_COLOR, NULL), &zen);
- do_world_tex(&shi, wo, &hor, &zen, &blend);
- if (wo->skytype & WO_SKYBLEND)
- GPU_link(mat, "node_mix_shader", blend, hor, zen, &shi.rgb);
- else
- GPU_link(mat, "set_rgb", hor, &shi.rgb);
- GPU_link(mat, "set_rgb", shi.rgb, &shr.combined);
- }
- GPU_material_output_link(mat, shr.combined);
-}
-
-GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
-{
- LinkData *link;
- GPUMaterial *mat;
-
- for (link = wo->gpumaterial.first; link; link = link->next)
- if (((GPUMaterial *)link->data)->scene == scene)
- return link->data;
-
- /* allocate material */
- mat = GPU_material_construct_begin(NULL);
- mat->scene = scene;
- mat->type = GPU_MATERIAL_TYPE_WORLD;
-
- /* create nodes */
- if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes) {
- ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
- }
- else {
- gpu_material_old_world(mat, wo);
- }
-
- if (GPU_material_do_color_management(mat))
- if (mat->outlink)
- GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
-
- gpu_material_construct_end(mat, wo->id.name);
-
- /* note that even if building the shader fails in some way, we still keep
- * it to avoid trying to compile again and again, and simple do not use
- * the actual shader on drawing */
-
- link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
- link->data = mat;
- BLI_addtail(&wo->gpumaterial, link);
-
- return mat;
-}
-
GPUMaterial *GPU_material_from_nodetree_find(
ListBase *gpumaterials, const void *engine_type, int options)
{
@@ -2502,15 +598,12 @@ GPUMaterial *GPU_material_from_nodetree_find(
}
/**
- * TODO: This is supposed to replace GPU_material_from_blender/_world in the future
- *
* \note Caller must use #GPU_material_from_nodetree_find to re-use existing materials,
* This is enforced since constructing other arguments to this function may be expensive
* so only do this when they are needed.
*/
GPUMaterial *GPU_material_from_nodetree(
- Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options,
- const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, bool deferred)
+ Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options)
{
LinkData *link;
bool has_volume_output, has_surface_output;
@@ -2534,10 +627,7 @@ GPUMaterial *GPU_material_from_nodetree(
mat->domain |= GPU_DOMAIN_VOLUME;
}
- if (!deferred) {
- GPU_material_generate_pass(mat, vert_code, geom_code, frag_lib, defines);
- }
- else if (mat->outlink) {
+ if (mat->outlink) {
/* Prune the unused nodes and extract attribs before compiling so the
* generated VBOs are ready to accept the future shader. */
GPU_nodes_prune(&mat->nodes, mat->outlink);
@@ -2556,7 +646,6 @@ GPUMaterial *GPU_material_from_nodetree(
return mat;
}
-/* Calls this function if /a mat was created with deferred compilation. */
void GPU_material_generate_pass(
GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
{
@@ -2571,74 +660,8 @@ void GPU_material_generate_pass(
}
}
-GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv)
-{
- GPUMaterial *mat;
- GPUNodeLink *outlink;
- LinkData *link;
-
- for (link = ma->gpumaterial.first; link; link = link->next) {
- GPUMaterial *current_material = (GPUMaterial *)link->data;
- if (current_material->scene == scene &&
- current_material->is_opensubdiv == use_opensubdiv)
- {
- return current_material;
- }
- }
-
- /* allocate material */
- mat = GPU_material_construct_begin(ma);
- mat->scene = scene;
- mat->type = GPU_MATERIAL_TYPE_MESH;
- mat->is_opensubdiv = use_opensubdiv;
-
- /* render pipeline option */
- bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
- if (!new_shading_nodes && (ma->mode & MA_TRANSP))
- GPU_material_enable_alpha(mat);
- else if (new_shading_nodes && ma->alpha < 1.0f)
- GPU_material_enable_alpha(mat);
-
- if (ma->nodetree && ma->use_nodes) {
- /* create nodes */
- if (new_shading_nodes)
- ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_NEW_SHADING);
- else
- ntreeGPUMaterialNodes(ma->nodetree, mat, NODE_OLD_SHADING);
- }
- else {
- if (new_shading_nodes) {
- /* create simple diffuse material instead of nodes */
- outlink = gpu_material_diffuse_bsdf(mat, ma);
- }
- else {
- /* create blender material */
- outlink = GPU_blender_material(mat, ma);
- }
-
- GPU_material_output_link(mat, outlink);
- }
-
- if (GPU_material_do_color_management(mat))
- if (mat->outlink)
- GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
-
- gpu_material_construct_end(mat, ma->id.name);
-
- /* note that even if building the shader fails in some way, we still keep
- * it to avoid trying to compile again and again, and simple do not use
- * the actual shader on drawing */
-
- link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
- link->data = mat;
- BLI_addtail(&ma->gpumaterial, link);
-
- return mat;
-}
-
void GPU_materials_free(void)
{
- Object *ob;
Material *ma;
World *wo;
extern Material defmaterial;
@@ -2650,307 +673,4 @@ void GPU_materials_free(void)
GPU_material_free(&wo->gpumaterial);
GPU_material_free(&defmaterial.gpumaterial);
-
- for (ob = G.main->object.first; ob; ob = ob->id.next)
- GPU_lamp_free(ob);
-}
-
-/* Lamps and shadow buffers */
-
-GPUNodeLink *GPU_lamp_get_data(
- GPUMaterial *mat, GPULamp *lamp,
- GPUNodeLink **r_col, GPUNodeLink **r_lv, GPUNodeLink **r_dist, GPUNodeLink **r_shadow, GPUNodeLink **r_energy)
-{
- GPUNodeLink *visifac;
-
- *r_col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob);
- *r_energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob);
- visifac = lamp_get_visibility(mat, lamp, r_lv, r_dist);
-
- shade_light_textures(mat, lamp, r_col);
-
- if (GPU_lamp_has_shadow_buffer(lamp)) {
- GPUNodeLink *vn, *inp;
-
- GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &vn);
- GPU_link(mat, "shade_inp", vn, *r_lv, &inp);
- mat->dynproperty |= DYN_LAMP_PERSMAT;
-
- if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
- GPU_link(mat, "shadows_only_vsm",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias),
- GPU_uniform(lamp->shadow_color), inp, r_shadow);
- }
- else {
- GPU_link(mat, "shadows_only",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
- GPU_dynamic_uniform((float *)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, r_shadow);
- }
- }
- else {
- GPU_link(mat, "set_rgb_one", r_shadow);
- }
-
- /* ensure shadow buffer and lamp textures will be updated */
- add_user_list(&mat->lamps, lamp);
-
- return visifac;
-}
-
-/* export the GLSL shader */
-
-GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
-{
- static struct {
- GPUBuiltin gputype;
- GPUDynamicType dynamictype;
- GPUDataType datatype;
- } builtins[] = {
- { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
- { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
- { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },
- { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F },
- { GPU_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWMAT, GPU_DATA_16F },
- { GPU_INVERSE_LOC_TO_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_LOCTOVIEWIMAT, GPU_DATA_16F },
- { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F },
- { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F },
- { 0 }
- };
-
- GPUShaderExport *shader = NULL;
- GPUInput *input;
- int liblen, fraglen;
-
- /* TODO(sergey): How to determine whether we need OSD or not here? */
- GPUMaterial *mat = GPU_material_from_blender(scene, ma, false);
- GPUPass *pass = (mat) ? mat->pass : NULL;
-
- if (pass && pass->fragmentcode && pass->vertexcode) {
- shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport");
-
- for (input = mat->inputs.first; input; input = input->next) {
- GPUInputUniform *uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
-
- if (input->ima) {
- /* image sampler uniform */
- uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE;
- uniform->datatype = GPU_DATA_1I;
- uniform->image = input->ima;
- uniform->texnumber = input->texid;
- BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
- }
- else if (input->tex) {
- /* generated buffer */
- uniform->texnumber = input->texid;
- uniform->datatype = GPU_DATA_1I;
- BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
-
- switch (input->textype) {
- case GPU_SHADOW2D:
- uniform->type = GPU_DYNAMIC_SAMPLER_2DSHADOW;
- uniform->lamp = input->dynamicdata;
- break;
- case GPU_TEX2D:
- if (GPU_texture_opengl_bindcode(input->tex)) {
- uniform->type = GPU_DYNAMIC_SAMPLER_2DBUFFER;
- glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(input->tex));
- uniform->texsize = GPU_texture_width(input->tex) * GPU_texture_height(input->tex);
- uniform->texpixels = MEM_mallocN(uniform->texsize * 4, "RGBApixels");
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
- break;
-
- case GPU_NONE:
- case GPU_TEX3D:
- case GPU_TEXCUBE:
- case GPU_FLOAT:
- case GPU_VEC2:
- case GPU_VEC3:
- case GPU_VEC4:
- case GPU_MAT3:
- case GPU_MAT4:
- case GPU_CLOSURE:
- case GPU_ATTRIB:
- break;
- }
- }
- else {
- uniform->type = input->dynamictype;
- BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
- switch (input->type) {
- case GPU_FLOAT:
- uniform->datatype = GPU_DATA_1F;
- break;
- case GPU_VEC2:
- uniform->datatype = GPU_DATA_2F;
- break;
- case GPU_VEC3:
- uniform->datatype = GPU_DATA_3F;
- break;
- case GPU_VEC4:
- uniform->datatype = GPU_DATA_4F;
- break;
- case GPU_MAT3:
- uniform->datatype = GPU_DATA_9F;
- break;
- case GPU_MAT4:
- uniform->datatype = GPU_DATA_16F;
- break;
-
- case GPU_NONE:
- case GPU_CLOSURE:
- case GPU_TEX2D:
- case GPU_TEX3D:
- case GPU_TEXCUBE:
- case GPU_SHADOW2D:
- case GPU_ATTRIB:
- break;
- }
-
- if (GPU_DYNAMIC_GROUP_FROM_TYPE(uniform->type) == GPU_DYNAMIC_GROUP_LAMP)
- uniform->lamp = input->dynamicdata;
-
- if (GPU_DYNAMIC_GROUP_FROM_TYPE(uniform->type) == GPU_DYNAMIC_GROUP_MAT)
- uniform->material = input->dynamicdata;
- }
-
- if (uniform->type != GPU_DYNAMIC_NONE)
- BLI_addtail(&shader->uniforms, uniform);
- else
- MEM_freeN(uniform);
- }
-
- /* process builtin uniform */
- for (int i = 0; builtins[i].gputype; i++) {
- if (mat->builtins & builtins[i].gputype) {
- GPUInputUniform *uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInputUniform");
- uniform->type = builtins[i].dynamictype;
- uniform->datatype = builtins[i].datatype;
- BLI_strncpy(uniform->varname, GPU_builtin_name(builtins[i].gputype), sizeof(uniform->varname));
- BLI_addtail(&shader->uniforms, uniform);
- }
- }
-
- /* now link fragment shader with library shader */
- /* TBD: remove the function that are not used in the main function */
- liblen = (pass->libcode) ? strlen(pass->libcode) : 0;
- fraglen = strlen(pass->fragmentcode);
- shader->fragment = (char *)MEM_mallocN(liblen + fraglen + 1, "GPUFragShader");
- if (pass->libcode)
- memcpy(shader->fragment, pass->libcode, liblen);
- memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen);
- shader->fragment[liblen + fraglen] = 0;
-
- // export the attribute
- for (int i = 0; i < mat->attribs.totlayer; i++) {
- GPUInputAttribute *attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUInputAttribute");
- attribute->type = mat->attribs.layer[i].type;
- attribute->number = mat->attribs.layer[i].glindex;
- BLI_snprintf(attribute->varname, sizeof(attribute->varname), "att%d", mat->attribs.layer[i].attribid);
-
- switch (attribute->type) {
- case CD_TANGENT:
- attribute->datatype = GPU_DATA_4F;
- break;
- case CD_MTFACE:
- attribute->datatype = GPU_DATA_2F;
- attribute->name = mat->attribs.layer[i].name;
- break;
- case CD_MCOL:
- attribute->datatype = GPU_DATA_4UB;
- attribute->name = mat->attribs.layer[i].name;
- break;
- case CD_ORCO:
- attribute->datatype = GPU_DATA_3F;
- break;
- }
-
- if (attribute->datatype != GPU_DATA_NONE)
- BLI_addtail(&shader->attributes, attribute);
- else
- MEM_freeN(attribute);
- }
-
- /* export the vertex shader */
- shader->vertex = BLI_strdup(pass->vertexcode);
- }
-
- return shader;
-}
-
-void GPU_free_shader_export(GPUShaderExport *shader)
-{
- if (shader == NULL)
- return;
-
- for (GPUInputUniform *uniform = shader->uniforms.first; uniform; uniform = uniform->next)
- if (uniform->texpixels)
- MEM_freeN(uniform->texpixels);
-
- BLI_freelistN(&shader->uniforms);
- BLI_freelistN(&shader->attributes);
-
- if (shader->vertex)
- MEM_freeN(shader->vertex);
- if (shader->fragment)
- MEM_freeN(shader->fragment);
-
- MEM_freeN(shader);
}
-
-#ifdef WITH_OPENSUBDIV
-void GPU_material_update_fvar_offset(GPUMaterial *gpu_material,
- DerivedMesh *dm)
-{
- GPUPass *pass = gpu_material->pass;
- GPUShader *shader = (pass != NULL ? pass->shader : NULL);
- ListBase *inputs = (pass != NULL ? &gpu_material->inputs : NULL);
- GPUInput *input;
-
- if (shader == NULL) {
- return;
- }
-
- GPU_shader_bind(shader);
-
- for (input = inputs->first;
- input != NULL;
- input = input->next)
- {
- if (input->source == GPU_SOURCE_ATTRIB &&
- input->attribtype == CD_MTFACE)
- {
- char name[64];
- /* TODO(sergey): This will work for until names are
- * consistent, we'll need to solve this somehow in the future.
- */
- int layer_index;
- int location;
-
- if (input->attribname[0] != '\0') {
- layer_index = CustomData_get_named_layer(&dm->loopData,
- CD_MLOOPUV,
- input->attribname);
- }
- else {
- layer_index = CustomData_get_active_layer(&dm->loopData,
- CD_MLOOPUV);
- }
-
- BLI_snprintf(name, sizeof(name),
- "fvar%d_offset",
- input->attribid);
- location = GPU_shader_get_uniform(shader, name);
- GPU_shader_uniform_int(shader, location, layer_index);
- }
- }
-
- GPU_shader_unbind();
-}
-#endif