Cleanup: split off hair cache function for reusability
For when we support sources of hair other than particle systems.
This commit is contained in:
parent
74b0edce74
commit
57b7833d1e
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue