What mathematical operation replaces series of multiplication

96 Views Asked by At

Technical details

because I might misunderstand my problem...

I have made an algorithm that calculates, what camera view frustum is needed to view a mesh so that it would be fully visible in the camera view, but as little as possible outside of it. TechnicalImage

Left view - Side view preview
Right view - Desired effect

Red box - Mesh bounds (MMB)
Blue lines - View frustum lines
Green lines - Far view frustum
White line - Center of the red Box from camera

Mathematics problem

To calculate the effect (right image) I took most outside points of the bounding box and calculated its position in the Viewport (2D) coordinates system ($\Bbb V$). Then for each vertex of the $\Bbb{V}$, I multiplied it by Left ($\mathbf l$), Right ($\mathbf r$), Top ($\mathbf t$), and Bottom ($\mathbf b$) separately, where $\mathbf l$, $\mathbf r$, $\mathbf t$, $\mathbf b$ are used to create frustum matrix which is later passed to rendering. Frustum Image

To achieve the results I'm looking for I need to multiply $\mathbf l$, $\mathbf r$, $\mathbf t$, $\mathbf b$ multiple times

Additional notation notes:

  • $\Bbb V$ - Viewport values are [0,1] when inside view of the camera
  • $\Bbb{Vl}$ - Viewport left corner on X axis position
  • $\Bbb{Vr}$ - Viewport right corner on X axis position $\Bbb{Vr} = \Bbb{Vl} + \Bbb{V} width$
  • $\Bbb{Vt}$ - Viewport top corner on Y axis position
  • $\Bbb{Vb}$ - Viewport bottom corner on Y axis position $\Bbb{Vb} = \Bbb{Vt} + \Bbb{V} height$

Example values: Example values

Starting values Final values
$\Bbb{Vl}$ = 0.85627 $\Bbb{Vl}$ = 1
$\Bbb{Vr}$ = 0.14078 $\Bbb{Vr}$ = 0
$\Bbb{Vt}$ = 0.72571 $\Bbb{Vt}$ = 1
$\Bbb{Vb}$ = 0.27459 $\Bbb{Vb}$ = 0
$\Bbb{l}$ = -0.01 $\Bbb{l}$ = -0.0072
$\Bbb{r}$ = 0.01 $\Bbb{r}$ = 0.0072
$\Bbb{t}$ = 0.01 $\Bbb{t}$ = 0.0045
$\Bbb{b}$ = -0.01 $\Bbb{b}$ = -0.045

Current solution

Note: Each multiplication is stepped - so $\Bbb{V}$ position is recalculated after mutliplication $$\mathbf{l} = \prod\mathbf{l}*(1-\Bbb{Vr}) $$ $$\mathbf{r} = \prod\mathbf{r}*(\Bbb{Vl}) $$ $$\mathbf{t} = \prod\mathbf{t}*(\Bbb{Vt}) $$ $$\mathbf{b} = \prod\mathbf{b}*(1-\Bbb{Vb}) $$

Main Question - Is there any way to replace (infinity) multiplications to get proper values of $\mathbf l$, $\mathbf r$, $\mathbf t$, and $\mathbf b$?

Secondary Question - If anwser still will be multiplication, is there any way to fix the issue when $\mathbf l$, $\mathbf r$, $\mathbf t$, or $\mathbf b$ become 0?

Sorry for the wrong notation or any problems with understanding my question...

EDIT: Video to showcase how it "should work" Video - As you can see it works because there are around 60 multiplications per second and for my use case I need to make it to one to make my solution optimized

EDIT 2:

Single side value progression example

  • Top value = $\Bbb{Vr}$ => Approaching 0
  • Bottom value = $\Bbb{l}$ => Approaching ~0,002691

enter image description here

1

There are 1 best solutions below

0
On

So I figured this out (but have no idea why this works)

enter image description here

Instead of relying on Viewport values alone - I decided to calculate Viewport to Frustrum at distance (White box - rectV value) and then use Far plane as reference.

Array elements of rectV and farV are points in WorldSpace of each corner

                Left = rectV[2].x / rectV[2].z / (farV[2].x / farV[2].z) * Right;
                Right = rectV[0].x / rectV[0].z / (farV[0].x / farV[0].z) * Left;
                Top = rectV[0].y / rectV[0].z / (farV[0].y / farV[0].z) * Bottom;
                Bottom = rectV[1].y / rectV[1].z / (farV[1].y / farV[1].z) * Top;

If someone smarter then have an idea of why this returns the proper value, and why the order of those calculations do not matter please let me know, I would love to know why...