EEVEE-Next: Displacement Option

This add the displacement option to EEVEE materials.
This unifies the option for Cycles and EEVEE.

The displacement only option is not matching cycles
and not particularly useful. So we decided to not
support it and revert to displacement + bump.

Pull Request: https://projects.blender.org/blender/blender/pulls/113979
This commit is contained in:
Clément Foucault
2023-11-21 19:55:38 +01:00
committed by Clément Foucault
parent 14500953ed
commit a001cf9f2b
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);