EEVEE-Next: New shadow settings #113980
|
@ -1013,12 +1013,6 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
|
|||
default="AUTO",
|
||||
)
|
||||
|
||||
use_transparent_shadow: BoolProperty(
|
||||
name="Transparent Shadows",
|
||||
description="Use transparent shadows for this material if it contains a Transparent BSDF, "
|
||||
"disabling will render faster but not give accurate shadows",
|
||||
default=True,
|
||||
)
|
||||
use_bump_map_correction: BoolProperty(
|
||||
name="Bump Map Correction",
|
||||
description="Apply corrections to solve shadow terminator artifacts caused by bump mapping",
|
||||
|
|
|
@ -1966,7 +1966,7 @@ class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
|
|||
col = layout.column()
|
||||
col.prop(cmat, "displacement_method", text="Displacement")
|
||||
col.prop(cmat, "emission_sampling")
|
||||
col.prop(cmat, "use_transparent_shadow")
|
||||
col.prop(mat, "use_transparent_shadow")
|
||||
col.prop(cmat, "use_bump_map_correction")
|
||||
|
||||
def draw(self, context):
|
||||
|
|
|
@ -1550,7 +1550,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
|||
/* settings */
|
||||
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
|
||||
shader->set_emission_sampling_method(get_emission_sampling(cmat));
|
||||
shader->set_use_transparent_shadow(get_boolean(cmat, "use_transparent_shadow"));
|
||||
shader->set_use_transparent_shadow(b_mat.use_transparent_shadow());
|
||||
shader->set_use_bump_map_correction(get_boolean(cmat, "use_bump_map_correction"));
|
||||
shader->set_heterogeneous_volume(!get_boolean(cmat, "homogeneous_volume"));
|
||||
shader->set_volume_sampling_method(get_volume_sampling(cmat));
|
||||
|
|
|
@ -300,7 +300,7 @@ class EEVEE_NEXT_MATERIAL_PT_settings_surface(MaterialButtonsPanel, Panel):
|
|||
col.prop(mat, "use_backface_culling_shadow", text="Shadow")
|
||||
|
||||
# TODO(fclem): Displacement option
|
||||
# TODO(fclem): Transparent shadow option
|
||||
layout.prop(mat, "use_transparent_shadow")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(mat, "surface_render_method", text="Render Method")
|
||||
|
|
|
@ -390,6 +390,11 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
|
|||
col.prop(ob, "hide_render", text="Renders", toggle=False, invert_checkbox=True)
|
||||
|
||||
if context.engine == 'BLENDER_EEVEE_NEXT':
|
||||
if ob.type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'CURVES', 'POINTCLOUD', 'VOLUME'}:
|
||||
layout.separator()
|
||||
col = layout.column(heading="Ray Visibility")
|
||||
col.prop(ob, "visible_shadow", text="Shadow", toggle=False)
|
||||
fclem marked this conversation as resolved
|
||||
|
||||
if ob.type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'CURVES', 'POINTCLOUD', 'VOLUME', 'LIGHT'}:
|
||||
layout.separator()
|
||||
col = layout.column(heading="Light Probes")
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 4
|
||||
#define BLENDER_FILE_SUBVERSION 5
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
|
|
@ -47,11 +47,13 @@
|
|||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idprop.hh"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh_legacy_convert.hh"
|
||||
#include "BKE_node.hh"
|
||||
#include "BKE_node_runtime.hh"
|
||||
|
@ -298,6 +300,30 @@ static void version_principled_bsdf_update_animdata(ID *owner_id, bNodeTree *ntr
|
|||
}
|
||||
}
|
||||
|
||||
static void versioning_eevee_shadow_settings(Object *object)
|
||||
{
|
||||
/** EEVEE no longer uses the Material::blend_shadow property.
|
||||
* Instead, it uses Object::visibility_flag for disabling shadow casting
|
||||
*/
|
||||
|
||||
short *material_len = BKE_object_material_len_p(object);
|
||||
if (!material_len) {
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace blender;
|
||||
bool hide_shadows = *material_len > 0;
|
||||
for (int i : IndexRange(*material_len)) {
|
||||
Material *material = BKE_object_material_get(object, i + 1);
|
||||
if (!material || material->blend_shadow != MA_BS_NONE) {
|
||||
hide_shadows = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable the hide_shadow flag only if there's not any shadow casting material. */
|
||||
SET_FLAG_FROM_TEST(object->visibility_flag, hide_shadows, OB_HIDE_SHADOW);
|
||||
}
|
||||
|
||||
void do_versions_after_linking_400(FileData *fd, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) {
|
||||
|
@ -382,6 +408,16 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
|
|||
BKE_mesh_legacy_face_map_to_generic(bmain);
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) {
|
||||
Scene *scene = static_cast<Scene *>(bmain->scenes.first);
|
||||
bool is_cycles = scene && STREQ(scene->r.engine, RE_engine_id_CYCLES);
|
||||
if (!is_cycles) {
|
||||
LISTBASE_FOREACH (Object *, object, &bmain->objects) {
|
||||
versioning_eevee_shadow_settings(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
@ -1783,6 +1819,29 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) {
|
||||
/* Unify Material::blend_shadow and Cycles.use_transparent_shadows into the
|
||||
* Material::blend_flag. */
|
||||
Scene *scene = static_cast<Scene *>(bmain->scenes.first);
|
||||
bool is_cycles = scene && STREQ(scene->r.engine, RE_engine_id_CYCLES);
|
||||
if (is_cycles) {
|
||||
LISTBASE_FOREACH (Material *, material, &bmain->materials) {
|
||||
bool transparent_shadows = true;
|
||||
pragma37 marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
I'm not really sure what the purpose is of this logic. Why not just set this to I'm not really sure what the purpose is of this logic. Why not just set this to `true`? The previous Cycles default does not depend on this DNA default.
|
||||
if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) {
|
||||
transparent_shadows = version_cycles_property_boolean(
|
||||
cmat, "use_transparent_shadow", true);
|
||||
}
|
||||
SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadows, MA_BL_TRANSPARENT_SHADOW);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LISTBASE_FOREACH (Material *, material, &bmain->materials) {
|
||||
bool transparent_shadow = material->blend_shadow != MA_BS_SOLID;
|
||||
SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadow, MA_BL_TRANSPARENT_SHADOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
|
|
@ -69,19 +69,24 @@ enum eMaterialProbe {
|
|||
|
||||
static inline void material_type_from_shader_uuid(uint64_t shader_uuid,
|
||||
eMaterialPipeline &pipeline_type,
|
||||
eMaterialGeometry &geometry_type)
|
||||
eMaterialGeometry &geometry_type,
|
||||
bool &transparent_shadows)
|
||||
{
|
||||
const uint64_t geometry_mask = ((1u << 4u) - 1u);
|
||||
const uint64_t pipeline_mask = ((1u << 4u) - 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;
|
||||
}
|
||||
|
||||
static inline uint64_t shader_uuid_from_material_type(eMaterialPipeline pipeline_type,
|
||||
eMaterialGeometry geometry_type)
|
||||
eMaterialGeometry geometry_type,
|
||||
char blend_flags)
|
||||
{
|
||||
BLI_assert(geometry_type < (1 << 4));
|
||||
return geometry_type | (pipeline_type << 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);
|
||||
}
|
||||
|
||||
ENUM_OPERATORS(eClosureBits, CLOSURE_AMBIENT_OCCLUSION)
|
||||
|
@ -142,7 +147,7 @@ struct MaterialKey {
|
|||
|
||||
MaterialKey(::Material *mat_, eMaterialGeometry geometry, eMaterialPipeline pipeline) : mat(mat_)
|
||||
{
|
||||
options = shader_uuid_from_material_type(pipeline, geometry);
|
||||
options = shader_uuid_from_material_type(pipeline, geometry, mat_->blend_flag);
|
||||
}
|
||||
|
||||
uint64_t hash() const
|
||||
|
|
|
@ -311,7 +311,8 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
|||
|
||||
eMaterialPipeline pipeline_type;
|
||||
eMaterialGeometry geometry_type;
|
||||
material_type_from_shader_uuid(shader_uuid, pipeline_type, geometry_type);
|
||||
bool transparent_shadows;
|
||||
material_type_from_shader_uuid(shader_uuid, pipeline_type, geometry_type, transparent_shadows);
|
||||
|
||||
GPUCodegenOutput &codegen = *codegen_;
|
||||
ShaderCreateInfo &info = *reinterpret_cast<ShaderCreateInfo *>(codegen.create_info);
|
||||
|
@ -356,7 +357,9 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
|||
}
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
|
||||
info.define("MAT_TRANSPARENT");
|
||||
if (pipeline_type != MAT_PIPE_SHADOW || transparent_shadows) {
|
||||
info.define("MAT_TRANSPARENT");
|
||||
}
|
||||
/* Transparent material do not have any velocity specific pipeline. */
|
||||
if (pipeline_type == MAT_PIPE_PREPASS_FORWARD_VELOCITY) {
|
||||
pipeline_type = MAT_PIPE_PREPASS_FORWARD;
|
||||
|
@ -641,7 +644,8 @@ GPUMaterial *ShaderModule::material_shader_get(::Material *blender_mat,
|
|||
{
|
||||
bool is_volume = ELEM(pipeline_type, MAT_PIPE_VOLUME_MATERIAL, MAT_PIPE_VOLUME_OCCUPANCY);
|
||||
|
||||
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type);
|
||||
uint64_t shader_uuid = shader_uuid_from_material_type(
|
||||
pipeline_type, geometry_type, blender_mat->blend_flag);
|
||||
|
||||
return DRW_shader_from_material(
|
||||
blender_mat, nodetree, shader_uuid, is_volume, deferred_compilation, codegen_callback, this);
|
||||
|
@ -656,7 +660,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);
|
||||
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type, 0);
|
||||
|
||||
return DRW_shader_from_world(
|
||||
blender_world, nodetree, shader_uuid, is_volume, defer_compilation, codegen_callback, this);
|
||||
|
@ -671,7 +675,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);
|
||||
uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type, 0);
|
||||
|
||||
bool is_volume = ELEM(pipeline_type, MAT_PIPE_VOLUME_MATERIAL, MAT_PIPE_VOLUME_OCCUPANCY);
|
||||
|
||||
|
|
|
@ -893,11 +893,12 @@ void ShadowModule::begin_sync()
|
|||
}
|
||||
}
|
||||
|
||||
void ShadowModule::sync_object(const ObjectHandle &handle,
|
||||
void ShadowModule::sync_object(const Object *ob,
|
||||
const ObjectHandle &handle,
|
||||
const ResourceHandle &resource_handle,
|
||||
bool is_shadow_caster,
|
||||
bool is_alpha_blend)
|
||||
{
|
||||
bool is_shadow_caster = !(ob->visibility_flag & OB_HIDE_SHADOW);
|
||||
if (!is_shadow_caster && !is_alpha_blend) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -328,9 +328,9 @@ class ShadowModule {
|
|||
|
||||
void begin_sync();
|
||||
/** Register a shadow caster or receiver. */
|
||||
void sync_object(const ObjectHandle &handle,
|
||||
void sync_object(const Object *ob,
|
||||
const ObjectHandle &handle,
|
||||
const ResourceHandle &resource_handle,
|
||||
bool is_shadow_caster,
|
||||
bool is_alpha_blend);
|
||||
void end_sync();
|
||||
|
||||
|
|
|
@ -140,7 +140,6 @@ void SyncModule::sync_mesh(Object *ob,
|
|||
return;
|
||||
}
|
||||
|
||||
bool is_shadow_caster = false;
|
||||
bool is_alpha_blend = false;
|
||||
for (auto i : material_array.gpu_materials.index_range()) {
|
||||
GPUBatch *geom = mat_geom[i];
|
||||
|
@ -173,7 +172,6 @@ void SyncModule::sync_mesh(Object *ob,
|
|||
geometry_call(material.reflection_probe_prepass.sub_pass, geom, res_handle);
|
||||
geometry_call(material.reflection_probe_shading.sub_pass, geom, res_handle);
|
||||
|
||||
is_shadow_caster = is_shadow_caster || material.shadow.sub_pass != nullptr;
|
||||
is_alpha_blend = is_alpha_blend || material.is_alpha_blend_transparent;
|
||||
|
||||
::Material *mat = GPU_material_get_material(gpu_material);
|
||||
|
@ -182,7 +180,7 @@ void SyncModule::sync_mesh(Object *ob,
|
|||
|
||||
inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials);
|
||||
|
||||
inst_.shadows.sync_object(ob_handle, res_handle, is_shadow_caster, is_alpha_blend);
|
||||
inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend);
|
||||
inst_.cryptomatte.sync_object(ob, res_handle);
|
||||
}
|
||||
|
||||
|
@ -215,7 +213,6 @@ bool SyncModule::sync_sculpt(Object *ob,
|
|||
bool has_motion = false;
|
||||
MaterialArray &material_array = inst_.materials.material_array_get(ob, has_motion);
|
||||
|
||||
bool is_shadow_caster = false;
|
||||
bool is_alpha_blend = false;
|
||||
for (SculptBatch &batch :
|
||||
sculpt_batches_per_material_get(ob_ref.object, material_array.gpu_materials))
|
||||
|
@ -249,7 +246,6 @@ bool SyncModule::sync_sculpt(Object *ob,
|
|||
geometry_call(material.reflection_probe_prepass.sub_pass, geom, res_handle);
|
||||
geometry_call(material.reflection_probe_shading.sub_pass, geom, res_handle);
|
||||
|
||||
is_shadow_caster = is_shadow_caster || material.shadow.sub_pass != nullptr;
|
||||
is_alpha_blend = is_alpha_blend || material.is_alpha_blend_transparent;
|
||||
|
||||
GPUMaterial *gpu_material = material_array.gpu_materials[batch.material_slot];
|
||||
|
@ -259,7 +255,7 @@ bool SyncModule::sync_sculpt(Object *ob,
|
|||
|
||||
inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials);
|
||||
|
||||
inst_.shadows.sync_object(ob_handle, res_handle, is_shadow_caster, is_alpha_blend);
|
||||
inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend);
|
||||
inst_.cryptomatte.sync_object(ob, res_handle);
|
||||
|
||||
return true;
|
||||
|
@ -322,9 +318,8 @@ void SyncModule::sync_point_cloud(Object *ob,
|
|||
::Material *mat = GPU_material_get_material(gpu_material);
|
||||
inst_.cryptomatte.sync_material(mat);
|
||||
|
||||
bool is_caster = material.shadow.sub_pass != nullptr;
|
||||
bool is_alpha_blend = material.is_alpha_blend_transparent;
|
||||
inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend);
|
||||
inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -486,9 +481,8 @@ void SyncModule::sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandl
|
|||
|
||||
gpencil_drawcall_flush(iter);
|
||||
|
||||
bool is_caster = true; /* TODO material.shadow.sub_pass. */
|
||||
bool is_alpha_blend = true; /* TODO material.is_alpha_blend. */
|
||||
inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend);
|
||||
inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -557,9 +551,8 @@ void SyncModule::sync_curves(Object *ob,
|
|||
::Material *mat = GPU_material_get_material(gpu_material);
|
||||
inst_.cryptomatte.sync_material(mat);
|
||||
|
||||
bool is_caster = material.shadow.sub_pass != nullptr;
|
||||
bool is_alpha_blend = material.is_alpha_blend_transparent;
|
||||
inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend);
|
||||
inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
.alpha_threshold = 0.5f, \
|
||||
\
|
||||
.blend_shadow = MA_BS_SOLID, \
|
||||
\
|
||||
.blend_flag = MA_BL_TRANSPARENT_SHADOW,\
|
||||
\
|
||||
.lineart.mat_occlusion = 1, \
|
||||
}
|
||||
|
|
|
@ -360,6 +360,7 @@ enum {
|
|||
MA_BL_TRANSLUCENCY = (1 << 3),
|
||||
MA_BL_LIGHTPROBE_VOLUME_DOUBLE_SIDED = (1 << 4),
|
||||
MA_BL_CULL_BACKFACE_SHADOW = (1 << 5),
|
||||
MA_BL_TRANSPARENT_SHADOW = (1 << 6),
|
||||
};
|
||||
|
||||
/** #Material::blend_shadow */
|
||||
|
|
|
@ -909,6 +909,15 @@ void RNA_def_material(BlenderRNA *brna)
|
|||
prop, "Shadow Backface Culling", "Use back face culling when casting shadows");
|
||||
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparent_shadow", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "blend_flag", MA_BL_TRANSPARENT_SHADOW);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Transparent Shadows",
|
||||
"Use transparent shadows for this material if it contains a Transparent BSDF, "
|
||||
"disabling will render faster but not give accurate shadows");
|
||||
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
|
||||
|
||||
prop = RNA_def_property(srna, "lightprobe_volume_single_sided", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(
|
||||
prop, nullptr, "blend_flag", MA_BL_LIGHTPROBE_VOLUME_DOUBLE_SIDED);
|
||||
|
|
Loading…
Reference in New Issue
Use
hide_shadow
for consistency with the other visibility options for now.I think having 2 different Python properties that change the same flag is going to be quite confusing for Python users.
Nevermind, I replied to this before we decided to unify the setting first. So use cycles naming convention for now. We can still create an alias if we decide to port it later.
We can do that for compatibility reasons.