From eb8dddaab1461cd1af2c0c705d9dc846670cb25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 9 Jul 2017 17:50:39 +0200 Subject: Eevee: Material: Code cleanup in order to add transparency support. --- .../blender/draw/engines/eevee/eevee_materials.c | 223 ++++++++++++--------- 1 file changed, 128 insertions(+), 95 deletions(-) (limited to 'source/blender/draw/engines/eevee/eevee_materials.c') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 151bd05358d..b85745732e1 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -677,6 +677,105 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata) } \ } while (0) +typedef struct EeveeMaterialShadingGroups{ + struct DRWShadingGroup *shading_grp; + struct DRWShadingGroup *depth_grp; + struct DRWShadingGroup *depth_clip_grp; +} EeveeMaterialShadingGroups; + +static void material_opaque( + Material *ma, GHash *material_hash, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, + bool do_cull, bool use_flat_nor, struct GPUMaterial **gpumat, struct GPUMaterial **gpumat_depth, + struct DRWShadingGroup **shgrp, struct DRWShadingGroup **shgrp_depth, struct DRWShadingGroup **shgrp_depth_clip) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; + EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + + float *color_p = &ma->r; + float *metal_p = &ma->ray_mirror; + float *spec_p = &ma->spec; + float *rough_p = &ma->gloss_mir; + + const bool use_gpumat = (ma->use_nodes && ma->nodetree); + + EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma); + + if (emsg) { + *shgrp = emsg->shading_grp; + *shgrp_depth = emsg->depth_grp; + *shgrp_depth_clip = emsg->depth_clip_grp; + + /* This will have been created already, just perform a lookup. */ + *gpumat = (use_gpumat) ? EEVEE_material_mesh_get( + draw_ctx->scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals) : NULL; + *gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get( + draw_ctx->scene, ma, (ma->blend_method == MA_BM_HASHED)) : NULL; + return; + } + + if (use_gpumat) { + /* Shading */ + *gpumat = EEVEE_material_mesh_get(scene, ma, + stl->effects->use_ao, stl->effects->use_bent_normals); + + *shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass); + if (*shgrp) { + add_standard_uniforms(*shgrp, sldata, vedata); + } + else { + /* Shader failed : pink color */ + static float col[3] = {1.0f, 0.0f, 1.0f}; + static float half = 0.5f; + + color_p = col; + metal_p = spec_p = rough_p = ½ + } + + /* Alpha CLipped : Discard pixel from depth pass, then + * fail the depth test for shading. */ + if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) { + *gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma, + (ma->blend_method == MA_BM_HASHED)); + + *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_cull : psl->depth_pass); + *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip); + + if (shgrp_depth) { + if (ma->blend_method == MA_BM_CLIP) { + DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1); + DRW_shgroup_uniform_float(*shgrp_depth_clip, "alphaThreshold", &ma->alpha_threshold, 1); + } + } + } + } + + /* Fallback to default shader */ + if (*shgrp == NULL) { + *shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor, + stl->effects->use_ao, stl->effects->use_bent_normals); + DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1); + DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1); + DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1); + DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1); + } + + /* Fallback default depth prepass */ + if (*shgrp_depth == NULL) { + *shgrp_depth = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp; + *shgrp_depth_clip = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip; + } + + emsg = MEM_mallocN(sizeof("EeveeMaterialShadingGroups"), "EeveeMaterialShadingGroups"); + emsg->shading_grp = *shgrp; + emsg->depth_grp = *shgrp_depth; + emsg->depth_clip_grp = *shgrp_depth_clip; + BLI_ghash_insert(material_hash, ma, emsg); +} + +// void EEVEE_materials_cache_blended(); + void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sldata, Object *ob) { EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; @@ -693,8 +792,13 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl /* First get materials for this mesh. */ if (ELEM(ob->type, OB_MESH)) { const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol)); + struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len); + struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array, materials_len); + struct DRWShadingGroup **shgrp_depth_clip_array = BLI_array_alloca(shgrp_depth_clip_array, materials_len); + struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len); + struct GPUMaterial **gpumat_depth_array = BLI_array_alloca(gpumat_array, materials_len); bool use_flat_nor = false; @@ -705,67 +809,29 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl } for (int i = 0; i < materials_len; ++i) { - DRWShadingGroup *shgrp = NULL; Material *ma = give_current_material(ob, i + 1); - if (ma == NULL) - ma = &defmaterial; - - float *color_p = &ma->r; - float *metal_p = &ma->ray_mirror; - float *spec_p = &ma->spec; - float *rough_p = &ma->gloss_mir; - - const bool use_gpumat = (ma->use_nodes && ma->nodetree); - - shgrp = BLI_ghash_lookup(material_hash, (const void *)ma); - if (shgrp) { - shgrp_array[i] = shgrp; /* ADD_SHGROUP_CALL below */ - /* This will have been created already, just perform a lookup. */ - gpumat_array[i] = (use_gpumat) ? EEVEE_material_mesh_get( - draw_ctx->scene, ma,stl->effects->use_ao, stl->effects->use_bent_normals) : NULL; - continue; - } - - /* May not be set below. */ gpumat_array[i] = NULL; + gpumat_depth_array[i] = NULL; + shgrp_array[i] = NULL; + shgrp_depth_array[i] = NULL; + shgrp_depth_clip_array[i] = NULL; - if (use_gpumat) { - Scene *scene = draw_ctx->scene; - struct GPUMaterial *gpumat = EEVEE_material_mesh_get(scene, ma, - stl->effects->use_ao, stl->effects->use_bent_normals); - - shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass); - if (shgrp) { - add_standard_uniforms(shgrp, sldata, vedata); - - BLI_ghash_insert(material_hash, ma, shgrp); - shgrp_array[i] = shgrp; /* ADD_SHGROUP_CALL below */ - - gpumat_array[i] = gpumat; - } - else { - /* Shader failed : pink color */ - static float col[3] = {1.0f, 0.0f, 1.0f}; - static float half = 0.5f; - - color_p = col; - metal_p = spec_p = rough_p = ½ - } - } - - /* Fallback to default shader */ - if (shgrp == NULL) { - shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor, - stl->effects->use_ao, stl->effects->use_bent_normals); - DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1); - DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1); - DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1); - DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1); - - BLI_ghash_insert(material_hash, ma, shgrp); + if (ma == NULL) + ma = &defmaterial; - shgrp_array[i] = shgrp; /* ADD_SHGROUP_CALL below */ + switch (ma->blend_method) { + case MA_BM_SOLID: + case MA_BM_CLIP: + case MA_BM_HASHED: + material_opaque(ma, material_hash, sldata, vedata, do_cull, use_flat_nor, + &gpumat_array[i], &gpumat_depth_array[i], + &shgrp_array[i], &shgrp_depth_array[i], &shgrp_depth_clip_array[i]); + break; + case MA_BM_ADD: + case MA_BM_MULTIPLY: + // material_transparent(ma, material_hash, &shgrp); + break; } } @@ -773,48 +839,15 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len); if (mat_geom) { for (int i = 0; i < materials_len; ++i) { + /* Shading pass */ ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]); /* Depth Prepass */ - DRWShadingGroup *depth_shgrp = NULL; - DRWShadingGroup *depth_clip_shgrp; - - Material *ma = give_current_material(ob, i + 1); - - if (ma != NULL && (ma->use_nodes && ma->nodetree)) { - if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) { - Scene *scene = draw_ctx->scene; - DRWPass *depth_pass, *depth_clip_pass; - struct GPUMaterial *gpumat = EEVEE_material_mesh_depth_get(scene, ma, (ma->blend_method == MA_BM_HASHED)); - - depth_pass = do_cull ? psl->depth_pass_cull : psl->depth_pass; - depth_clip_pass = do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip; - - /* Use same shader for both. */ - depth_shgrp = DRW_shgroup_material_create(gpumat, depth_pass); - depth_clip_shgrp = DRW_shgroup_material_create(gpumat, depth_clip_pass); - - if (ma->blend_method == MA_BM_CLIP) { - DRW_shgroup_uniform_float(depth_shgrp, "alphaThreshold", &ma->alpha_threshold, 1); - DRW_shgroup_uniform_float(depth_clip_shgrp, "alphaThreshold", &ma->alpha_threshold, 1); - } - } - - /* Shadow Pass */ - /* TODO clipped shadow map */ - EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat); - } - - if (depth_shgrp == NULL) { - depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp; - depth_clip_shgrp = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip; - - /* Shadow Pass */ - EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat); - } + ADD_SHGROUP_CALL(shgrp_depth_array[i], ob, mat_geom[i]); + ADD_SHGROUP_CALL(shgrp_depth_clip_array[i], ob, mat_geom[i]); - ADD_SHGROUP_CALL(depth_shgrp, ob, mat_geom[i]); - ADD_SHGROUP_CALL(depth_clip_shgrp, ob, mat_geom[i]); + /* Shadow Pass */ + EEVEE_lights_cache_shcaster_add(sldata, psl, mat_geom[i], ob->obmat); } } } @@ -906,7 +939,7 @@ void EEVEE_materials_cache_finish(EEVEE_Data *vedata) { EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; - BLI_ghash_free(stl->g_data->material_hash, NULL, NULL); + BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN); BLI_ghash_free(stl->g_data->hair_material_hash, NULL, NULL); } -- cgit v1.2.3