[Bf-blender-cvs] [f76f48c3d3e] blender-v2.91-release: Fix T69911: Adaptive subdivision offscreen dicing does not work correctly if the camera is shifted

Philipp Oeser noreply at git.blender.org
Mon Oct 26 13:06:13 CET 2020


Commit: f76f48c3d3eb3ac518fed158a0f17c7507604ca8
Author: Philipp Oeser
Date:   Mon Oct 26 12:49:37 2020 +0100
Branches: blender-v2.91-release
https://developer.blender.org/rBf76f48c3d3eb3ac518fed158a0f17c7507604ca8

Fix T69911: Adaptive subdivision offscreen dicing does not work correctly if the camera is shifted

Code was assuming frustrum planes are symmetrical which is not the case
for shifting. This lead to a shrinking region if shift was negative (and
a growing region if shift was positive)

So instead of only keeping track of plane on one side (and mirroring
over in code) get the actual planes after shifting and use these
instead.

This code corrects this for ortho and perspective cameras, it does not
touch panoramic cameras.

Reviewed By: brecht

Maniphest Tasks: T69911

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

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

M	intern/cycles/render/camera.cpp
M	intern/cycles/render/camera.h

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

diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index ee68c9ede22..0f2befae320 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -313,9 +313,12 @@ void Camera::update(Scene *scene)
   if (type == CAMERA_PERSPECTIVE) {
     float3 v = transform_perspective(&full_rastertocamera,
                                      make_float3(full_width, full_height, 1.0f));
-
     frustum_right_normal = normalize(make_float3(v.z, 0.0f, -v.x));
     frustum_top_normal = normalize(make_float3(0.0f, v.z, -v.y));
+
+    v = transform_perspective(&full_rastertocamera, make_float3(0.0f, 0.0f, 1.0f));
+    frustum_left_normal = normalize(make_float3(-v.z, 0.0f, v.x));
+    frustum_bottom_normal = normalize(make_float3(0.0f, -v.z, v.y));
   }
 
   /* Compute kernel camera data. */
@@ -644,17 +647,22 @@ float Camera::world_to_raster_size(float3 P)
 
     if (offscreen_dicing_scale > 1.0f) {
       float3 p = transform_point(&worldtocamera, P);
-      float3 v = transform_perspective(&full_rastertocamera,
-                                       make_float3(full_width, full_height, 0.0f));
+      float3 v1 = transform_perspective(&full_rastertocamera,
+                                        make_float3(full_width, full_height, 0.0f));
+      float3 v2 = transform_perspective(&full_rastertocamera, make_float3(0.0f, 0.0f, 0.0f));
 
       /* Create point clamped to frustum */
       float3 c;
-      c.x = max(-v.x, min(v.x, p.x));
-      c.y = max(-v.y, min(v.y, p.y));
+      c.x = max(v2.x, min(v1.x, p.x));
+      c.y = max(v2.y, min(v1.y, p.y));
       c.z = max(0.0f, p.z);
 
-      float f_dist = len(p - c) / sqrtf((v.x * v.x + v.y * v.y) * 0.5f);
-
+      /* Check right side */
+      float f_dist = len(p - c) / sqrtf((v1.x * v1.x + v1.y * v1.y) * 0.5f);
+      if (f_dist < 0.0f) {
+        /* Check left side */
+        f_dist = len(p - c) / sqrtf((v2.x * v2.x + v2.y * v2.y) * 0.5f);
+      }
       if (f_dist > 0.0f) {
         res += res * f_dist * (offscreen_dicing_scale - 1.0f);
       }
@@ -685,10 +693,8 @@ float Camera::world_to_raster_size(float3 P)
       /* Distance from the four planes */
       float r = dot(p, frustum_right_normal);
       float t = dot(p, frustum_top_normal);
-      p = make_float3(-p.x, -p.y, p.z);
-      float l = dot(p, frustum_right_normal);
-      float b = dot(p, frustum_top_normal);
-      p = make_float3(-p.x, -p.y, p.z);
+      float l = dot(p, frustum_left_normal);
+      float b = dot(p, frustum_bottom_normal);
 
       if (r <= 0.0f && l <= 0.0f && t <= 0.0f && b <= 0.0f) {
         /* Point is inside frustum */
@@ -701,9 +707,9 @@ float Camera::world_to_raster_size(float3 P)
       else {
         /* Point may be behind or off to the side, need to check */
         float3 along_right = make_float3(-frustum_right_normal.z, 0.0f, frustum_right_normal.x);
-        float3 along_left = make_float3(frustum_right_normal.z, 0.0f, frustum_right_normal.x);
+        float3 along_left = make_float3(frustum_left_normal.z, 0.0f, -frustum_left_normal.x);
         float3 along_top = make_float3(0.0f, -frustum_top_normal.z, frustum_top_normal.y);
-        float3 along_bottom = make_float3(0.0f, frustum_top_normal.z, frustum_top_normal.y);
+        float3 along_bottom = make_float3(0.0f, frustum_bottom_normal.z, -frustum_bottom_normal.y);
 
         float dist[] = {r, l, t, b};
         float3 along[] = {along_right, along_left, along_top, along_bottom};
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 0e91fa44a5b..21dad5eea3b 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -170,6 +170,8 @@ class Camera : public Node {
 
   float3 frustum_right_normal;
   float3 frustum_top_normal;
+  float3 frustum_left_normal;
+  float3 frustum_bottom_normal;
 
   /* update */
   bool need_update;



More information about the Bf-blender-cvs mailing list