1

So I'm currently programming a shader in hlsl (more specifically, shaderlab, unity's version of hlsl) where I want to simulate rocket engine's plumes. These plumes tend to follow an equation that I simplified quite a lot to be (where $A$ represents the linear expansion and $B$ represents the quadratic expansion of the plume)

$$f(x) = \text{Radius}+(x*A) + (x^2 * B)$$

and the ray function would be

$$f(x) = \text{RayOrigin} + \text{RayDirection} * x$$

These being in $3D$ space, where the plume function will be rotated $360^\circ$ around the origin, I'm looking for a way to find the 1st and 2nd intersections of the ray function with the plume function. The ideal formula would be to find the ray function's $x$ given that I have the $\text{Radius}$,$\text{RayOrigin}$, $\text{RayDirection}$, $A$ and $B$

TShiong
  • 1,257

2 Answers2

1

Unfortunately, I am unable to comment because I have under 50 reputation. However, I will try to answer your question. I'm not sure what you mean by the "plume function will be rotated 360º around the origin"; I assume it is fixed at that orientation.

Finding the intersection is simply to find the points where the outputs of the 2 functions are equal.

$$\text{Plume}(x) = \text{Ray}(x)$$ $$Bx^2+Ax+\text{Radius} = \text{RayDirection}\cdot x + \text{RayOrigin}$$ $$B\cdot x^2+(A-\text{RayDirection}) \cdot x+(\text{Radius}-\text{RayOrigin})=0.$$

Now it is simply a matter of applying the quadratic formula $$x_{1,2} = \frac {-b \pm \sqrt{b^2 -4ac}} {2a}$$ with $a=B$, $b=A-\text{RayDirection}$ and $c=\text{Radius} - \text{RayOrigin}$.

You can find the number of solutions using $\Delta = b^2-4ac$. We have the 3 cases:

  1. $$\Delta<0 \implies \text{No solution}$$
  2. $$\Delta=0 \implies \text{1 solution}$$
  3. $$\Delta>0 \implies \text{2 solutions}$$

which you can use to determine whether or not to try to compute solutions.

Edit: here are the equations for the plume and line intersection: \begin{cases} x^2+z^2=(\text{Plume}(y))^2 \\ x=x_0-x_1+ta \\ y=y_0-y_1+tb \\ z=z_0-z_1+tc \\ \end{cases} where the parametric form of a line passing through $(x_0,y_0,z_0)$ with direction $(a,b,c)$ is used. This is assuming the plume is placed at $(x_1,y_1,z_1)$ in global coordinates and revolved around the y-axis. You can plug in the equation into a numerical root finder such as Newton's method or the more stable ITP method to find solutions of $t$, which you can use to find the points of intersection by plugging $t$ into the equation of the line $\vec v = (x_0,y_0,z_0) + t(a,b,c)$. Also, there can be more than 2 intersections as you can see from the equation. I believe there can be up to 3, but since the first equation yields a 4-th degree equation in $t$ there might be cases with 4 solutions, I am not too sure.

  • by "rotated 360º" i mean like this this , i've extracted the example function to the side (named Peq) so its easier to see. but basically creating a "cylinder-like" shape another example – Pedro Costa Sep 03 '23 at 18:05
  • I see, I will give it some thought. Both your functions are in 3D space and dependent on time, right? Do you have an equation to model your raycast? I believe there are implementations for collisions in Unity. You could try to model the plume shape using some equations then use raycasts to figure out the collision points, which would be easier. – The Innkeeper Sep 03 '23 at 18:10
  • the implementation is actually for visual effects, so unfortunately i can't use unity's raycast system (i wish i could). Yes, both for 3D Space. And No, not dependent on time, $Plume(x)$ would be for $0<=x<=1$ and $ray(x)$ would be for $x>0$. The idea here is to find the entry and exit point (1st and 2nd intersections) and create a volumetric effect with it (via raymarching between both points). I'll also look into implementing the formula you sent and come back with results! Thank you very much for your help! – Pedro Costa Sep 03 '23 at 18:22
  • The formula will not work, it is for 2 dimensions. I will have to work through for 3 dimensions. However, how is your plume object created in the scene? It seems like you could just add a mesh collider and use an invisible GameObject to cast rays onto it. I will try to work it out in 3D for now. – The Innkeeper Sep 03 '23 at 18:26
  • I have edited the answer to take into account the revolution of the parabola. – The Innkeeper Sep 03 '23 at 19:29
  • Got it working perfectly! here's a demo of the shader! The problem with using raycasts onto objects is that i can't cheaply transfer that data to the shader, so almost everything has to be calculated on the shader code itself. The 1st intersection is red and the 2nd is green, so wherever you see yellow means that there's 4 roots/intersections.

    https://www.shadertoy.com/view/Dl2Bzw

    Also the shader on unity

    https://cdn.discordapp.com/attachments/1085910413239140416/1148786412263591936/Unity_BTsdTZbw6V.gif

    – Pedro Costa Sep 06 '23 at 01:07
1

As I understood, calling the support axis line as

$$ L_{\lambda}\to p_{\lambda} = p_0+\lambda \vec w $$

From $\vec w$ we create $\hat u, \hat v$ such that $\vec w\cdot \hat u = \vec w\cdot \hat v = \hat u\cdot \hat v = 0, \|\hat u\|=\|\hat v\|= 1$ and then we define

$$ r_{\lambda}=r_0 + a\lambda + b\lambda^2\\ p_{\lambda} = p_0+\lambda \vec w\\ q_{\lambda,\theta} = p_{\lambda}+r_{\lambda}\left(\hat u\cos\theta+\hat v\sin\theta\right) $$

thus we can plot each plume giving values to $\lambda,\theta$. Follows a plot for

$$ \cases{ p_0=(0,0,0)'\\ r_0=1\\ a=0.2\\ b=0.1\\ \vec w =4(1,1,1)' } $$

enter image description here

and for

$$ \cases{ p_0=(0,0,0)'\\ r_0=1\\ a=0.2\\ b=-1\\ \vec w =4(1,1,1)' } $$

enter image description here

NOTE

To determine the crossing point for the plume with the direction line is sufficient to determine the positive root for

$$ r_{\lambda}=0 $$

thus in the last case we have $\lambda=1.10499$ giving

enter image description here

Cesareo
  • 33,252