For the record, Lukas Tönne contributed to OSL Volume support as well. :) Am 28.12.2013 17:40, schrieb Brecht Van Lommel: > 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_ >
_______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
