Cleanup: split off hair cache function for reusability

For when we support sources of hair other than particle systems.
This commit is contained in:
Brecht Van Lommel 2020-02-27 15:01:33 +01:00
parent 74b0edce74
commit 57b7833d1e
4 changed files with 149 additions and 140 deletions

View File

@ -120,7 +120,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
bool cast_shadow = false;
if (ob_visibility & OB_VISIBLE_PARTICLES) {
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
EEVEE_particle_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) {

View File

@ -1728,6 +1728,144 @@ BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot)
return ma;
}
static void eevee_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
ParticleSystem *psys,
ModifierData *md,
int matnr,
bool *cast_shadow)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
DRWShadingGroup *shgrp = NULL;
Material *ma = eevee_object_material_get(ob, matnr - 1);
float *color_p = &ma->r;
float *metal_p = &ma->metallic;
float *spec_p = &ma->spec;
float *rough_p = &ma->roughness;
bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
shgrp = DRW_shgroup_hair_create(ob, psys, md, psl->depth_pass, e_data.default_hair_prepass_sh);
shgrp = DRW_shgroup_hair_create(
ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
shgrp = NULL;
if (ma->use_nodes && ma->nodetree && !holdout) {
static int ssr_id;
ssr_id = (use_ssr) ? 1 : -1;
static float half = 0.5f;
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma);
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);
if (!use_diffuse && !use_glossy && !use_refract) {
/* HACK: Small hack to avoid issue when utilTex is needed for
* world_normals_get and none of the bsdfs are present.
* This binds utilTex even if not needed. */
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
}
add_standard_uniforms(shgrp,
sldata,
vedata,
&ssr_id,
NULL,
use_diffuse,
use_glossy,
use_refract,
false,
false,
DEFAULT_RENDER_PASS_FLAG);
/* Add the hair to all the render_passes that are enabled */
RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
shgrp = DRW_shgroup_material_hair_create(
ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
if (!use_diffuse && !use_glossy && !use_refract) {
/* Small hack to avoid issue when utilTex is needed for
* world_normals_get and none of the bsdfs that need it are present.
* This binds `utilTex` even if not needed. */
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
}
add_standard_uniforms(shgrp,
sldata,
vedata,
&ssr_id,
NULL,
use_diffuse,
use_glossy,
use_refract,
false,
false,
render_pass_flag);
RENDER_PASS_ITER_END(render_pass_index)
break;
}
case GPU_MAT_QUEUED: {
stl->g_data->queued_shaders_count++;
color_p = compile_col;
metal_p = spec_p = rough_p = ½
break;
}
case GPU_MAT_FAILED:
default:
color_p = error_col;
metal_p = spec_p = rough_p = ½
break;
}
}
/* Fallback to default shader */
if (shgrp == NULL) {
shgrp = EEVEE_default_shading_group_get(sldata, vedata, ob, psys, md, true, holdout, use_ssr);
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);
RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
shgrp = EEVEE_default_hair_render_pass_shading_group_get(
sldata,
vedata,
ob,
psys,
md,
holdout,
use_ssr,
psl->material_accum_pass[render_pass_index],
render_pass_flag);
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);
RENDER_PASS_ITER_END(render_pass_index)
}
/* Shadows */
DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
*cast_shadow = true;
}
void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
@ -1906,18 +2044,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
}
}
void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow)
void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
if (ob->type == OB_MESH) {
if (ob != draw_ctx->object_edit) {
@ -1934,130 +2066,7 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
if (draw_as != PART_DRAW_PATH) {
continue;
}
DRWShadingGroup *shgrp = NULL;
Material *ma = eevee_object_material_get(ob, part->omat - 1);
float *color_p = &ma->r;
float *metal_p = &ma->metallic;
float *spec_p = &ma->spec;
float *rough_p = &ma->roughness;
shgrp = DRW_shgroup_hair_create(
ob, psys, md, psl->depth_pass, e_data.default_hair_prepass_sh);
shgrp = DRW_shgroup_hair_create(
ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
shgrp = NULL;
if (ma->use_nodes && ma->nodetree && !holdout) {
static int ssr_id;
ssr_id = (use_ssr) ? 1 : -1;
static float half = 0.5f;
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma);
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);
if (!use_diffuse && !use_glossy && !use_refract) {
/* HACK: Small hack to avoid issue when utilTex is needed for
* world_normals_get and none of the bsdfs are present.
* This binds utilTex even if not needed. */
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
}
add_standard_uniforms(shgrp,
sldata,
vedata,
&ssr_id,
NULL,
use_diffuse,
use_glossy,
use_refract,
false,
false,
DEFAULT_RENDER_PASS_FLAG);
/* Add the hair to all the render_passes that are enabled */
RENDER_PASS_ITER_BEGIN(
stl->g_data->render_passes, render_pass_index, render_pass_flag)
shgrp = DRW_shgroup_material_hair_create(
ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
if (!use_diffuse && !use_glossy && !use_refract) {
/* Small hack to avoid issue when utilTex is needed for
* world_normals_get and none of the bsdfs that need it are present.
* This binds `utilTex` even if not needed. */
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
}
add_standard_uniforms(shgrp,
sldata,
vedata,
&ssr_id,
NULL,
use_diffuse,
use_glossy,
use_refract,
false,
false,
render_pass_flag);
RENDER_PASS_ITER_END(render_pass_index)
break;
}
case GPU_MAT_QUEUED: {
stl->g_data->queued_shaders_count++;
color_p = compile_col;
metal_p = spec_p = rough_p = ½
break;
}
case GPU_MAT_FAILED:
default:
color_p = error_col;
metal_p = spec_p = rough_p = ½
break;
}
}
/* Fallback to default shader */
if (shgrp == NULL) {
shgrp = EEVEE_default_shading_group_get(
sldata, vedata, ob, psys, md, true, holdout, use_ssr);
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);
RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
shgrp = EEVEE_default_hair_render_pass_shading_group_get(
sldata,
vedata,
ob,
psys,
md,
holdout,
use_ssr,
psl->material_accum_pass[render_pass_index],
render_pass_flag);
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);
RENDER_PASS_ITER_END(render_pass_index)
}
/* Shadows */
DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
*cast_shadow = true;
eevee_hair_cache_populate(vedata, sldata, ob, psys, md, part->omat, cast_shadow);
}
}
}

View File

@ -897,10 +897,10 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow);
void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow);
void EEVEE_particle_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob,
bool *cast_shadow);
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, struct World *wo);

View File

@ -204,7 +204,7 @@ void EEVEE_render_cache(void *vedata,
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
if (ob_visibility & OB_VISIBLE_PARTICLES) {
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
EEVEE_particle_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
if (ob_visibility & OB_VISIBLE_SELF) {