EEVEE-Next: Displacement Option #113979

Merged
Clément Foucault merged 11 commits from fclem/blender:eevee-next-displacement-option into main 2023-11-21 19:55:49 +01:00
10 changed files with 117 additions and 34 deletions

View File

@ -1964,7 +1964,7 @@ class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
cmat = mat.cycles
col = layout.column()
col.prop(cmat, "displacement_method", text="Displacement")
col.prop(mat, "displacement_method", text="Displacement")
col.prop(cmat, "emission_sampling")
col.prop(mat, "use_transparent_shadow")
col.prop(cmat, "use_bump_map_correction")

View File

@ -56,12 +56,6 @@ static VolumeInterpolation get_volume_interpolation(PointerRNA &ptr)
ptr, "volume_interpolation", VOLUME_NUM_INTERPOLATION, VOLUME_INTERPOLATION_LINEAR);
}
static DisplacementMethod get_displacement_method(PointerRNA &ptr)
{
return (DisplacementMethod)get_enum(
ptr, "displacement_method", DISPLACE_NUM_METHODS, DISPLACE_BUMP);
}
static EmissionSampling get_emission_sampling(PointerRNA &ptr)
{
return (EmissionSampling)get_enum(
@ -76,6 +70,12 @@ static int validate_enum_value(int value, int num_values, int default_value)
return value;
}
static DisplacementMethod get_displacement_method(BL::Material &b_mat)
{
int value = b_mat.displacement_method();
return (DisplacementMethod)validate_enum_value(value, DISPLACE_NUM_METHODS, DISPLACE_BUMP);
}
template<typename NodeType> static InterpolationType get_image_interpolation(NodeType &b_node)
{
int value = b_node.interpolation();
@ -1548,7 +1548,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
shader->set_volume_sampling_method(get_volume_sampling(cmat));
shader->set_volume_interpolation_method(get_volume_interpolation(cmat));
shader->set_volume_step_rate(get_float(cmat, "volume_step_rate"));
shader->set_displacement_method(get_displacement_method(cmat));
shader->set_displacement_method(get_displacement_method(b_mat));
shader->set_graph(graph);

View File

@ -299,6 +299,9 @@ class EEVEE_NEXT_MATERIAL_PT_settings_surface(MaterialButtonsPanel, Panel):
col.prop(mat, "use_backface_culling", text="Camera")
col.prop(mat, "use_backface_culling_shadow", text="Shadow")
layout.prop(mat, "displacement_method", text="Displacement")
if mat.displacement_method == 'DISPLACEMENT':
layout.label(text="Unsupported displacement method", icon='ERROR')
layout.prop(mat, "max_vertex_displacement", text="Max Displacement")
layout.prop(mat, "use_transparent_shadow")

View File

@ -2514,5 +2514,17 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
scene->eevee.diffuse_options.screen_trace_max_roughness = 0.5f;
}
}
if (!DNA_struct_member_exists(fd->filesdna, "Material", "char", "displacement_method")) {
/* Replace Cycles.displacement_method by Material::displacement_method. */
LISTBASE_FOREACH (Material *, material, &bmain->materials) {
int displacement_method = MA_DISPLACEMENT_BUMP;
if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) {
displacement_method = version_cycles_property_int(
cmat, "displacement_method", MA_DISPLACEMENT_BUMP);
}
material->displacement_method = displacement_method;
}
}
}
}

View File

@ -190,8 +190,11 @@ MaterialPass MaterialModule::material_pass_get(Object *ob,
break;
case GPU_MAT_FAILED:
default:
matpass.gpumat = inst_.shaders.material_shader_get(
error_mat_, error_mat_->nodetree, pipeline_type, geometry_type, false);
matpass.gpumat = inst_.shaders.material_shader_get(error_mat_,
error_mat_->nodetree,
pipeline_type,
geometry_type,
false);
break;
}
/* Returned material should be ready to be drawn. */

View File

