[Bf-blender-cvs] [a35db17] master: Cycles Volume Render: work on nodes and closures.

Brecht Van Lommel noreply at git.blender.org
Sat Dec 28 17:40:26 CET 2013


Commit: a35db17cee5a9b47dc9624f7dfcb41f5fc185b33
Author: Brecht Van Lommel
Date:   Sat Dec 28 01:54:44 2013 +0100
https://developer.blender.org/rBa35db17cee5a9b47dc9624f7dfcb41f5fc185b33

Cycles Volume Render: work on nodes and closures.

* Henyey-Greenstein scattering closure implementation.
* Rename transparent to absorption node and isotropic to scatter node.
* Volume density is folded into the closure weights.
* OSL support for volume closures and nodes.
* This commit has no user visible changes, there is no volume render code yet.

This is work by "storm", Stuart Broadfoot, Thomas Dinges and myself.

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

M	intern/cycles/app/cycles_xml.cpp
M	intern/cycles/blender/blender_shader.cpp
M	intern/cycles/kernel/closure/volume.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/osl/osl_closures.cpp
M	intern/cycles/kernel/osl/osl_closures.h
M	intern/cycles/kernel/osl/osl_shader.cpp
M	intern/cycles/kernel/shaders/CMakeLists.txt
A	intern/cycles/kernel/shaders/node_absorption_volume.osl
M	intern/cycles/kernel/shaders/node_light_path.osl
A	intern/cycles/kernel/shaders/node_scatter_volume.osl
M	intern/cycles/kernel/shaders/stdosl.h
M	intern/cycles/kernel/svm/svm_closure.h
M	intern/cycles/kernel/svm/svm_light_path.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	intern/cycles/render/osl.cpp
M	release/scripts/addons
M	release/scripts/addons_contrib
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_shader.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/shader/nodes/node_shader_volume_absorption.c
D	source/blender/nodes/shader/nodes/node_shader_volume_isotropic.c
A	source/blender/nodes/shader/nodes/node_shader_volume_scatter.c
D	source/blender/nodes/shader/nodes/node_shader_volume_transparent.c

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

diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index df187f0..a483c76 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -452,11 +452,11 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
 		else if(string_iequals(node.name(), "background")) {
 			snode = new BackgroundNode();
 		}
