diff options
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_util.h | 10 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle.h | 14 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_bake.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 18 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path_branched.h | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_texture_coordinate.osl | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/split/kernel_scene_intersect.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_attribute.h | 48 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 8 |
10 files changed, 110 insertions, 19 deletions
diff --git a/intern/cycles/kernel/bvh/bvh_util.h b/intern/cycles/kernel/bvh/bvh_util.h index 867ea3af8d1..b1faebce957 100644 --- a/intern/cycles/kernel/bvh/bvh_util.h +++ b/intern/cycles/kernel/bvh/bvh_util.h @@ -239,4 +239,14 @@ ccl_device_forceinline int intersection_get_shader(KernelGlobals *ccl_restrict k return shader & SHADER_MASK; } +ccl_device_forceinline int intersection_get_object(KernelGlobals *ccl_restrict kg, + const Intersection *ccl_restrict isect) +{ + if (isect->object != OBJECT_NONE) { + return isect->object; + } + + return kernel_tex_fetch(__prim_object, isect->prim); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 980caf92cd0..77ce0227ec8 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -107,6 +107,20 @@ triangle_smooth_normal(KernelGlobals *kg, float3 Ng, int prim, float u, float v) return is_zero(N) ? Ng : N; } +ccl_device_inline float3 +triangle_smooth_normal_unnormalized(KernelGlobals *kg, float3 Ng, int prim, float u, float v) +{ + /* load triangle vertices */ + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); + float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x)); + float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); + float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); + + float3 N = (1.0f - u - v) * n2 + u * n0 + v * n1; + + return is_zero(N) ? Ng : N; +} + /* Ray differentials on triangle */ ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index 7cea331510e..807e5c050f8 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -81,7 +81,8 @@ ccl_device_noinline void compute_light_pass( kg, sd, emission_sd, L, &state, &ray, &throughput, &ss_indirect)) { while (ss_indirect.num_rays) { kernel_path_subsurface_setup_indirect(kg, &ss_indirect, &state, &ray, L, &throughput); - kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L); + kernel_path_indirect( + kg, &indirect_sd, emission_sd, &ray, throughput, &state, L, sd->object); } is_sss_sample = true; } @@ -97,7 +98,8 @@ ccl_device_noinline void compute_light_pass( state.ray_t = 0.0f; # endif /* compute indirect light */ - kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L); + kernel_path_indirect( + kg, &indirect_sd, emission_sd, &ray, throughput, &state, L, sd->object); /* sum and reset indirect light pass variables for the next samples */ path_radiance_sum_indirect(L); diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index a050847cb68..690f5cd86ef 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -58,7 +58,8 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg, ccl_addr_space PathState *state, Ray *ray, Intersection *isect, - PathRadiance *L) + PathRadiance *L, + const int last_object) { PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT); @@ -66,6 +67,12 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg, if (path_state_ao_bounce(kg, state)) { ray->t = kernel_data.background.ao_distance; + if (last_object != OBJECT_NONE) { + const float object_ao_distance = kernel_tex_fetch(__objects, last_object).ao_distance; + if (object_ao_distance != 0.0f) { + ray->t = object_ao_distance; + } + } } bool hit = scene_intersect(kg, ray, visibility, isect); @@ -253,7 +260,7 @@ ccl_device_forceinline bool kernel_path_shader_apply(KernelGlobals *kg, PROFILING_INIT(kg, PROFILING_SHADER_APPLY); #ifdef __SHADOW_TRICKS__ - if ((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) { + if (sd->object_flag & SD_OBJECT_SHADOW_CATCHER) { if (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) { state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_STORE_SHADOW_INFO); @@ -375,7 +382,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, Ray *ray, float3 throughput, PathState *state, - PathRadiance *L) + PathRadiance *L, + const int last_object) { # ifdef __SUBSURFACE__ SubsurfaceIndirectRays ss_indirect; @@ -388,7 +396,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, for (;;) { /* Find intersection with objects in scene. */ Intersection isect; - bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L); + bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L, last_object); /* Find intersection with lamps and compute emission for MIS. */ kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L); @@ -532,7 +540,7 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg, for (;;) { /* Find intersection with objects in scene. */ Intersection isect; - bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L); + bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L, sd.object); /* Find intersection with lamps and compute emission for MIS. */ kernel_path_lamp_emission(kg, state, ray, throughput, &isect, &sd, L); diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 97ed21a9b75..ec02e3db901 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -98,6 +98,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg, volume_ray.t = (hit) ? isect->t : FLT_MAX; float step_size = volume_stack_step_size(kg, state->volume_stack); + const int object = sd->object; # ifdef __VOLUME_DECOUPLED__ /* decoupled ray marching only supported on CPU */ @@ -140,7 +141,8 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg, if (result == VOLUME_PATH_SCATTERED && kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) { - kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp * num_samples_inv, &ps, L); + kernel_path_indirect( + kg, indirect_sd, emission_sd, &pray, tp * num_samples_inv, &ps, L, object); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -186,7 +188,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg, kernel_path_volume_connect_light(kg, sd, emission_sd, tp, state, L); if (kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) { - kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, L); + kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, L, object); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -272,7 +274,8 @@ ccl_device_noinline_cpu void kernel_branched_path_surface_indirect_light(KernelG ps.rng_hash = state->rng_hash; - kernel_path_indirect(kg, indirect_sd, emission_sd, &bsdf_ray, tp * num_samples_inv, &ps, L); + kernel_path_indirect( + kg, indirect_sd, emission_sd, &bsdf_ray, tp * num_samples_inv, &ps, L, sd->object); /* for render passes, sum and reset indirect light pass variables * for the next samples */ @@ -401,7 +404,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, for (;;) { /* Find intersection with objects in scene. */ Intersection isect; - bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L); + bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L, sd.object); # ifdef __VOLUME__ /* Volume integration. */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 5a79790ca6b..1519b2ace9d 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1454,7 +1454,10 @@ typedef struct KernelObject { float shadow_terminator_shading_offset; float shadow_terminator_geometry_offset; - float pad1, pad2, pad3; + + float ao_distance; + + float pad1, pad2; } KernelObject; static_assert_align(KernelObject, 16); diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl index ac05e984af2..9cdb925dbfa 100644 --- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl +++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl @@ -58,7 +58,9 @@ shader node_texture_coordinate( getattribute("geom:uv", UV); } else { - getattribute("geom:generated", Generated); + if (!getattribute("geom:generated", Generated)) { + Generated = transform("object", P); + } getattribute("geom:uv", UV); } diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h index 5fef3e045f8..9ac95aafd2f 100644 --- a/intern/cycles/kernel/split/kernel_scene_intersect.h +++ b/intern/cycles/kernel/split/kernel_scene_intersect.h @@ -65,7 +65,10 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg) PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; Intersection isect; - bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L); + const int last_object = state->bounce > 0 ? + intersection_get_object(kg, &kernel_split_state.isect[ray_index]) : + OBJECT_NONE; + bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L, last_object); kernel_split_state.isect[ray_index] = isect; if (!hit) { diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index f598bfb8f8f..62740824ad1 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -72,6 +72,22 @@ ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, u } #endif + if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) { + /* No generated attribute, fall back to object coordinates. */ + float3 f = sd->P; + object_inverse_position_transform(kg, sd, &f); + if (type == NODE_ATTR_OUTPUT_FLOAT) { + stack_store_float(stack, out_offset, average(f)); + } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { + stack_store_float3(stack, out_offset, f); + } + else { + stack_store_float(stack, out_offset, 1.0f); + } + return; + } + /* Surface. */ if (desc.type == NODE_ATTR_FLOAT) { float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL); @@ -145,6 +161,22 @@ ccl_device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float * } #endif + if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) { + /* No generated attribute, fall back to object coordinates. */ + float3 f = sd->P + sd->dP.dx; + object_inverse_position_transform(kg, sd, &f); + if (type == NODE_ATTR_OUTPUT_FLOAT) { + stack_store_float(stack, out_offset, average(f)); + } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { + stack_store_float3(stack, out_offset, f); + } + else { + stack_store_float(stack, out_offset, 1.0f); + } + return; + } + /* Surface */ if (desc.type == NODE_ATTR_FLOAT) { float dx; @@ -222,6 +254,22 @@ ccl_device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float * } #endif + if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) { + /* No generated attribute, fall back to object coordinates. */ + float3 f = sd->P + sd->dP.dy; + object_inverse_position_transform(kg, sd, &f); + if (type == NODE_ATTR_OUTPUT_FLOAT) { + stack_store_float(stack, out_offset, average(f)); + } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { + stack_store_float3(stack, out_offset, f); + } + else { + stack_store_float(stack, out_offset, 1.0f); + } + return; + } + /* Surface */ if (desc.type == NODE_ATTR_FLOAT) { float dy; diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 98b3c4ecb7c..f14f358fed8 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -273,7 +273,7 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st if (space == NODE_NORMAL_MAP_TANGENT) { /* tangent space */ - if (sd->object == OBJECT_NONE) { + if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_ALL_TRIANGLE) == 0) { /* Fallback to unperturbed normal. */ stack_store_float3(stack, normal_offset, sd->N); return; @@ -282,10 +282,8 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st /* first try to get tangent attribute */ const AttributeDescriptor attr = find_attribute(kg, sd, node.z); const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); - const AttributeDescriptor attr_normal = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL); - if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND || - attr_normal.offset == ATTR_STD_NOT_FOUND) { + if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND) { /* Fallback to unperturbed normal. */ stack_store_float3(stack, normal_offset, sd->N); return; @@ -297,7 +295,7 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st float3 normal; if (sd->shader & SHADER_SMOOTH_NORMAL) { - normal = primitive_surface_attribute_float3(kg, sd, attr_normal, NULL, NULL); + normal = triangle_smooth_normal_unnormalized(kg, sd->Ng, sd->prim, sd->u, sd->v); } else { normal = sd->Ng; |