@ -61,6 +61,24 @@ static inline bool geometry_type_has_surface(eMaterialGeometry geometry_type)
return geometry_type < MAT_GEOM_VOLUME;
}
enum eMaterialDisplacement {
MAT_DISPLACEMENT_BUMP = 0,
MAT_DISPLACEMENT_VERTEX_WITH_BUMP,
};
static inline eMaterialDisplacement to_displacement_type(int displacement_method)
{
switch (displacement_method) {
case MA_DISPLACEMENT_DISPLACE:
/* Currently unsupported. Revert to vertex displacement + bump. */
ATTR_FALLTHROUGH;
case MA_DISPLACEMENT_BOTH:
return MAT_DISPLACEMENT_VERTEX_WITH_BUMP;
default:
return MAT_DISPLACEMENT_BUMP;
}
}
enum eMaterialProbe {
MAT_PROBE_NONE = 0,
MAT_PROBE_REFLECTION,
@ -70,23 +88,30 @@ enum eMaterialProbe {
static inline void material_type_from_shader_uuid(uint64_t shader_uuid,
eMaterialPipeline &pipeline_type,
eMaterialGeometry &geometry_type,
eMaterialDisplacement &displacement_type,
bool &transparent_shadows)
{
const uint64_t geometry_mask = ((1u << 4u) - 1u);
const uint64_t pipeline_mask = ((1u << 4u) - 1u);
const uint64_t displacement_mask = ((1u << 2u) - 1u);
geometry_type = static_cast<eMaterialGeometry>(shader_uuid & geometry_mask);
pipeline_type = static_cast<eMaterialPipeline>((shader_uuid >> 4u) & pipeline_mask);
transparent_shadows = (shader_uuid >> 8u) & 1u;
displacement_type = static_cast<eMaterialDisplacement>((shader_uuid >> 8u) & displacement_mask);
transparent_shadows = (shader_uuid >> 10u) & 1u;
}
static inline uint64_t shader_uuid_from_material_type(eMaterialPipeline pipeline_type,
eMaterialGeometry geometry_type,
char blend_flags)
static inline uint64_t shader_uuid_from_material_type(
eMaterialPipeline pipeline_type,
eMaterialGeometry geometry_type,
eMaterialDisplacement displacement_type = MAT_DISPLACEMENT_BUMP,
char blend_flags = 0)
{
BLI_assert(displacement_type < (1 << 2));
BLI_assert(geometry_type < (1 << 4));
BLI_assert(pipeline_type < (1 << 4));
uchar transparent_shadows = blend_flags & MA_BL_TRANSPARENT_SHADOW ? 1 : 0;
return geometry_type | (pipeline_type << 4) | (transparent_shadows << 8);
uint64_t transparent_shadows = blend_flags & MA_BL_TRANSPARENT_SHADOW ? 1 : 0;
return geometry_type | (pipeline_type << 4) | (displacement_type << 8) |
(transparent_shadows << 10);
}
ENUM_OPERATORS(eClosureBits, CLOSURE_AMBIENT_OCCLUSION)
@ -147,7 +172,8 @@ struct MaterialKey {
MaterialKey(::Material *mat_, eMaterialGeometry geometry, eMaterialPipeline pipeline) : mat(mat_)
{
options = shader_uuid_from_material_type(pipeline, geometry, mat_->blend_flag);
options = shader_uuid_from_material_type(
pipeline, geometry, to_displacement_type(mat_->displacement_method), mat_->blend_flag);
}
uint64_t hash() const

View File

@ -321,8 +321,10 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
eMaterialPipeline pipeline_type;
eMaterialGeometry geometry_type;
eMaterialDisplacement displacement_type;
bool transparent_shadows;
material_type_from_shader_uuid(shader_uuid, pipeline_type, geometry_type, transparent_shadows);
material_type_from_shader_uuid(
shader_uuid, pipeline_type, geometry_type, displacement_type, transparent_shadows);
GPUCodegenOutput &codegen = *codegen_;
ShaderCreateInfo &info = *reinterpret_cast<ShaderCreateInfo *>(codegen.create_info);
@ -501,17 +503,18 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
}
if (!is_compute) {
if (!ELEM(geometry_type,
MAT_GEOM_WORLD,
MAT_GEOM_VOLUME_WORLD,
MAT_GEOM_VOLUME_OBJECT,
MAT_GEOM_VOLUME))
{
vert_gen << "vec3 nodetree_displacement()\n";
vert_gen << "{\n";
vert_gen << ((codegen.displacement) ? codegen.displacement : "return vec3(0);\n");
vert_gen << "}\n\n";
}
const bool use_vertex_displacement = (codegen.displacement != nullptr) &&
(displacement_type != MAT_DISPLACEMENT_BUMP) &&
(!ELEM(geometry_type,
MAT_GEOM_WORLD,
MAT_GEOM_VOLUME_WORLD,
MAT_GEOM_VOLUME_OBJECT,
MAT_GEOM_VOLUME));
vert_gen << "vec3 nodetree_displacement()\n";
vert_gen << "{\n";
vert_gen << ((use_vertex_displacement) ? codegen.displacement : "return vec3(0);\n");
vert_gen << "}\n\n";
info.vertex_source_generated = vert_gen.str();
}
@ -654,8 +657,10 @@ GPUMaterial *ShaderModule::material_shader_get(::Material *blender_mat,
{
bool is_volume = ELEM(pipeline_type, MAT_PIPE_VOLUME_MATERIAL, MAT_PIPE_VOLUME_OCCUPANCY);
eMaterialDisplacement displacement_type = to_displacement_type(blender_mat->displacement_method);
uint64_t shader_uuid = shader_uuid_from_material_type(
pipeline_type, geometry_type, blender_mat->blend_flag);
pipeline_type, geometry_type, displacement_type, blender_mat->blend_flag);
return DRW_shader_from_material(
blender_mat, nodetree, shader_uuid, is_volume, deferred_compilation, codegen_callback, this);
@ -670,7 +675,7 @@ GPUMaterial *ShaderModule::world_shader_get(::World *blender_world,
eMaterialGeometry geometry_type = is_volume ? MAT_GEOM_VOLUME_WORLD : MAT_GEOM_WORLD;
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type, 0);
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type);
return DRW_shader_from_world(
blender_world, nodetree, shader_uuid, is_volume, defer_compilation, codegen_callback, this);
@ -685,7 +690,7 @@ GPUMaterial *ShaderModule::material_shader_get(const char *name,
eMaterialGeometry geometry_type,
bool is_lookdev)
{
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type, 0);
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type);
bool is_volume = ELEM(pipeline_type, MAT_PIPE_VOLUME_MATERIAL, MAT_PIPE_VOLUME_OCCUPANCY);

View File

@ -240,7 +240,7 @@ void dF_branch_incomplete(float fn, out vec2 result)
result = vec2(0.0);
}
#elif 0 /* TODO(@fclem): User Option? */
#elif defined(GPU_FAST_DERIVATIVE) /* TODO(@fclem): User Option? */
/* Fast derivatives */
vec3 dF_impl(vec3 v)
{

View File

@ -209,7 +209,10 @@ typedef struct Material {
short paint_active_slot;
short paint_clone_slot;
short tot_slots;
char _pad2[2];
/* Displacement. */
char displacement_method;
char _pad2[1];
/* Transparency. */
float alpha_threshold;
@ -376,6 +379,13 @@ enum {
MA_BS_HASHED = 3,
};
/** #Material::displacement_method */
enum {
MA_DISPLACEMENT_BUMP = 0,
MA_DISPLACEMENT_DISPLACE = 1,
MA_DISPLACEMENT_BOTH = 2,
};
/* Grease Pencil Stroke styles */
enum {
GP_MATERIAL_STROKE_STYLE_SOLID = 0,

View File

@ -857,6 +857,25 @@ void RNA_def_material(BlenderRNA *brna)
{0, nullptr, 0, nullptr, nullptr},
};
static EnumPropertyItem prop_displacement_method_items[] = {
{MA_DISPLACEMENT_BUMP,
"BUMP",
0,
"Bump Only",
"Bump mapping to simulate the appearance of displacement"},
{MA_DISPLACEMENT_DISPLACE,
"DISPLACEMENT",
0,
"Displacement Only",
"Use true displacement of surface only, requires fine subdivision"},
{MA_DISPLACEMENT_BOTH,
"BOTH",
0,
"Displacement and Bump",
"Combination of true displacement and bump mapping for finer detail"},
{0, nullptr, 0, nullptr, nullptr},
};
srna = RNA_def_struct(brna, "Material", "ID");
RNA_def_struct_ui_text(
srna,
@ -871,6 +890,11 @@ void RNA_def_material(BlenderRNA *brna)
"Controls the blending and the compatibility with certain features");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop = RNA_def_property(srna, "displacement_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_displacement_method_items);
RNA_def_property_ui_text(prop, "Displacement Method", "Method to use for the displacement");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
# if 1 /* Delete this section once we remove old eevee. */
/* Blending (only Eevee for now) */
prop = RNA_def_property(srna, "blend_method", PROP_ENUM, PROP_NONE);