diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_material.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 159 |
1 files changed, 129 insertions, 30 deletions
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 5f8015be52f..310e2ec722c 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -40,18 +40,21 @@ #include "DNA_scene_types.h" #include "DNA_world_types.h" +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + #include "BKE_anim.h" #include "BKE_colortools.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_main.h" #include "BKE_node.h" #include "BKE_scene.h" #include "BKE_texture.h" -#include "BKE_utildefines.h" -#include "BLI_math.h" -#include "BLI_blenlib.h" +#include "IMB_imbuf_types.h" #include "GPU_extensions.h" #include "GPU_material.h" @@ -464,7 +467,7 @@ static void area_lamp_vectors(LampRen *lar) static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol) { - static char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub", + 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"}; @@ -605,7 +608,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la Material *ma= shi->mat; GPUMaterial *mat= shi->gpumat; GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view; - GPUNodeLink *outcol, *specfac, *t, *shadfac; + GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL; float one = 1.0f; if((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW)) @@ -629,10 +632,8 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la } else { if(lamp->type == LA_AREA) { - float area[4][4], areasize; + float area[4][4]= {{0.0f}}, areasize= 0.0f; - memset(&area, 0, sizeof(area)); - memset(&areasize, 0, sizeof(areasize)); 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_uniform(lamp->dynvec), vn, GPU_uniform((float*)area), GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp); @@ -758,10 +759,10 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) { Base *base; Object *ob; - Scene *sce; + Scene *sce_iter; GPULamp *lamp; - for(SETLOOPER(shi->gpumat->scene, base)) { + for(SETLOOPER(shi->gpumat->scene, sce_iter, base)) { ob= base->object; if(ob->type==OB_LAMP) { @@ -891,6 +892,8 @@ static void do_material_tex(GPUShadeInput *shi) char *lastuvname = NULL; float one = 1.0f, norfac, ofs[3]; int tex_nr, rgbnor, talpha; + int init_done = 0, iBumpSpacePrev; + GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude; GPU_link(mat, "set_value", GPU_uniform(&one), &stencil); @@ -956,7 +959,7 @@ static void do_material_tex(GPUShadeInput *shi) rgbnor = 0; if(tex && tex->type == TEX_IMAGE && tex->ima) { - GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb, &tnor); + GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb); rgbnor= TEX_RGB; if(tex->imaflag & TEX_USEALPHA) @@ -1025,29 +1028,125 @@ static void do_material_tex(GPUShadeInput *shi) } if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) { - if((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) { - if(mtex->norfac < 0.0f) - GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); - - if(mtex->normapspace == MTEX_NSPACE_TANGENT) - GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor); - else - newnor = tnor; - - norfac = MIN2(fabsf(mtex->norfac), 1.0); - if(norfac == 1.0f && !GPU_link_changed(stencil)) { - shi->vn = newnor; - } - else { + if(tex->type==TEX_IMAGE) { + if(tex->imaflag & TEX_NORMALMAP) { + /* normalmap image */ + GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor ); + + if(mtex->norfac < 0.0f) + GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); + + if(mtex->normapspace == MTEX_NSPACE_TANGENT) + GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor); + else + newnor = tnor; + + norfac = MIN2(fabsf(mtex->norfac), 1.0); + + 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( mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) { + /* ntap bumpmap image */ + int iBumpSpace; + float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types + float hScaleTex = 13.0f; // factor for scaling texspace bumps + + GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION); + GPUNodeLink *vR1, *vR2; + GPUNodeLink *dBs, *dBt, *fDet; + + if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) + hScale = hScaleTex; + norfac = hScale * mtex->norfac; 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); + + 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 = 1; + } + + // 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 ) { + + 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( mtex->texflag & MTEX_3TAP_BUMP ) + GPU_link( mat, "mtex_bump_tap3", + texco, GPU_image(tex->ima, &tex->iuser), tnorfac, + &dBs, &dBt ); + else + GPU_link( mat, "mtex_bump_tap5", + texco, GPU_image(tex->ima, &tex->iuser), tnorfac, + &dBs, &dBt ); + + + if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { + float ima_x= 512.0f, ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only + ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser); + if(ibuf) { + ima_x= ibuf->x; + ima_y= ibuf->y; + } + + GPU_link( mat, "mtex_bump_apply_texspace", + fDet, dBs, dBt, vR1, vR2, + GPU_image(tex->ima, &tex->iuser), texco, GPU_uniform(&ima_x), GPU_uniform(&ima_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); GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); } @@ -1296,7 +1395,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) return mat; } -void GPU_materials_free() +void GPU_materials_free(void) { Object *ob; Material *ma; |