Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/bvh/bvh_util.h10
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h14
-rw-r--r--intern/cycles/kernel/kernel_bake.h6
-rw-r--r--intern/cycles/kernel/kernel_path.h18
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h11
-rw-r--r--intern/cycles/kernel/kernel_types.h5
-rw-r--r--intern/cycles/kernel/shaders/node_texture_coordinate.osl4
-rw-r--r--intern/cycles/kernel/split/kernel_scene_intersect.h5
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h48
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h8
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;