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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2021-08-18 00:24:46 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2021-08-18 22:12:39 +0300
commitb8ecdbcd964a7e78d7e077ef84a914b1374ae076 (patch)
tree589d69109b3f70d219ef14a040bc717381266c85
parente5f8db92b696a36e919eb6ac3125190d9e2202d9 (diff)
Cycles: avoid copying vertex normals attribute twice to the devices
Vertex normals are needed for normals maps and therefore are packed and send to the device alongside the other float3 attributes. However, we already pack and send vertex normals through `DeviceScene.tri_vnormal`. This removes the packing of vertex normals from the attributes buffer, and reuses `tri_vnormal` in the kernel for normals lookup for normal maps, which reduces memory usage a bit, and speeds up device updates. This also fixes potential missing normals updates following rB12a06292af86, since the need for vertex normals for normals maps was overlooked. Reviewed By: brecht Differential Revision: https://developer.blender.org/D12237
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h14
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h8
-rw-r--r--intern/cycles/render/geometry.cpp15
3 files changed, 32 insertions, 5 deletions
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 208338a934b..1e7fbd9c7fb 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/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index fc46bb584be..09ea11ee3ed 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -267,7 +267,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->prim & PRIMITIVE_ALL_TRIANGLE) == 0) {
/* Fallback to unperturbed normal. */
stack_store_float3(stack, normal_offset, sd->N);
return;
@@ -276,10 +276,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;
@@ -291,7 +289,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;
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 6d084e82576..a8e4db38180 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -788,6 +788,11 @@ void GeometryManager::device_update_attributes(Device *device,
foreach (AttributeRequest &req, attributes.requests) {
Attribute *attr = geom->attributes.find(req);
+ /* Vertex normals are stored in DeviceScene.tri_vnormal. */
+ if (attr && attr->std == ATTR_STD_VERTEX_NORMAL) {
+ continue;
+ }
+
update_attribute_element_size(geom,
attr,
ATTR_PRIM_GEOMETRY,
@@ -854,6 +859,11 @@ void GeometryManager::device_update_attributes(Device *device,
Attribute *attr = geom->attributes.find(req);
if (attr) {
+ /* Vertex normals are stored in DeviceScene.tri_vnormal. */
+ if (attr->std == ATTR_STD_VERTEX_NORMAL) {
+ continue;
+ }
+
/* force a copy if we need to reallocate all the data */
attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
}
@@ -877,6 +887,11 @@ void GeometryManager::device_update_attributes(Device *device,
Attribute *subd_attr = mesh->subd_attributes.find(req);
if (subd_attr) {
+ /* Vertex normals are stored in DeviceScene.tri_vnormal. */
+ if (subd_attr->std == ATTR_STD_VERTEX_NORMAL) {
+ continue;
+ }
+
/* force a copy if we need to reallocate all the data */
subd_attr->modified |= attributes_need_realloc[Attribute::kernel_type(*subd_attr)];
}