[Bf-blender-cvs] [e7ea1ae] master: Cycles microdisplacement: Improved automatic bump mapping

Mai Lavelle noreply at git.blender.org
Fri Sep 2 05:12:58 CEST 2016


Commit: e7ea1ae78c84904864c17248b1b22b1e6c11acc9
Author: Mai Lavelle
Date:   Sun Aug 14 11:44:25 2016 -0400
Branches: master
https://developer.blender.org/rBe7ea1ae78c84904864c17248b1b22b1e6c11acc9

Cycles microdisplacement: Improved automatic bump mapping

Object coordinates can now be used in the displacement shader and will give
correct results, where as before bump mapping was calculated from the displace
positions and resulted in incorrect shading.

This works by evaluating the shader in two parts, first bump then surface, and
setting the shader state to match what it would be if the surface was
undisplaced for the bump shader evaluation. Currently only `P` is set as if
undisplaced, but other shader variables could be set as well, such as `I` or
`time`. Since these aren't set to anything meaningful for displacement I left
them out of this patch, we can decide what to do with them separately.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2156

===================================================================

M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/osl/osl_globals.h
M	intern/cycles/kernel/osl/osl_services.cpp
M	intern/cycles/kernel/osl/osl_services.h
M	intern/cycles/kernel/osl/osl_shader.cpp
M	intern/cycles/kernel/svm/svm.h
A	intern/cycles/kernel/svm/svm_bump.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/osl.cpp
M	intern/cycles/render/shader.cpp
M	intern/cycles/render/svm.cpp
M	intern/cycles/render/svm.h

