[Bf-blender-cvs] [1583c087287] cycles-x: Cycles X: restore homogeneous volume absorption

Brecht Van Lommel noreply at git.blender.org
Fri Jun 11 19:19:29 CEST 2021


Commit: 1583c087287ef4a0f6ff05aae49be6ceb9c66dfc
Author: Brecht Van Lommel
Date:   Fri Jun 11 16:59:22 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB1583c087287ef4a0f6ff05aae49be6ceb9c66dfc

Cycles X: restore homogeneous volume absorption

This is a first step towards bringing back volume scattering. Almost nothing
works yet, no scattering, heterogeneous media, cameras inside volumes, etc.

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

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

M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/integrator/integrator_intersect_closest.h
M	intern/cycles/kernel/integrator/integrator_megakernel.h
M	intern/cycles/kernel/integrator/integrator_shade_shadow.h
M	intern/cycles/kernel/integrator/integrator_shade_surface.h
M	intern/cycles/kernel/integrator/integrator_shade_volume.h
M	intern/cycles/kernel/integrator/integrator_state.h
M	intern/cycles/kernel/integrator/integrator_state_template.h
M	intern/cycles/kernel/integrator/integrator_state_util.h
A	intern/cycles/kernel/integrator/integrator_volume_stack.h
M	intern/cycles/kernel/kernel_path_state.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/kernel_volume.h

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

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 70ad17d9ee6..33829ac3d4d 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -247,6 +247,7 @@ set(SRC_INTEGRATOR_HEADERS
   integrator/integrator_state_template.h
   integrator/integrator_state_util.h
   integrator/integrator_subsurface.h
+  integrator/integrator_volume_stack.h
 )
 
 set(SRC_UTIL_HEADERS
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_closest.h b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
index 4a6cc2478be..b0fc87f5c8d 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_closest.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
@@ -28,6 +28,7 @@
 
 CCL_NAMESPACE_BEGIN
 
+template<uint32_t current_kernel>
 ccl_device_forceinline bool integrator_intersect_shader_next_kernel(
     INTEGRATOR_STATE_ARGS, const Intersection *ccl_restrict isect)
 {
@@ -71,16 +72,17 @@ ccl_device_forceinline bool integrator_intersect_shader_next_kernel(
 
   /* Setup next kernel to execute. */
   if (flags & SD_HAS_RAYTRACE) {
-    INTEGRATOR_PATH_NEXT_SORTED(DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST,
-                                DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE,
-                                shader);
+    INTEGRATOR_PATH_NEXT_SORTED(
+        current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, shader);
   }
   else {
-    INTEGRATOR_PATH_NEXT_SORTED(DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST,
-                                DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE,
-                                shader);
+    INTEGRATOR_PATH_NEXT_SORTED(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader);
   }
 
+  /* Setup shadow catcher. */
+  const int object_flags = intersection_get_object_flags(kg, isect);
+  kernel_shadow_catcher_split(INTEGRATOR_STATE_PASS, object_flags);
+
   return true;
 }
 
@@ -122,7 +124,7 @@ ccl_device void integrator_intersect_closest(INTEGRATOR_STATE_ARGS)
   integrator_state_write_isect(INTEGRATOR_STATE_PASS, &isect);
 
 #ifdef __VOLUME__
-  if (INTEGRATOR_STATE_ARRAY(volume_stack, 0, object) != OBJECT_NONE) {
+  if (INTEGRATOR_STATE_ARRAY(volume_stack, 0, shader) != SHADER_NONE) {
     /* Continue with volume kernel if we are inside a volume, regardless
      * if we hit anything. */
     INTEGRATOR_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST,
@@ -140,9 +142,8 @@ ccl_device void integrator_intersect_closest(INTEGRATOR_STATE_ARGS)
     }
     else {
       /* Hit a surface, continue with surface kernel unless terminated. */
-      if (integrator_intersect_shader_next_kernel(INTEGRATOR_STATE_PASS, &isect)) {
-        const int object_flags = intersection_get_object_flags(kg, &isect);
-        kernel_shadow_catcher_split(INTEGRATOR_STATE_PASS, object_flags);
+      if (integrator_intersect_shader_next_kernel<DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST>(
+              INTEGRATOR_STATE_PASS, &isect)) {
         return;
       }
       else {
diff --git a/intern/cycles/kernel/integrator/integrator_megakernel.h b/intern/cycles/kernel/integrator/integrator_megakernel.h
index 6a3622c2531..04c720d90f6 100644
--- a/intern/cycles/kernel/integrator/integrator_megakernel.h
+++ b/intern/cycles/kernel/integrator/integrator_megakernel.h
@@ -63,6 +63,9 @@ ccl_device void integrator_megakernel(INTEGRATOR_STATE_ARGS,
         case DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE:
           integrator_shade_surface(INTEGRATOR_STATE_PASS, render_buffer);
           break;
+        case DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME:
+          integrator_shade_volume(INTEGRATOR_STATE_PASS, render_buffer);
+          break;
         case DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE:
           integrator_shade_surface_raytrace(INTEGRATOR_STATE_PASS, render_buffer);
           break;
diff --git a/intern/cycles/kernel/integrator/integrator_shade_shadow.h b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
index e8aad52a509..975ad750df8 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
@@ -16,11 +16,15 @@
 
 #pragma once
 
+#include "kernel/integrator/integrator_shade_volume.h"
+#include "kernel/integrator/integrator_volume_stack.h"
+
+#include "kernel/kernel_shader.h"
+
 CCL_NAMESPACE_BEGIN
 
 #ifdef __TRANSPARENT_SHADOWS__
-ccl_device_inline float3 integrate_transparent_shadow_shader_eval(INTEGRATOR_STATE_ARGS,
-                                                                  const int hit)
+ccl_device_inline float3 integrate_transparent_surface_shadow(INTEGRATOR_STATE_ARGS, const int hit)
 {
   /* TODO: does aliasing like this break automatic SoA in CUDA?
    * Should we instead store closures separate from ShaderData?
@@ -45,17 +49,67 @@ ccl_device_inline float3 integrate_transparent_shadow_shader_eval(INTEGRATOR_STA
         INTEGRATOR_STATE_PASS, shadow_sd, NULL, PATH_RAY_SHADOW);
   }
 
+#  ifdef __VOLUME__
+  /* Exit/enter volume. */
+  shadow_volume_stack_enter_exit(INTEGRATOR_STATE_PASS, shadow_sd);
+#  endif
+
   /* Compute transparency from closures. */
   return shader_bsdf_transparency(kg, shadow_sd);
 }
 
+#  ifdef __VOLUME__
+ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_ARGS, const int hit)
+{
+  /* TODO: deduplicate with surface, or does it not matter for memory usage? */
+  ShaderDataTinyStorage shadow_sd_storage;
+  ShaderData *shadow_sd = AS_SHADER_DATA(&shadow_sd_storage);
+
+  /* Setup shader data. */
+  Ray ray ccl_optional_struct_init;
+  integrator_state_read_ray(INTEGRATOR_STATE_PASS, &ray);
+
+  Intersection isect ccl_optional_struct_init;
+  integrator_state_read_shadow_isect(INTEGRATOR_STATE_PASS, &isect, hit);
+
+  shader_setup_from_volume(kg, shadow_sd, &ray);
+
+  /* Evaluate shader. */
+  float3 sigma_a = zero_float3();
+  if (!shadow_volume_shader_sample(INTEGRATOR_STATE_PASS, shadow_sd, &sigma_a)) {
+    return one_float3();
+  }
+
+  /* Integrate extinction over segment. */
+  const float start_t = (hit == 0) ? 0.0f : INTEGRATOR_STATE_ARRAY(shadow_isect, hit - 1, t);
+  const float end_t = isect.t;
+  const float t = end_t - start_t;
+
+  return exp3(-sigma_a * t);
+}
+#  endif
+
 ccl_device_inline bool integrate_transparent_shadow(INTEGRATOR_STATE_ARGS, const int num_hits)
 {
   /* Accumulate shadow for transparent surfaces. */
   const int num_recorded_hits = min(num_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
 
   for (int hit = 0; hit < num_recorded_hits; hit++) {
-    const float3 shadow = integrate_transparent_shadow_shader_eval(INTEGRATOR_STATE_PASS, hit);
+#  ifdef __VOLUME__
+    /* Volume shaders. */
+    if (INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) != SHADER_NONE) {
+      const float3 shadow = integrate_transparent_volume_shadow(INTEGRATOR_STATE_PASS, hit);
+      const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
+      if (is_zero(throughput)) {
+        return true;
+      }
+
+      INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
+    }
+#  endif
+
+    /* Surface shaders. */
+    const float3 shadow = integrate_transparent_surface_shadow(INTEGRATOR_STATE_PASS, hit);
     const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
     if (is_zero(throughput)) {
       return true;
diff --git a/intern/cycles/kernel/integrator/integrator_shade_surface.h b/intern/cycles/kernel/integrator/integrator_shade_surface.h
index cdfd00b9304..d305f20d361 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_surface.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_surface.h
@@ -24,6 +24,7 @@
 #include "kernel/kernel_shader.h"
 
 #include "kernel/integrator/integrator_subsurface.h"
+#include "kernel/integrator/integrator_volume_stack.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -183,108 +184,94 @@ ccl_device_forceinline void integrate_surface_direct_light(INTEGRATOR_STATE_ARGS
 #endif
 
 /* Path tracing: bounce off or through surface with new direction. */
-ccl_device_forceinline bool integrate_surface_bounce(INTEGRATOR_STATE_ARGS,
-                                                     ShaderData *sd,
-                                                     const RNGState *rng_state)
+ccl_device_forceinline bool integrate_surface_bsdf_bssrdf_bounce(INTEGRATOR_STATE_ARGS,
+                                                                 ShaderData *sd,
+                                                                 const RNGState *rng_state)
 {
   /* Sample BSDF or BSSRDF. */
-  if (sd->flag & (SD_BSDF | SD_BSSRDF)) {
-    float bsdf_u, bsdf_v;
-    path_state_rng_2D(kg, rng_state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
-    const ShaderClosure *sc = shader_bsdf_bssrdf_pick(sd, &bsdf_u);
+  if (!(sd->flag & (SD_BSDF | SD_BSSRDF))) {
+    return false;
+  }
+
+  float bsdf_u, bsdf_v;
+  path_state_rng_2D(kg, rng_state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+  const ShaderClosure *sc = shader_bsdf_bssrdf_pick(sd, &bsdf_u);
 
 #ifdef __SUBSURFACE__
-    /* BSSRDF closure, we schedule subsurface intersection kernel. */
-    if (CLOSURE_IS_BSSRDF(sc->type)) {
-      return subsurface_bounce(INTEGRATOR_STATE_PASS, sd, sc);
-    }
+  /* BSSRDF closure, we schedule subsurface intersection kernel. */
+  if (CLOSURE_IS_BSSRDF(sc->type)) {
+    return subsurface_bounce(INTEGRATOR_STATE_PASS, sd, sc);
+  }
 #endif
 
-    /* BSDF closure, sample direction. */
-    float bsdf_pdf;
-    BsdfEval bsdf_eval ccl_optional_struct_init;
-    float3 bsdf_omega_in ccl_optional_struct_init;
-    differential3 bsdf_domega_in ccl_optional_struct_init;
-    int label;
+  /* BSDF closure, sample direction. */
+  float bsdf_pdf;
+  BsdfEval bsdf_eval ccl_optional_struct_init;
+  float3 bsdf_omega_in ccl_optional_struct_init;
+  differential3 bsdf_domega_in ccl_optional_struct_init;
+  int label;
 
-    label = shader_bsdf_sample_closure(
-        kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
+  label = shader_bsdf_sample_closure(
+      kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
 
-    if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
-      r

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list