From bc096e1eb8790c1624ce7386cd86668267fbea48 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Dec 2016 11:31:19 +0100 Subject: [PATCH] Cycles: Split ShaderData object and shader flags We started to run out of bits there, so now we separate flags which came from __object_flags and which are either runtime or coming from __shader_flags. Rule now is: SD_OBJECT_* flags are to be tested against new object_flags field of ShaderData, all the rest flags are to be tested against flags field of ShaderData. There should be no user-visible changes, and time difference should be minimal. In fact, from tests here can only see hardly measurable difference and sometimes the new code is somewhat faster (all within a noise floor, so hard to tell for sure). Reviewers: brecht, dingto, juicyfruit, lukasstockner97, maiself Differential Revision: https://developer.blender.org/D2428 --- intern/cycles/kernel/bvh/bvh_volume.h | 2 - intern/cycles/kernel/bvh/bvh_volume_all.h | 1 - intern/cycles/kernel/bvh/qbvh_volume.h | 1 - intern/cycles/kernel/bvh/qbvh_volume_all.h | 2 - .../kernel/geom/geom_motion_triangle_shader.h | 2 +- intern/cycles/kernel/geom/geom_object.h | 1 - intern/cycles/kernel/geom/geom_primitive.h | 5 +- intern/cycles/kernel/geom/geom_triangle.h | 16 +-- intern/cycles/kernel/kernel_path.h | 18 ++- intern/cycles/kernel/kernel_path_branched.h | 19 +-- intern/cycles/kernel/kernel_shader.h | 27 ++-- intern/cycles/kernel/kernel_types.h | 136 ++++++++++++------ intern/cycles/kernel/osl/osl_services.cpp | 2 +- ...out_emission_blurring_pathtermination_ao.h | 14 +- intern/cycles/kernel/svm/svm_wireframe.h | 2 +- 15 files changed, 155 insertions(+), 93 deletions(-) diff --git a/intern/cycles/kernel/bvh/bvh_volume.h b/intern/cycles/kernel/bvh/bvh_volume.h index 107373c17dc..57e5b8d736d 100644 --- a/intern/cycles/kernel/bvh/bvh_volume.h +++ b/intern/cycles/kernel/bvh/bvh_volume.h @@ -236,9 +236,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance push */ object = kernel_tex_fetch(__prim_object, -prim_addr-1); int object_flag = kernel_tex_fetch(__object_flag, object); - if(object_flag & SD_OBJECT_HAS_VOLUME) { - # if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); # else diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h index 529848ebe7b..5a1accebaa0 100644 --- a/intern/cycles/kernel/bvh/bvh_volume_all.h +++ b/intern/cycles/kernel/bvh/bvh_volume_all.h @@ -287,7 +287,6 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance push */ object = kernel_tex_fetch(__prim_object, -prim_addr-1); int object_flag = kernel_tex_fetch(__object_flag, object); - if(object_flag & SD_OBJECT_HAS_VOLUME) { # if BVH_FEATURE(BVH_MOTION) diff --git a/intern/cycles/kernel/bvh/qbvh_volume.h b/intern/cycles/kernel/bvh/qbvh_volume.h index 1e77d8e67ec..dc6627e2dbb 100644 --- a/intern/cycles/kernel/bvh/qbvh_volume.h +++ b/intern/cycles/kernel/bvh/qbvh_volume.h @@ -293,7 +293,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance push. */ object = kernel_tex_fetch(__prim_object, -prim_addr-1); int object_flag = kernel_tex_fetch(__object_flag, object); - if(object_flag & SD_OBJECT_HAS_VOLUME) { # if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); diff --git a/intern/cycles/kernel/bvh/qbvh_volume_all.h b/intern/cycles/kernel/bvh/qbvh_volume_all.h index eb48af6fc68..ff1fa92af6e 100644 --- a/intern/cycles/kernel/bvh/qbvh_volume_all.h +++ b/intern/cycles/kernel/bvh/qbvh_volume_all.h @@ -344,9 +344,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance push. */ object = kernel_tex_fetch(__prim_object, -prim_addr-1); int object_flag = kernel_tex_fetch(__object_flag, object); - if(object_flag & SD_OBJECT_HAS_VOLUME) { - # if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); # else diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h index 5b1e014f850..0e024a05db6 100644 --- a/intern/cycles/kernel/geom/geom_motion_triangle_shader.h +++ b/intern/cycles/kernel/geom/geom_motion_triangle_shader.h @@ -81,7 +81,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, } /* Compute face normal. */ float3 Ng; - if(ccl_fetch(sd, flag) & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if(ccl_fetch(sd, object_flag) & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0])); } else { diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 9f0fe032ba4..f51b2d18657 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -113,7 +113,6 @@ ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg, int object, float time, Transform *itfm) { int object_flag = kernel_tex_fetch(__object_flag, object); - if(object_flag & SD_OBJECT_MOTION) { /* if we do motion blur */ Transform tfm = object_fetch_transform_motion(kg, object, time); diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h index dba82588dbc..8a73bb2f78b 100644 --- a/intern/cycles/kernel/geom/geom_primitive.h +++ b/intern/cycles/kernel/geom/geom_primitive.h @@ -157,8 +157,9 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData * if(is_curve_primitive) { center = curve_motion_center_location(kg, sd); - if(!(ccl_fetch(sd, flag) & SD_OBJECT_TRANSFORM_APPLIED)) + if(!(ccl_fetch(sd, object_flag) & SD_OBJECT_TRANSFORM_APPLIED)) { object_position_transform(kg, sd, ¢er); + } } else #endif @@ -181,7 +182,7 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData * motion_post = primitive_attribute_float3(kg, sd, desc, NULL, NULL); #ifdef __HAIR__ - if(is_curve_primitive && (ccl_fetch(sd, flag) & SD_OBJECT_HAS_VERTEX_MOTION) == 0) { + if(is_curve_primitive && (ccl_fetch(sd, object_flag) & SD_OBJECT_HAS_VERTEX_MOTION) == 0) { object_position_transform(kg, sd, &motion_pre); object_position_transform(kg, sd, &motion_post); } diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 9ed619f0bbf..3229091bbb0 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -32,10 +32,12 @@ ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd) const float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); /* return normal */ - if(ccl_fetch(sd, flag) & SD_OBJECT_NEGATIVE_SCALE_APPLIED) + if(ccl_fetch(sd, object_flag) & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { return normalize(cross(v2 - v0, v1 - v0)); - else + } + else { return normalize(cross(v1 - v0, v2 - v0)); + } } /* point and normal on triangle */ @@ -46,20 +48,18 @@ ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0)); float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1)); float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2)); - /* compute point */ float t = 1.0f - u - v; *P = (u*v0 + v*v1 + t*v2); - /* get object flags */ int object_flag = kernel_tex_fetch(__object_flag, object); - /* compute normal */ - if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) + if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { *Ng = normalize(cross(v2 - v0, v1 - v0)); - else + } + else { *Ng = normalize(cross(v1 - v0, v2 - v0)); - + } /* shader`*/ *shader = kernel_tex_fetch(__tri_shader, prim); } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 557c308b747..8ce9a4f02ec 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -452,7 +452,7 @@ bool kernel_path_subsurface_scatter( # ifdef __VOLUME__ ss_indirect->need_update_volume_stack = kernel_data.integrator.use_volumes && - ccl_fetch(sd, flag) & SD_OBJECT_INTERSECTS_VOLUME; + ccl_fetch(sd, object_flag) & SD_OBJECT_INTERSECTS_VOLUME; # endif /* __VOLUME__ */ /* compute lighting with the BSDF closure */ @@ -777,21 +777,25 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, /* holdout */ #ifdef __HOLDOUT__ - if((sd.flag & (SD_HOLDOUT|SD_OBJECT_HOLDOUT_MASK)) && (state.flag & PATH_RAY_CAMERA)) { + if(((sd.flag & SD_HOLDOUT) || + (sd.object_flag & SD_OBJECT_HOLDOUT_MASK)) && + (state.flag & PATH_RAY_CAMERA)) + { if(kernel_data.background.transparent) { float3 holdout_weight; - - if(sd.flag & SD_OBJECT_HOLDOUT_MASK) + if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) { holdout_weight = make_float3(1.0f, 1.0f, 1.0f); - else + } + else { holdout_weight = shader_holdout_eval(kg, &sd); - + } /* any throughput is ok, should all be identical here */ L_transparent += average(holdout_weight*throughput); } - if(sd.flag & SD_OBJECT_HOLDOUT_MASK) + if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) { break; + } } #endif /* __HOLDOUT__ */ diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 4ec0ac8e8c9..ff2b828795d 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -167,8 +167,9 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, true); #ifdef __VOLUME__ Ray volume_ray = *ray; - bool need_update_volume_stack = kernel_data.integrator.use_volumes && - ccl_fetch(sd, flag) & SD_OBJECT_INTERSECTS_VOLUME; + bool need_update_volume_stack = + kernel_data.integrator.use_volumes && + ccl_fetch(sd, object_flag) & SD_OBJECT_INTERSECTS_VOLUME; #endif /* __VOLUME__ */ /* compute lighting with the BSDF closure */ @@ -473,21 +474,21 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in /* holdout */ #ifdef __HOLDOUT__ - if(sd.flag & (SD_HOLDOUT|SD_OBJECT_HOLDOUT_MASK)) { + if((sd.flag & SD_HOLDOUT) || (sd.object_flag & SD_OBJECT_HOLDOUT_MASK)) { if(kernel_data.background.transparent) { float3 holdout_weight; - - if(sd.flag & SD_OBJECT_HOLDOUT_MASK) + if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) { holdout_weight = make_float3(1.0f, 1.0f, 1.0f); - else + } + else { holdout_weight = shader_holdout_eval(kg, &sd); - + } /* any throughput is ok, should all be identical here */ L_transparent += average(holdout_weight*throughput); } - - if(sd.flag & SD_OBJECT_HOLDOUT_MASK) + if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) { break; + } } #endif /* __HOLDOUT__ */ diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index d7a9167aaf8..d0826e5e879 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -38,7 +38,7 @@ CCL_NAMESPACE_BEGIN #ifdef __OBJECT_MOTION__ ccl_device void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) { - if(ccl_fetch(sd, flag) & SD_OBJECT_MOTION) { + if(ccl_fetch(sd, object_flag) & SD_OBJECT_MOTION) { ccl_fetch(sd, ob_tfm) = object_fetch_transform_motion(kg, ccl_fetch(sd, object), time); ccl_fetch(sd, ob_itfm) = transform_quick_inverse(ccl_fetch(sd, ob_tfm)); } @@ -59,7 +59,9 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg, #endif ccl_fetch(sd, type) = isect->type; - ccl_fetch(sd, flag) = kernel_tex_fetch(__object_flag, ccl_fetch(sd, object)); + ccl_fetch(sd, flag) = 0; + ccl_fetch(sd, object_flag) = kernel_tex_fetch(__object_flag, + ccl_fetch(sd, object)); /* matrices and time */ #ifdef __OBJECT_MOTION__ @@ -160,10 +162,11 @@ void shader_setup_from_subsurface( const Intersection *isect, const Ray *ray) { - bool backfacing = sd->flag & SD_BACKFACING; + const bool backfacing = sd->flag & SD_BACKFACING; /* object, matrices, time, ray_length stay the same */ - sd->flag = kernel_tex_fetch(__object_flag, sd->object); + sd->flag = 0; + sd->object_flag = kernel_tex_fetch(__object_flag, sd->object); sd->prim = kernel_tex_fetch(__prim_index, isect->prim); sd->type = isect->type; @@ -271,8 +274,10 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, ccl_fetch(sd, ray_length) = t; ccl_fetch(sd, flag) = kernel_tex_fetch(__shader_flag, (ccl_fetch(sd, shader) & SHADER_MASK)*SHADER_SIZE); + ccl_fetch(sd, object_flag) = 0; if(ccl_fetch(sd, object) != OBJECT_NONE) { - ccl_fetch(sd, flag) |= kernel_tex_fetch(__object_flag, ccl_fetch(sd, object)); + ccl_fetch(sd, object_flag) |= kernel_tex_fetch(__object_flag, + ccl_fetch(sd, object)); #ifdef __OBJECT_MOTION__ shader_setup_object_transforms(kg, sd, time); @@ -298,7 +303,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, ccl_fetch(sd, N) = triangle_smooth_normal(kg, ccl_fetch(sd, prim), ccl_fetch(sd, u), ccl_fetch(sd, v)); #ifdef __INSTANCING__ - if(!(ccl_fetch(sd, flag) & SD_OBJECT_TRANSFORM_APPLIED)) { + if(!(ccl_fetch(sd, object_flag) & SD_OBJECT_TRANSFORM_APPLIED)) { object_normal_transform_auto(kg, sd, &ccl_fetch(sd, N)); } #endif @@ -309,7 +314,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, triangle_dPdudv(kg, ccl_fetch(sd, prim), &ccl_fetch(sd, dPdu), &ccl_fetch(sd, dPdv)); # ifdef __INSTANCING__ - if(!(ccl_fetch(sd, flag) & SD_OBJECT_TRANSFORM_APPLIED)) { + if(!(ccl_fetch(sd, object_flag) & SD_OBJECT_TRANSFORM_APPLIED)) { object_dir_transform_auto(kg, sd, &ccl_fetch(sd, dPdu)); object_dir_transform_auto(kg, sd, &ccl_fetch(sd, dPdv)); } @@ -379,6 +384,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat ccl_fetch(sd, I) = -ray->D; ccl_fetch(sd, shader) = kernel_data.background.surface_shader; ccl_fetch(sd, flag) = kernel_tex_fetch(__shader_flag, (ccl_fetch(sd, shader) & SHADER_MASK)*SHADER_SIZE); + ccl_fetch(sd, object_flag) = 0; #ifdef __OBJECT_MOTION__ ccl_fetch(sd, time) = ray->time; #endif @@ -420,6 +426,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s sd->I = -ray->D; sd->shader = SHADER_NONE; sd->flag = 0; + sd->object_flag = 0; #ifdef __OBJECT_MOTION__ sd->time = ray->time; #endif @@ -1027,6 +1034,7 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg, sd->num_closure = 0; sd->num_closure_extra = 0; sd->flag = 0; + sd->object_flag = 0; for(int i = 0; stack[i].shader != SHADER_NONE; i++) { /* setup shaderdata from stack. it's mostly setup already in @@ -1034,11 +1042,12 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg, sd->object = stack[i].object; sd->shader = stack[i].shader; - sd->flag &= ~(SD_SHADER_FLAGS|SD_OBJECT_FLAGS); + sd->flag &= ~SD_SHADER_FLAGS; sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*SHADER_SIZE); + sd->object_flag &= ~SD_OBJECT_FLAGS; if(sd->object != OBJECT_NONE) { - sd->flag |= kernel_tex_fetch(__object_flag, sd->object); + sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object); #ifdef __OBJECT_MOTION__ /* todo: this is inefficient for motion blur, we should be diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index a826cda702b..b7af90cd739 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -692,56 +692,108 @@ typedef enum ShaderContext { /* Shader Data * * Main shader state at a point on the surface or in a volume. All coordinates - * are in world space. */ + * are in world space. + */ enum ShaderDataFlag { - /* runtime flags */ - SD_BACKFACING = (1 << 0), /* backside of surface? */ - SD_EMISSION = (1 << 1), /* have emissive closure? */ - SD_BSDF = (1 << 2), /* have bsdf closure? */ - SD_BSDF_HAS_EVAL = (1 << 3), /* have non-singular bsdf closure? */ - SD_BSSRDF = (1 << 4), /* have bssrdf */ - SD_HOLDOUT = (1 << 5), /* have holdout closure? */ - SD_ABSORPTION = (1 << 6), /* have volume absorption closure? */ - SD_SCATTER = (1 << 7), /* have volume phase closure? */ - SD_AO = (1 << 8), /* have ao closure? */ - SD_TRANSPARENT = (1 << 9), /* have transparent closure? */ + /* Runtime flags. */ + + /* Set when ray hits backside of surface. */ + SD_BACKFACING = (1 << 0), + /* Shader has emissive closure. */ + SD_EMISSION = (1 << 1), + /* Shader has BSDF closure. */ + SD_BSDF = (1 << 2), + /* Shader has non-singular BSDF closure. */ + SD_BSDF_HAS_EVAL = (1 << 3), + /* Shader has BSSRDF closure. */ + SD_BSSRDF = (1 << 4), + /* Shader has holdout closure. */ + SD_HOLDOUT = (1 << 5), + /* Shader has volume absorption closure. */ + SD_ABSORPTION = (1 << 6), + /* Shader has have volume phase (scatter) closure. */ + SD_SCATTER = (1 << 7), + /* Shader has AO closure. */ + SD_AO = (1 << 8), + /* Shader has transparent closure. */ + SD_TRANSPARENT = (1 << 9), + /* BSDF requires LCG for evaluation. */ SD_BSDF_NEEDS_LCG = (1 << 10), - SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF| - SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO| + SD_CLOSURE_FLAGS = (SD_EMISSION | + SD_BSDF | + SD_BSDF_HAS_EVAL | + SD_BSSRDF | + SD_HOLDOUT | + SD_ABSORPTION | + SD_SCATTER | + SD_AO | SD_BSDF_NEEDS_LCG), - /* shader flags */ - SD_USE_MIS = (1 << 12), /* direct light sample */ - SD_HAS_TRANSPARENT_SHADOW = (1 << 13), /* has transparent shadow */ - SD_HAS_VOLUME = (1 << 14), /* has volume shader */ - SD_HAS_ONLY_VOLUME = (1 << 15), /* has only volume shader, no surface */ - SD_HETEROGENEOUS_VOLUME = (1 << 16), /* has heterogeneous volume */ - SD_HAS_BSSRDF_BUMP = (1 << 17), /* bssrdf normal uses bump */ - SD_VOLUME_EQUIANGULAR = (1 << 18), /* use equiangular sampling */ - SD_VOLUME_MIS = (1 << 19), /* use multiple importance sampling */ - SD_VOLUME_CUBIC = (1 << 20), /* use cubic interpolation for voxels */ - SD_HAS_BUMP = (1 << 21), /* has data connected to the displacement input */ - SD_HAS_DISPLACEMENT = (1 << 22), /* has true displacement */ - SD_HAS_CONSTANT_EMISSION = (1 << 23), /* has constant emission (value stored in __shader_flag) */ + /* Shader flags. */ - SD_SHADER_FLAGS = (SD_USE_MIS|SD_HAS_TRANSPARENT_SHADOW|SD_HAS_VOLUME| - SD_HAS_ONLY_VOLUME|SD_HETEROGENEOUS_VOLUME| - SD_HAS_BSSRDF_BUMP|SD_VOLUME_EQUIANGULAR|SD_VOLUME_MIS| - SD_VOLUME_CUBIC|SD_HAS_BUMP|SD_HAS_DISPLACEMENT|SD_HAS_CONSTANT_EMISSION), + /* direct light sample */ + SD_USE_MIS = (1 << 16), + /* Has transparent shadow. */ + SD_HAS_TRANSPARENT_SHADOW = (1 << 17), + /* Has volume shader. */ + SD_HAS_VOLUME = (1 << 18), + /* Has only volume shader, no surface. */ + SD_HAS_ONLY_VOLUME = (1 << 19), + /* Has heterogeneous volume. */ + SD_HETEROGENEOUS_VOLUME = (1 << 20), + /* BSSRDF normal uses bump. */ + SD_HAS_BSSRDF_BUMP = (1 << 21), + /* Use equiangular volume sampling */ + SD_VOLUME_EQUIANGULAR = (1 << 22), + /* Use multiple importance volume sampling. */ + SD_VOLUME_MIS = (1 << 23), + /* Use cubic interpolation for voxels. */ + SD_VOLUME_CUBIC = (1 << 24), + /* Has data connected to the displacement input. */ + SD_HAS_BUMP = (1 << 25), + /* Has true displacement. */ + SD_HAS_DISPLACEMENT = (1 << 26), + /* Has constant emission (value stored in __shader_flag) */ + SD_HAS_CONSTANT_EMISSION = (1 << 27), - /* object flags */ - SD_OBJECT_HOLDOUT_MASK = (1 << 24), /* holdout for camera rays */ - SD_OBJECT_MOTION = (1 << 25), /* has object motion blur */ - SD_OBJECT_TRANSFORM_APPLIED = (1 << 26), /* vertices have transform applied */ - SD_OBJECT_NEGATIVE_SCALE_APPLIED = (1 << 27), /* vertices have negative scale applied */ - SD_OBJECT_HAS_VOLUME = (1 << 28), /* object has a volume shader */ - SD_OBJECT_INTERSECTS_VOLUME = (1 << 29), /* object intersects AABB of an object with volume shader */ - SD_OBJECT_HAS_VERTEX_MOTION = (1 << 30), /* has position for motion vertices */ + SD_SHADER_FLAGS = (SD_USE_MIS | + SD_HAS_TRANSPARENT_SHADOW | + SD_HAS_VOLUME | + SD_HAS_ONLY_VOLUME | + SD_HETEROGENEOUS_VOLUME| + SD_HAS_BSSRDF_BUMP | + SD_VOLUME_EQUIANGULAR | + SD_VOLUME_MIS | + SD_VOLUME_CUBIC | + SD_HAS_BUMP | + SD_HAS_DISPLACEMENT | + SD_HAS_CONSTANT_EMISSION) +}; - SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_OBJECT_TRANSFORM_APPLIED| - SD_OBJECT_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME| + /* Object flags. */ +enum ShaderDataObjectFlag { + /* Holdout for camera rays. */ + SD_OBJECT_HOLDOUT_MASK = (1 << 0), + /* Has object motion blur. */ + SD_OBJECT_MOTION = (1 << 1), + /* Vertices have transform applied. */ + SD_OBJECT_TRANSFORM_APPLIED = (1 << 2), + /* Vertices have negative scale applied. */ + SD_OBJECT_NEGATIVE_SCALE_APPLIED = (1 << 3), + /* Object has a volume shader. */ + SD_OBJECT_HAS_VOLUME = (1 << 4), + /* Object intersects AABB of an object with volume shader. */ + SD_OBJECT_INTERSECTS_VOLUME = (1 << 5), + /* Has position for motion vertices. */ + SD_OBJECT_HAS_VERTEX_MOTION = (1 << 6), + + SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK | + SD_OBJECT_MOTION | + SD_OBJECT_TRANSFORM_APPLIED | + SD_OBJECT_NEGATIVE_SCALE_APPLIED | + SD_OBJECT_HAS_VOLUME | SD_OBJECT_INTERSECTS_VOLUME) }; @@ -780,6 +832,8 @@ typedef ccl_addr_space struct ShaderData { ccl_soa_member(int, shader); /* booleans describing shader, see ShaderDataFlag */ ccl_soa_member(int, flag); + /* booleans describing object of the shader, see ShaderDataObjectFlag */ + ccl_soa_member(int, object_flag); /* primitive id if there is one, ~0 otherwise */ ccl_soa_member(int, prim); diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 2c8acb4e902..58bbdc33920 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -712,7 +712,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD else motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P); - if(!(sd->flag & SD_OBJECT_TRANSFORM_APPLIED)) { + if(!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { object_position_transform(kg, sd, &P[0]); object_position_transform(kg, sd, &P[1]); object_position_transform(kg, sd, &P[2]); diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h index fe5899de254..5d951b972ed 100644 --- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h +++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h @@ -137,22 +137,22 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao( /* holdout */ #ifdef __HOLDOUT__ - if((ccl_fetch(sd, flag) & (SD_HOLDOUT|SD_OBJECT_HOLDOUT_MASK)) && + if(((ccl_fetch(sd, flag) & SD_HOLDOUT) || + (ccl_fetch(sd, object_flag) & SD_OBJECT_HOLDOUT_MASK)) && (state->flag & PATH_RAY_CAMERA)) { if(kernel_data.background.transparent) { float3 holdout_weight; - - if(ccl_fetch(sd, flag) & SD_OBJECT_HOLDOUT_MASK) + if(ccl_fetch(sd, object_flag) & SD_OBJECT_HOLDOUT_MASK) { holdout_weight = make_float3(1.0f, 1.0f, 1.0f); - else + } + else { holdout_weight = shader_holdout_eval(kg, sd); - + } /* any throughput is ok, should all be identical here */ L_transparent_coop[ray_index] += average(holdout_weight*throughput); } - - if(ccl_fetch(sd, flag) & SD_OBJECT_HOLDOUT_MASK) { + if(ccl_fetch(sd, object_flag) & SD_OBJECT_HOLDOUT_MASK) { ASSIGN_RAY_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER); *enqueue_flag = 1; } diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h index 29af11c36b6..87e40791333 100644 --- a/intern/cycles/kernel/svm/svm_wireframe.h +++ b/intern/cycles/kernel/svm/svm_wireframe.h @@ -57,7 +57,7 @@ ccl_device_inline float wireframe(KernelGlobals *kg, else motion_triangle_vertices(kg, ccl_fetch(sd, object), ccl_fetch(sd, prim), ccl_fetch(sd, time), Co); - if(!(ccl_fetch(sd, flag) & SD_OBJECT_TRANSFORM_APPLIED)) { + if(!(ccl_fetch(sd, object_flag) & SD_OBJECT_TRANSFORM_APPLIED)) { object_position_transform(kg, sd, &Co[0]); object_position_transform(kg, sd, &Co[1]); object_position_transform(kg, sd, &Co[2]);