===================================================================

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 9317bfb..3c37bc0 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -113,6 +113,7 @@ set(SRC_SVM_HEADERS
 	svm/svm.h
 	svm/svm_attribute.h
 	svm/svm_blackbody.h
+	svm/svm_bump.h
 	svm/svm_camera.h
 	svm/svm_closure.h
 	svm/svm_convert.h
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index deebf87..0646148 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -714,20 +714,21 @@ enum ShaderDataFlag {
 	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_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_VOLUME_CUBIC|SD_HAS_BUMP|SD_HAS_DISPLACEMENT),
 
 	/* object flags */
-	SD_HOLDOUT_MASK             = (1 << 22),  /* holdout for camera rays */
-	SD_OBJECT_MOTION            = (1 << 23),  /* has object motion blur */
-	SD_TRANSFORM_APPLIED        = (1 << 24),  /* vertices have transform applied */
-	SD_NEGATIVE_SCALE_APPLIED   = (1 << 25),  /* vertices have negative scale applied */
-	SD_OBJECT_HAS_VOLUME        = (1 << 26),  /* object has a volume shader */
-	SD_OBJECT_INTERSECTS_VOLUME = (1 << 27),  /* object intersects AABB of an object with volume shader */
-	SD_OBJECT_HAS_VERTEX_MOTION = (1 << 28),  /* has position for motion vertices */
+	SD_HOLDOUT_MASK             = (1 << 23),  /* holdout for camera rays */
+	SD_OBJECT_MOTION            = (1 << 24),  /* has object motion blur */
+	SD_TRANSFORM_APPLIED        = (1 << 25),  /* vertices have transform applied */
+	SD_NEGATIVE_SCALE_APPLIED   = (1 << 26),  /* vertices have negative scale applied */
+	SD_OBJECT_HAS_VOLUME        = (1 << 27),  /* object has a volume shader */
+	SD_OBJECT_INTERSECTS_VOLUME = (1 << 28),  /* object intersects AABB of an object with volume shader */
+	SD_OBJECT_HAS_VERTEX_MOTION = (1 << 29),  /* has position for motion vertices */
 
 	SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED|
 	                   SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME|
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 8353c4e..65cb7ec 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -54,6 +54,7 @@ struct OSLGlobals {
 	vector<OSL::ShaderGroupRef> surface_state;
 	vector<OSL::ShaderGroupRef> volume_state;
 	vector<OSL::ShaderGroupRef> displacement_state;
+	vector<OSL::ShaderGroupRef> bump_state;
 	OSL::ShaderGroupRef background_state;
 
 	/* attributes */
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 422af32..f61a9ec 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -93,6 +93,7 @@ ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
 ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
 ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
 ustring OSLRenderServices::u_geom_name("geom:name");
+ustring OSLRenderServices::u_geom_undisplaced("geom:undisplaced");
 ustring OSLRenderServices::u_is_smooth("geom:is_smooth");
 #ifdef __HAIR__
 ustring OSLRenderServices::u_is_curve("geom:is_curve");
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 2701abb..0f2e02c 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -158,6 +158,7 @@ public:
 	static ustring u_geom_trianglevertices;
 	static ustring u_geom_polyvertices;
 	static ustring u_geom_name;
+	static ustring u_geom_undisplaced;
 	static ustring u_is_smooth;
 	static ustring u_is_curve;
 	static ustring u_curve_thickness;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 20dd167..681ea3c 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -184,6 +184,47 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state
 	OSL::ShadingContext *octx = tdata->context[(int)ctx];
 	int shader = sd->shader & SHADER_MASK;
 
+	/* automatic bump shader */
+	if(kg->osl->bump_state[shader]) {
+		/* save state */
+		float3 P = sd->P;
+		float3 dPdx = sd->dP.dx;
+		float3 dPdy = sd->dP.dy;
+
+		/* set state as if undisplaced */
+		if(sd->flag & SD_HAS_DISPLACEMENT) {
+			float data[9];
+			bool found = kg->osl->services->get_attribute(sd, true, OSLRenderServices::u_empty, TypeDesc::TypeVector,
+			                                              OSLRenderServices::u_geom_undisplaced, data);
+			assert(found);
+
+			memcpy(&sd->P, data, sizeof(float)*3);
+			memcpy(&sd->dP.dx, data+3, sizeof(float)*3);
+			memcpy(&sd->dP.dy, data+6, sizeof(float)*3);
+
+			object_position_transform(kg, sd, &sd->P);
+			object_dir_transform(kg, sd, &sd->dP.dx);
+			object_dir_transform(kg, sd, &sd->dP.dy);
+
+			globals->P = TO_VEC3(sd->P);
+			globals->dPdx = TO_VEC3(sd->dP.dx);
+			globals->dPdy = TO_VEC3(sd->dP.dy);
+		}
+
+		/* execute bump shader */
+		ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
+
+		/* reset state */
+		sd->P = P;
+		sd->dP.dx = dPdx;
+		sd->dP.dy = dPdy;
+
+		globals->P = TO_VEC3(P);
+		globals->dPdx = TO_VEC3(dPdx);
+		globals->dPdy = TO_VEC3(dPdy);
+	}
+
+	/* surface shader */
 	if(kg->osl->surface_state[shader]) {
 		ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
 	}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 502994e..998a32e 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -181,6 +181,7 @@ CCL_NAMESPACE_END
 #include "svm_brick.h"
 #include "svm_vector_transform.h"
 #include "svm_voxel.h"
+#include "svm_bump.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -294,6 +295,12 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
 			case NODE_CLOSURE_SET_NORMAL:
 				svm_node_set_normal(kg, sd, stack, node.y, node.z);
 				break;
+			case NODE_ENTER_BUMP_EVAL:
+				svm_node_enter_bump_eval(kg, sd, stack, node.y);
+				break;
+			case NODE_LEAVE_BUMP_EVAL:
+				svm_node_leave_bump_eval(kg, sd, stack, node.y);
+				break;
 #    endif  /* NODES_FEATURE(NODE_FEATURE_BUMP) */
 			case NODE_HSV:
 				svm_node_hsv(kg, sd, stack, node, &offset);
diff --git a/intern/cycles/kernel/svm/svm_bump.h b/intern/cycles/kernel/svm/svm_bump.h
new file mode 100644
index 0000000..04a8c7b
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_bump.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011-2016 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Bump Eval Nodes */
+
+ccl_device void svm_node_enter_bump_eval(KernelGlobals *kg, ShaderData *sd, float *stack, uint offset)
+{
+	/* save state */
+	stack_store_float3(stack, offset+0, ccl_fetch(sd, P));
+	stack_store_float3(stack, offset+3, ccl_fetch(sd, dP).dx);
+	stack_store_float3(stack, offset+6, ccl_fetch(sd, dP).dy);
+
+	/* set state as if undisplaced */
+	const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED);
+
+	if(desc.offset != ATTR_STD_NOT_FOUND) {
+		float3 P, dPdx, dPdy;
+		P = primitive_attribute_float3(kg, sd, desc, &dPdx, &dPdy);
+
+		object_position_transform(kg, sd, &P);
+		object_dir_transform(kg, sd, &dPdx);
+		object_dir_transform(kg, sd, &dPdy);
+
+		ccl_fetch(sd, P) = P;
+		ccl_fetch(sd, dP).dx = dPdx;
+		ccl_fetch(sd, dP).dy = dPdy;
+	}
+}
+
+ccl_device void svm_node_leave_bump_eval(KernelGlobals *kg, ShaderData *sd, float *stack, uint offset)
+{
+	/* restore state */
+	ccl_fetch(sd, P) = stack_load_float3(stack, offset+0);
+	ccl_fetch(sd, dP).dx = stack_load_float3(stack, offset+3);
+	ccl_fetch(sd, dP).dy = stack_load_float3(stack, offset+6);
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 51083c3..9cfa839 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -26,6 +26,8 @@ CCL_NAMESPACE_BEGIN
 /* SVM stack offsets with this value indicate that it's not on the stack */
 #define SVM_STACK_INVALID 255 
 
+#define SVM_BUMP_EVAL_STATE_SIZE 9
+
 /* Nodes */
 
 /* Known frequencies of used nodes, used for selective nodes compilation
@@ -127,6 +129,8 @@ typedef enum ShaderNodeType {
 	NODE_HAIR_INFO,
 	NODE_UVMAP,
 	NODE_TEX_VOXEL,
+	NODE_ENTER_BUMP_EVAL,
+	NODE_LEAVE_BUMP_EVAL,
 } ShaderNodeType;
 
 typedef enum NodeAttributeType {
@@ -374,7 +378,8 @@ typedef enum NodeTexVoxelSpace {
 typedef enum ShaderType {
 	SHADER_TYPE_SURFACE,
 	SHADER_TYPE_VOLUME,
-	SHADER_TYPE_DISPLACEMENT
+	SHADER_TYPE_DISPLACEMENT,
+	SHADER_TYPE_BUMP,
 } ShaderType;
 
 /* Closure */
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 6e795ef..57256ce 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -856,27 +856,8 @@ void ShaderGraph::bump_from_displacement()
 	/* connect the bump out to the set normal in: */
 	connect(bump->output("Normal"), set_normal->input("Direction"));
 
-	/* connect bump output to normal input nodes that aren't 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list