diff options
13 files changed, 92 insertions, 30 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 535dce7730a..769ac11736d 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -360,7 +360,9 @@ static char *eevee_get_volume_defines(int options) **/ static void add_standard_uniforms( DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, - int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend) + int *ssr_id, float *refract_depth, + bool use_diffuse, bool use_glossy, bool use_refract, + bool use_ssrefraction, bool use_alpha_blend) { LightCache *lcache = vedata->stl->g_data->light_cache; @@ -377,13 +379,13 @@ static void add_standard_uniforms( DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo); - /* TODO if glossy or diffuse bsdf */ - if (true) { + if (use_diffuse || use_glossy || use_refract) { DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex); DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool); DRW_shgroup_uniform_texture_ref(shgrp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); DRW_shgroup_uniform_texture_ref(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); - + } + if ((use_diffuse || use_glossy) && !use_refract) { if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) != 0) { DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &vedata->stl->effects->gtao_horizons); } @@ -392,15 +394,13 @@ static void add_standard_uniforms( DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &vedata->txl->maxzbuffer); } } - - /* TODO if diffuse bsdf */ - if (true) { + if (use_diffuse) { DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex); } - - /* TODO if glossy bsdf */ - if (true) { + if (use_glossy || use_refract) { DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &lcache->cube_tx.tex); + } + if (use_glossy) { DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); } @@ -851,7 +851,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( } DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, use_blend); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, use_blend); return shgrp; } @@ -888,7 +888,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( * EDIT: THIS IS NOT THE CASE FOR HAIRS !!! DUMMY!!! */ if (!is_hair) { DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false); } } @@ -896,7 +896,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( DRWShadingGroup *shgrp = DRW_shgroup_hair_create(ob, psys, md, vedata->psl->default_pass[options], e_data.default_lit[options]); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false); return shgrp; } else { @@ -928,7 +928,7 @@ static struct DRWShadingGroup *EEVEE_lookdev_shading_group_get( DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass); /* XXX / WATCH: This creates non persistent binds for the ubos and textures. * But it's currently OK because the following shgroups does not add any bind. */ - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false); } return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass); @@ -1116,6 +1116,7 @@ static void material_opaque( EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; EEVEE_LampsInfo *linfo = sldata->lamps; + bool use_diffuse, use_glossy, use_refract; float *color_p = &ma->r; float *metal_p = &ma->metallic; @@ -1123,7 +1124,7 @@ static void material_opaque( float *rough_p = &ma->roughness; const bool use_gpumat = (ma->use_nodes && ma->nodetree); - const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && + const bool use_ssrefract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((effects->enabled_effects & EFFECT_REFRACT) != 0); const bool use_sss = ((ma->blend_flag & MA_BL_SS_SUBSURFACE) != 0) && ((effects->enabled_effects & EFFECT_SSS) != 0); @@ -1138,7 +1139,7 @@ static void material_opaque( /* This will have been created already, just perform a lookup. */ *gpumat = (use_gpumat) ? EEVEE_material_mesh_get( - scene, ma, vedata, false, false, use_refract, use_sss, use_translucency, linfo->shadow_method) : NULL; + scene, ma, vedata, false, false, use_ssrefract, use_sss, use_translucency, linfo->shadow_method) : NULL; *gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get( scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL; return; @@ -1151,7 +1152,7 @@ static void material_opaque( /* Shading */ *gpumat = EEVEE_material_mesh_get( - scene, ma, vedata, false, false, use_refract, + scene, ma, vedata, false, false, use_ssrefract, use_sss, use_translucency, linfo->shadow_method); GPUMaterialStatus status_mat_surface = GPU_material_status(*gpumat); @@ -1167,7 +1168,7 @@ static void material_opaque( * the surface shader. */ status_mat_surface = status_mat_depth; } - else if (use_refract) { + else if (use_ssrefract) { *shgrp_depth = DRW_shgroup_material_create( *gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass); *shgrp_depth_clip = DRW_shgroup_material_create( @@ -1181,8 +1182,14 @@ static void material_opaque( } if (*shgrp_depth != NULL) { - add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, false, false); - add_standard_uniforms(*shgrp_depth_clip, sldata, vedata, NULL, NULL, false, false); + use_diffuse = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_DIFFUSE); + use_glossy = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_GLOSSY); + use_refract = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_REFRACT); + + add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, + use_diffuse, use_glossy, use_refract, false, false); + add_standard_uniforms(*shgrp_depth_clip, sldata, vedata, NULL, NULL, + use_diffuse, use_glossy, use_refract, false, false); if (ma->blend_method == MA_BM_CLIP) { DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1); @@ -1200,13 +1207,18 @@ static void material_opaque( { static int no_ssr = -1; static int first_ssr = 1; - int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr; + int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_ssrefract) ? &first_ssr : &no_ssr; + use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE); + use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY); + use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT); *shgrp = DRW_shgroup_material_create( *gpumat, - (use_refract) ? psl->refract_pass : + (use_ssrefract) ? psl->refract_pass : (use_sss) ? psl->sss_pass : psl->material_pass); - add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false); + + add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, + use_diffuse, use_glossy, use_refract, use_ssrefract, false); if (use_sss) { struct GPUTexture *sss_tex_profile = NULL; @@ -1237,7 +1249,6 @@ static void material_opaque( } case GPU_MAT_QUEUED: { - /* TODO Bypass probe compilation. */ color_p = compile_col; metal_p = spec_p = rough_p = ½ break; @@ -1264,7 +1275,7 @@ static void material_opaque( /* Fallback default depth prepass */ if (*shgrp_depth == NULL) { - if (use_refract) { + if (use_ssrefract) { *shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull : stl->g_data->refract_depth_shgrp; *shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull : stl->g_data->refract_depth_shgrp_clip; } @@ -1292,7 +1303,7 @@ static void material_transparent( EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; EEVEE_LampsInfo *linfo = sldata->lamps; - const bool use_refract = ( + const bool use_ssrefract = ( ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0) ); @@ -1308,7 +1319,7 @@ static void material_transparent( /* Shading */ *gpumat = EEVEE_material_mesh_get( - scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract, + scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_ssrefract, false, false, linfo->shadow_method); switch (GPU_material_status(*gpumat)) { @@ -1318,7 +1329,13 @@ static void material_transparent( bool use_blend = (ma->blend_method & MA_BM_BLEND) != 0; *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass); - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend); + + bool use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE); + bool use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY); + bool use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT); + + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, + use_diffuse, use_glossy, use_refract, use_ssrefract, use_blend); break; } case GPU_MAT_QUEUED: @@ -1643,11 +1660,17 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, switch (GPU_material_status(gpumat)) { case GPU_MAT_SUCCESS: { + bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE); + bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY); + bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT); + shgrp = DRW_shgroup_material_hair_create( ob, psys, md, psl->material_pass, gpumat); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, + use_diffuse, use_glossy, use_refract, false, false); break; } case GPU_MAT_QUEUED: diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 5945621cb65..cc1150b6d77 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -124,6 +124,11 @@ typedef enum GPUMatType { GPU_MATERIAL_TYPE_WORLD = 2, } GPUMatType; +typedef enum GPUMatFlag { + GPU_MATFLAG_DIFFUSE = (1 << 0), + GPU_MATFLAG_GLOSSY = (1 << 1), + GPU_MATFLAG_REFRACT = (1 << 2), +} GPUMatFlag; typedef enum GPUBlendMode { GPU_BLEND_SOLID = 0, @@ -270,6 +275,9 @@ bool GPU_material_do_color_management(GPUMaterial *mat); bool GPU_material_use_domain_surface(GPUMaterial *mat); bool GPU_material_use_domain_volume(GPUMaterial *mat); +void GPU_material_flag_set(GPUMaterial *mat, GPUMatFlag flag); +bool GPU_material_flag_get(GPUMaterial *mat, GPUMatFlag flag); + void GPU_pass_cache_init(void); void GPU_pass_cache_garbage_collect(void); void GPU_pass_cache_free(void); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9859f56c1db..69c3a3a73ba 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -109,6 +109,9 @@ struct GPUMaterial { */ int domain; + /* Only used by Eevee to know which bsdf are used. */ + int flag; + /* Used by 2.8 pipeline */ GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ @@ -564,6 +567,16 @@ bool GPU_material_use_domain_volume(GPUMaterial *mat) return (mat->domain & GPU_DOMAIN_VOLUME); } +void GPU_material_flag_set(GPUMaterial *mat, GPUMatFlag flag) +{ + mat->flag |= flag; +} + +bool GPU_material_flag_get(GPUMaterial *mat, GPUMatFlag flag) +{ + return (mat->flag & flag); +} + GPUMaterial *GPU_material_from_nodetree_find( ListBase *gpumaterials, const void *engine_type, int options) { diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 064ee42907e..808d2f73659 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1102,7 +1102,7 @@ void node_bsdf_anisotropic( vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); + node_bsdf_glossy(color, roughness, N, -1, result); } void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index c1423867d96..6551b20a375 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -54,6 +54,8 @@ static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *node, bNode if (!in[4].link) GPU_link(mat, "world_normals_get", &in[4].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index 58a37b0e81d..c1b8c748657 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *node, bNodeExec if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 7b060bc68aa..ada6e21356f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecDa if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_glass", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index c3fb43c0ce8..f56837de261 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -51,6 +51,8 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index 7f02295d45f..831ac1c98da 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -117,6 +117,8 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeE GPU_link(mat, "set_rgb", GPU_uniform((float *)one), &sss_scale); } + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&node->ssr_id), GPU_uniform(&node->sss_id), sss_scale); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c index 41dd3f8af3c..b59f1c80342 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c @@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, bNode *node, bNodeE if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); + GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index 2c0949f275c..349db30af14 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -45,6 +45,8 @@ static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *node, bNode if (!in[1].link) GPU_link(mat, "world_normals_get", &in[1].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_translucent", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index ce331f03d4e..59b831c0dab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_velvet", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c index 57fb9026595..3f0ba3c1c60 100644 --- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c +++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c @@ -54,6 +54,8 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *node, if (!in[5].link) GPU_link(mat, "world_normals_get", &in[5].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + if (node->sss_id == 1) { bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2); bNodeSocketValueRGBA *socket_data = socket->default_value; |