-		else if(string_iequals(node.name(), "transparent_volume")) {
-			snode = new TransparentVolumeNode();
+		else if(string_iequals(node.name(), "absorption_volume")) {
+			snode = new AbsorptionVolumeNode();
 		}
-		else if(string_iequals(node.name(), "isotropic_volume")) {
-			snode = new IsotropicVolumeNode();
+		else if(string_iequals(node.name(), "scatter_volume")) {
+			snode = new ScatterVolumeNode();
 		}
 		else if(string_iequals(node.name(), "geometry")) {
 			snode = new GeometryNode();
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index a6d2b53..0c3a32a 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -422,11 +422,11 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
 	else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
 		node = new AmbientOcclusionNode();
 	}
-	else if (b_node.is_a(&RNA_ShaderNodeVolumeIsotropic)) {
-		node = new IsotropicVolumeNode();
+	else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
+		node = new ScatterVolumeNode();
 	}
-	else if (b_node.is_a(&RNA_ShaderNodeVolumeTransparent)) {
-		node = new TransparentVolumeNode();
+	else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
+		node = new AbsorptionVolumeNode();
 	}
 	else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
 		node = new GeometryNode();
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index f493256..dae24fb 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -14,53 +14,102 @@
  * limitations under the License
  */
 
+#ifndef __VOLUME_H__
+#define __VOLUME_H__
+
 CCL_NAMESPACE_BEGIN
 
-/* note: the interfaces here are just as an example, need to figure
- * out the right functions and parameters to use */
+/* HENYEY-GREENSTEIN CLOSURE */
 
-/* ISOTROPIC VOLUME CLOSURE */
+/* Given cosine between rays, return probability density that a photon bounces
+ * to that direction. The g parameter controls how different it is from the
+ * uniform sphere. g=0 uniform diffuse-like, g=1 close to sharp single ray. */
+ccl_device float single_peaked_henyey_greenstein(float cos_theta, float g)
+{
+	if(fabsf(g) < 1e-3f)
+		return M_1_PI_F * 0.25f;
+	
+	return ((1.0f - g * g) / safe_powf(1.0f + g * g - 2.0f * g * cos_theta, 1.5f)) * (M_1_PI_F * 0.25f);
+};
 
-ccl_device int volume_isotropic_setup(ShaderClosure *sc, float density)
+ccl_device int volume_henyey_greenstein_setup(ShaderClosure *sc)
 {
-	sc->type = CLOSURE_VOLUME_ISOTROPIC_ID;
-	sc->data0 = density;
+	sc->type = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
+	
+	/* clamp anisotropy to avoid delta function */
+	sc->data0 = signf(sc->data0) * min(fabsf(sc->data0), 1.0f - 1e-3f);
 
-	return SD_VOLUME;
+	return SD_BSDF|SD_BSDF_HAS_EVAL;
 }
 
-ccl_device float3 volume_isotropic_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
 {
-	return make_float3(1.0f, 1.0f, 1.0f);
-}
+	float g = sc->data0;
 
-/* TRANSPARENT VOLUME CLOSURE */
+	/* note that I points towards the viewer */
+	float cos_theta = dot(-I, omega_in);
 
-ccl_device int volume_transparent_setup(ShaderClosure *sc, float density)
+	*pdf = single_peaked_henyey_greenstein(cos_theta, g);
+
+	return make_float3(*pdf, *pdf, *pdf);
+}
+
+ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
+	float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
 {
-	sc->type = CLOSURE_VOLUME_TRANSPARENT_ID;
-	sc->data0 = density;
+	float g = sc->data0;
+	float cos_phi, sin_phi, cos_theta;
 
-	return SD_VOLUME;
+	/* match pdf for small g */
+	if(fabsf(g) < 1e-3f) {
+		cos_theta = (1.0f - 2.0f * randu);
+	}
+	else {
+		float k = (1.0f - g * g) / (1.0f - g + 2.0f * g * randu);
+		cos_theta = (1.0f + g * g - k * k) / (2.0f * g);
+	}
+
+	float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
+
+	float phi = M_2PI_F * randv;
+	cos_phi = cosf(phi);
+	sin_phi = sinf(phi);
+
+	/* note that I points towards the viewer and so is used negated */
+	float3 T, B;
+	make_orthonormals(-I, &T, &B);
+	*omega_in = sin_theta * cos_phi * T + sin_theta * sin_phi * B + cos_theta * (-I);
+
+	*pdf = single_peaked_henyey_greenstein(cos_theta, g);
+	*eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */
+
+#ifdef __RAY_DIFFERENTIALS__
+	/* todo: implement ray differential estimation */
+	*domega_in_dx = make_float3(0.0f, 0.0f, 0.0f);
+	*domega_in_dy = make_float3(0.0f, 0.0f, 0.0f);
+#endif
+
+	return LABEL_VOLUME_SCATTER;
 }
 
-ccl_device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+/* ABSORPTION VOLUME CLOSURE */
+
+ccl_device int volume_absorption_setup(ShaderClosure *sc)
 {
-	return make_float3(1.0f, 1.0f, 1.0f);
+	sc->type = CLOSURE_VOLUME_ABSORPTION_ID;
+
+	return SD_VOLUME;
 }
 
 /* VOLUME CLOSURE */
 
-ccl_device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+ccl_device float3 volume_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
 {
 	float3 eval;
 
 	switch(sc->type) {
-		case CLOSURE_VOLUME_ISOTROPIC_ID:
-			eval = volume_isotropic_eval_phase(sc, omega_in, omega_out);
-			break;
-		case CLOSURE_VOLUME_TRANSPARENT_ID:
-			eval = volume_transparent_eval_phase(sc, omega_in, omega_out);
+		case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+			eval = volume_henyey_greenstein_eval_phase(sc, I, omega_in, pdf);
 			break;
 		default:
 			eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -70,5 +119,24 @@ ccl_device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc,
 	return eval;
 }
 
+ccl_device int volume_sample(const ShaderData *sd, const ShaderClosure *sc, float randu,
+	float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
+{
+	int label;
+
+	switch(sc->type) {
+		case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
+			label = volume_henyey_greenstein_sample(sc, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+			break;
+		default:
+			*eval = make_float3(0.0f, 0.0f, 0.0f);
+			label = LABEL_NONE;
+			break;
+	}
+
+	return label;
+}
+
 CCL_NAMESPACE_END
 
+#endif
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 457a7f7..012aa4a 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -868,17 +868,19 @@ ccl_device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
 {
 #ifdef __MULTI_CLOSURE__
 	float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+	float pdf;
 
 	for(int i = 0; i< sd->num_closure; i++) {
 		const ShaderClosure *sc = &sd->closure[i];
 
 		if(CLOSURE_IS_VOLUME(sc->type))
-			eval += volume_eval_phase(kg, sc, omega_in, omega_out);
+			eval += volume_eval_phase(sc, omega_in, omega_out, &pdf);
 	}
 
 	return eval;
 #else
-	return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
+	float pdf;
+	return volume_eval_phase(&sd->closure, omega_in, omega_out, &pdf);
 #endif
 }
 
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 9b1893e..4821a1b 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -201,6 +201,7 @@ enum PathRayFlag {
 	PATH_RAY_GLOSSY = 16,
 	PATH_RAY_SINGULAR = 32,
 	PATH_RAY_TRANSPARENT = 64,
+	PATH_RAY_VOLUME_SCATTER = 128,
 
 	PATH_RAY_SHADOW_OPAQUE = 128,
 	PATH_RAY_SHADOW_TRANSPARENT = 256,
@@ -224,18 +225,13 @@ enum PathRayFlag {
 
 typedef enum ClosureLabel {
 	LABEL_NONE = 0,
-	LABEL_CAMERA = 1,
-	LABEL_LIGHT = 2,
-	LABEL_BACKGROUND = 4,
-	LABEL_TRANSMIT = 8,
-	LABEL_REFLECT = 16,
-	LABEL_VOLUME = 32,
-	LABEL_OBJECT = 64,
-	LABEL_DIFFUSE = 128,
-	LABEL_GLOSSY = 256,
-	LABEL_SINGULAR = 512,
-	LABEL_TRANSPARENT = 1024,
-	LABEL_STOP = 2048
+	LABEL_TRANSMIT = 1,
+	LABEL_REFLECT = 2,
+	LABEL_DIFFUSE = 4,
+	LABEL_GLOSSY = 8,
+	LABEL_SINGULAR = 16,
+	LABEL_TRANSPARENT = 32,
+	LABEL_VOLUME_SCATTER = 64,
 } ClosureLabel;
 
 /* Render Passes */
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 340e449..a96c0e2 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -55,6 +55,7 @@
 #include "closure/bsdf_westin.h"
 #include "closure/bsdf_toon.h"
 #include "closure/bsdf_hair.h"
+#include "closure/volume.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -169,6 +170,13 @@ BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, hair_transmission,
 #endif
 BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
 
+VOLUME_CLOSURE_CLASS_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein, LABEL_VOLUME_SCATTER)
+	CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, sc.data0),
+VOLUME_CLOSURE_CLASS_END(VolumeHenyeyGreenstein, henyey_greenstein)
+
+VOLUME_CLOSURE_CLASS_BEGIN(VolumeAbsorption, absorption, LABEL_SINGULAR)
+VOLUME_CLOSURE_CLASS_END(VolumeAbsorption, absorption)
+
 /* Registration */
 
 static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, OSL::ClosureParam *params, OSL::PrepareClosureFunc prepare)
@@ -248,6 +256,11 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
 		bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
 	register_closure(ss, "hair_transmission", id++,
 		bsdf_hair_transmission_params(), bsdf_hair_transmission_prepare);
+
+	register_closure(ss, "henyey_greenstein", id++,
+		volume_henyey_greenstein_params(), volume_henyey_greenstein_prepare);
+	register_closure(ss, "absorption", id++,
+		volume_absorption_params(), volume_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list