From da2dfaad1a5686b899fce4f309cc0b8d4a349f49 Mon Sep 17 00:00:00 2001 From: Alexander Romanov Date: Mon, 21 Mar 2016 14:36:33 +0300 Subject: [PATCH] Mirror influence of environment texture in Blender viewport This patch implements Mirror influence for environment textures. Approach matches the one from BI. {F281871} See the video https://youtu.be/BskgCv6dcIE Example: {F281876} Alexander (Blend4Web Team) Reviewers: campbellbarton, merwin, brecht Reviewed By: brecht Subscribers: TwisterGE, blueprintrandom, youle, Evgeny_Rodygin, AlexKowel, yurikovelenov Differential Revision: https://developer.blender.org/D1786 --- source/blender/gpu/GPU_material.h | 5 +++-- source/blender/gpu/intern/gpu_material.c | 21 ++++++++++++++++++- .../gpu/shaders/gpu_shader_material.glsl | 10 +++++++++ .../nodes/shader/nodes/node_shader_material.c | 2 ++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f150b7215e1..81b08e2b128 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -192,7 +192,8 @@ typedef enum GPUDynamicType { GPU_DYNAMIC_MAT_HARD = 5 | GPU_DYNAMIC_GROUP_MAT, GPU_DYNAMIC_MAT_EMIT = 6 | GPU_DYNAMIC_GROUP_MAT, GPU_DYNAMIC_MAT_AMB = 7 | GPU_DYNAMIC_GROUP_MAT, - GPU_DYNAMIC_MAT_ALPHA = 8 | GPU_DYNAMIC_GROUP_MAT + GPU_DYNAMIC_MAT_ALPHA = 8 | GPU_DYNAMIC_GROUP_MAT, + GPU_DYNAMIC_MAT_MIR = 9 | GPU_DYNAMIC_GROUP_MAT } GPUDynamicType; GPUNodeLink *GPU_attribute(CustomDataType type, const char *name); @@ -249,7 +250,7 @@ typedef struct GPUShadeInput { GPUNodeLink *rgb, *specrgb, *vn, *view, *vcol, *ref; GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb; - GPUNodeLink *spectra; + GPUNodeLink *spectra, *mir, *refcol; } GPUShadeInput; typedef struct GPUShadeResult { diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index bf9fb4cb718..fefc18d017e 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1270,7 +1270,7 @@ static void do_material_tex(GPUShadeInput *shi) } /* mapping */ - if (mtex->mapto & (MAP_COL + MAP_COLSPEC)) { + 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); @@ -1311,6 +1311,20 @@ static void do_material_tex(GPUShadeInput *shi) 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 (!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) { @@ -1603,6 +1617,8 @@ void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->r, GPU_DYNAMIC_MAT_DIFFRGB, NULL), &shi->rgb); GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->specr, GPU_DYNAMIC_MAT_SPECRGB, NULL), &shi->specrgb); + GPU_link(mat, "set_rgb", GPU_dynamic_uniform(&ma->mirr, GPU_DYNAMIC_MAT_MIR, NULL), &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) @@ -1723,6 +1739,9 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) 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); } diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 05853c3e2d3..0471ff3c293 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -923,6 +923,11 @@ void shade_norm(vec3 normal, out vec3 outnormal) outnormal = -normalize(normal); } +void mtex_mirror(vec3 tcol, vec4 refcol, float tin, float colmirfac, out vec4 outrefcol) +{ + outrefcol = mix(refcol, vec4(1.0, tcol), tin*colmirfac); +} + void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) { float facm; @@ -2058,6 +2063,11 @@ void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol) outcol = t*lampcol*speccol; } +void shade_add_mirror(vec3 mir, vec4 refcol, vec3 combined, out vec3 result) +{ + result = mir*refcol.gba + (vec3(1.0) - mir*refcol.rrr)*combined; +} + void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha) { if (spectra > 0.0) { diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 41e44a64376..fa13f6191ad 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -263,6 +263,8 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn); if (node->type == SH_NODE_MATERIAL_EXT) { + if (hasinput[MAT_IN_MIR]) + shi.mir = gpu_get_input_link(&in[MAT_IN_MIR]); if (hasinput[MAT_IN_AMB]) shi.amb = gpu_get_input_link(&in[MAT_IN_AMB]); if (hasinput[MAT_IN_EMIT])