Skip to content

Commit 3ba84a5

Browse files
committed
Don't render decals on solid objects' backfaces
- Fixes issue with decals appearing on backfaces of transparent, solid objects.
1 parent 6cc5391 commit 3ba84a5

6 files changed

Lines changed: 41 additions & 4 deletions

File tree

src/ccycles/ccycles.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ CCL_CAPI void CDECL cycles_scene_object_set_shader(ccl::Session* session_id, ccl
248248
* \ingroup ccycles_object
249249
*/
250250
CCL_CAPI void CDECL cycles_scene_object_set_is_shadowcatcher(ccl::Session* session_id, ccl::Object*, bool is_shadowcatcher);
251+
/**
252+
* Set is_solid flag for object
253+
* \ingroup ccycles_object
254+
*/
255+
CCL_CAPI void CDECL cycles_scene_object_set_is_solid(ccl::Session* session_id, ccl::Object*, bool is_solid);
251256
/**
252257
* Set mesh_light_no_cast_shadow flag for object. This is to signal that this mesh light shouldn't cast shadows.
253258
* \ingroup ccycles_object

src/ccycles/object.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ void cycles_scene_object_set_is_shadowcatcher(ccl::Session* session_id, ccl::Obj
148148
}
149149
}
150150

151+
void cycles_scene_object_set_is_solid(ccl::Session* session_id, ccl::Object* object, bool is_solid)
152+
{
153+
ASSERT(object);
154+
155+
ccl::Scene* sce = nullptr;
156+
if(scene_find(session_id, &sce)) {
157+
object->set_is_solid(is_solid);
158+
object->tag_update(sce);
159+
sce->light_manager->tag_update(sce, ccl::LightManager::UPDATE_ALL);
160+
}
161+
}
162+
151163
void cycles_scene_object_set_mesh_light_no_cast_shadow(ccl::Session* session_id, ccl::Object* object, bool mesh_light_no_cast_shadow)
152164
{
153165
ASSERT(object);

src/kernel/svm/tex_coord.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ ccl_device_inline void decal_data_read(KernelGlobals kg,
350350
uint decal_map_side;
351351
uint type = node.y;
352352
uint out_offset = node.z;
353+
const bool suppress_for_solid_backface =
354+
((sd->object_flag & SD_OBJECT_IS_SOLID) != 0) && ((sd->flag & SD_BACKFACING) != 0);
353355

354356
float3 uv = stack_load_float3(stack, out_offset);
355357

@@ -411,6 +413,7 @@ ccl_device_inline void decal_data_read(KernelGlobals kg,
411413
decal->cur_uv.x = uv.x;
412414
decal->cur_uv.y = uv.y;
413415
decal->data = map_to_uv(data, *decal);
416+
decal->on_correct_side = !suppress_for_solid_backface;
414417
}
415418
else {
416419

@@ -449,6 +452,10 @@ ccl_device_inline void decal_data_read(KernelGlobals kg,
449452
} break;
450453
}
451454
}
455+
456+
if (suppress_for_solid_backface) {
457+
decal->on_correct_side = false;
458+
}
452459
}
453460

454461
// stack_store_float(stack, decal_forward_offset, dotp > 0.0f ? 1.0f : -1.0f);
@@ -696,7 +703,9 @@ ccl_device_noinline int svm_rhino_node_tex_coord(KernelGlobals kg,
696703
DecalData decal;
697704
decal_data_read(kg, sd, stack, node, &offset, &decal, 0);
698705
data = decal.data;
699-
// data = map_to_uv(data, decal);
706+
if (!decal.on_correct_side) {
707+
data.z = -1.0f;
708+
}
700709
break;
701710
}
702711
case NODE_TEXCO_ENV_DECAL_PLANAR: {
@@ -888,7 +897,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
888897
DecalData decal;
889898
decal_data_read(kg, sd, stack, node, &offset, &decal, 0);
890899
data = decal.data;
891-
// data = map_to_uv(data, decal);
900+
if (!decal.on_correct_side) {
901+
data.z = -1.0f;
902+
}
892903
break;
893904
}
894905
case NODE_TEXCO_ENV_DECAL_PLANAR: {
@@ -1083,7 +1094,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
10831094
DecalData decal;
10841095
decal_data_read(kg, sd, stack, node, &offset, &decal, 0);
10851096
data = decal.data;
1086-
// data = map_to_uv(data, decal);
1097+
if (!decal.on_correct_side) {
1098+
data.z = -1.0f;
1099+
}
10871100
break;
10881101
}
10891102
case NODE_TEXCO_ENV_DECAL_PLANAR: {

src/kernel/types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,8 @@ enum ShaderDataObjectFlag {
874874
SD_OBJECT_HAS_VOLUME_MOTION = (1 << 11),
875875
/* object is mesh lamp, but doesn't cast shadows */
876876
SD_OBJECT_LIGHT_NO_CAST_SHADOWS = (1 << 12),
877+
/* object represents solid geometry */
878+
SD_OBJECT_IS_SOLID = (1 << 13),
877879

878880
/* object is using caustics */
879881
SD_OBJECT_CAUSTICS = (SD_OBJECT_CAUSTICS_CASTER | SD_OBJECT_CAUSTICS_RECEIVER),
@@ -882,7 +884,7 @@ enum ShaderDataObjectFlag {
882884
SD_OBJECT_NEGATIVE_SCALE | SD_OBJECT_HAS_VOLUME |
883885
SD_OBJECT_INTERSECTS_VOLUME | SD_OBJECT_SHADOW_CATCHER |
884886
SD_OBJECT_HAS_VOLUME_ATTRIBUTES | SD_OBJECT_CAUSTICS |
885-
SD_OBJECT_HAS_VOLUME_MOTION)
887+
SD_OBJECT_HAS_VOLUME_MOTION | SD_OBJECT_IS_SOLID)
886888
};
887889

888890
typedef struct ccl_align(16) ShaderData

src/scene/object.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ NODE_DEFINE(Object)
9090
SOCKET_STRING(asset_name, "Asset Name", ustring());
9191

9292
SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false);
93+
SOCKET_BOOLEAN(is_solid, "Solid", false);
9394
SOCKET_BOOLEAN(mesh_light_no_cast_shadow, "Mesh Light No Cast Shadow", false);
9495

9596
SOCKET_BOOLEAN(is_caustics_caster, "Cast Shadow Caustics", false);
@@ -569,6 +570,9 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
569570
if (ob->use_holdout) {
570571
flag |= SD_OBJECT_HOLDOUT_MASK;
571572
}
573+
if (ob->is_solid) {
574+
flag |= SD_OBJECT_IS_SOLID;
575+
}
572576
state->object_flag[ob->index] = flag;
573577
state->object_volume_step[ob->index] = FLT_MAX;
574578

src/scene/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class Object : public Node {
5353
NODE_SOCKET_API(bool, hide_on_missing_motion)
5454
NODE_SOCKET_API(bool, use_holdout)
5555
NODE_SOCKET_API(bool, is_shadow_catcher)
56+
NODE_SOCKET_API(bool, is_solid)
5657
NODE_SOCKET_API(bool, mesh_light_no_cast_shadow)
5758
NODE_SOCKET_API(float, shadow_terminator_shading_offset)
5859
NODE_SOCKET_API(float, shadow_terminator_geometry_offset)

0 commit comments

Comments
 (0)