Advanced Effects

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Now Irrlricht GLSL Screen Space Reflection is another matter!
But before that I'd like to get Normal Maps etc working with Deferred Rendering..
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

While playing around with Screen Space Reflection, I saw that finding the INTERSECTION between
a VECTOR and a PLANE seems important (raytracing)..
In my case this vector would be a "Finite Line" with a Start XYZ and an End XYZ..
Pretty Straight Forward..

So I searched the Internet for a simple function which is fed
the "Line Start and End Points", The "Plane Position" and the "Plane Normal"
that would simply return the INTERSECTION XYZ..

I Couldn't find any that did what I needed.

Image
Last edited by Vectrotek on Thu Feb 09, 2017 11:45 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

So I tried expressing of the problem in mathematical notation..

Now, after some screen grabs of my notes, I'll also paste the Final Resulting
C++ Function. (written specially for Irrlicht and easily ported to GLSL or HLSL)

You'll note that I tried to avoid "Inter Variable Transfers" as much as possible (using long Math-Strings)
to keep CPU or GPU load as low as possible..
(I'm not sure if these rules still count with modern cache and memory hardware)

Here goes.. (Math Notes)
Last edited by Vectrotek on Thu Feb 09, 2017 11:46 pm, edited 3 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

STEP 1:

(I now know that there is an much easier way thanks to "thanhle")

Image
Last edited by Vectrotek on Fri Feb 10, 2017 8:44 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

STEP 2:
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

STEP 3: (The logic of all the Math Steps is converted to a C++ function following this)
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

THE FUNCTION..
(like I would have liked to find on the Internet)
There may be an easier method, but I sure couldn't find it..

This function has been tested extensively, and if anyone
has any questions please let me know..

Code: Select all

 
 
 // Normal "should" be normalised. (especially if using Dot Product to determine on which side a checked point is located)
 
 vector3df GetPlaneIntersectionGivenLineTwoEndPoints (vector3df LinePtA ,vector3df LinePtB , vector3df Pln, vector3df PNml)
  {
   vector3df ClosePtA;
   vector3df ClosePtB;
 
   ClosePtA.X =  (LinePtA.X * (PNml.Y * PNml.Y) + LinePtA.X * (PNml.Z * PNml.Z) + (PNml.X * PNml.X) * Pln.X 
                  - PNml.X * PNml.Y * LinePtA.Y + PNml.X * PNml.Y * Pln.Y 
                  - PNml.X * PNml.Z * LinePtA.Z + PNml.X * PNml.Z * Pln.Z )
                  / ((PNml.X * PNml.X) + (PNml.Y * PNml.Y) + (PNml.Z * PNml.Z));        
 
   ClosePtA.Y =  (LinePtA.Y * (PNml.X * PNml.X) + LinePtA.Y * (PNml.Z * PNml.Z) - PNml.Y * PNml.X * LinePtA.X 
                  + PNml.Y * PNml.X * Pln.X + (PNml.Y * PNml.Y) * Pln.Y 
                  - PNml.Y * PNml.Z * LinePtA.Z + PNml.Y * PNml.Z * Pln.Z)
                  / ((PNml.X * PNml.X) + (PNml.Y * PNml.Y) + (PNml.Z * PNml.Z));        
 
   ClosePtA.Z = (LinePtA .Z * (PNml.X * PNml.X) + LinePtA.Z * (PNml.Y * PNml.Y)
                 - PNml.Z * PNml.X * LinePtA.X 
                 + PNml.Z * PNml.X * Pln.X - PNml.Z * PNml.Y * LinePtA.Y + PNml.Z * PNml.Y * Pln.Y + Pln.Z * (PNml.Z * PNml.Z))
                 / ((PNml.X * PNml.X) + (PNml.Y * PNml.Y) + (PNml.Z * PNml.Z));  
 
   ClosePtB.X = (LinePtB.X * (PNml.Y * PNml.Y) + LinePtB.X * (PNml.Z * PNml.Z) + (PNml.X * PNml.X) * Pln.X 
                 - PNml.X * PNml.Y * LinePtB.Y + PNml.X * PNml.Y * Pln.Y 
                 - PNml.X * PNml.Z * LinePtB.Z + PNml.X * PNml.Z * Pln.Z )
                 / ((PNml.X * PNml.X) + (PNml.Y * PNml.Y) + (PNml.Z * PNml.Z));        
 
   ClosePtB.Y = (LinePtB.Y * (PNml.X * PNml.X) + LinePtB.Y * (PNml.Z * PNml.Z) - PNml.Y * PNml.X * LinePtB.X 
                 + PNml.Y * PNml.X * Pln.X + (PNml.Y * PNml.Y) * Pln.Y 
                 - PNml.Y * PNml.Z * LinePtB.Z + PNml.Y * PNml.Z * Pln.Z)
                 / ((PNml.X * PNml.X) + (PNml.Y * PNml.Y) + (PNml.Z * PNml.Z));        
 
   ClosePtB.Z = (LinePtB.Z * (PNml.X * PNml.X) + LinePtB.Z * (PNml.Y * PNml.Y)
                 - PNml.Z * PNml.X * LinePtB.X 
                 + PNml.Z * PNml.X * Pln.X - PNml.Z * PNml.Y * LinePtB.Y + PNml.Z * PNml.Y * Pln.Y + Pln.Z * (PNml.Z * PNml.Z))
                 / ((PNml.X * PNml.X) + (PNml.Y * PNml.Y) + (PNml.Z * PNml.Z));  
 
   vector3df DeltaCloseA;
   vector3df DeltaCloseB;
   // I know that there are operators for these that would cost less code,
   // but when converting to Inline Assembly (maybe some time) this would be easier to read and translate..
   DeltaCloseA.X = ClosePtA.X - LinePtA.X;
   DeltaCloseA.Y = ClosePtA.Y - LinePtA.Y;
   DeltaCloseA.Z = ClosePtA.Z - LinePtA.Z;
 
   DeltaCloseB.X = ClosePtB.X - LinePtB.X;
   DeltaCloseB.Y = ClosePtB.Y - LinePtB.Y;
   DeltaCloseB.Z = ClosePtB.Z - LinePtB.Z;
 
   f32 DistA = sqrt ((DeltaCloseA .X * DeltaCloseA.X)
                    +(DeltaCloseA .Y * DeltaCloseA.Y)
                    +(DeltaCloseA .Z * DeltaCloseA.Z));
 
   f32 DistB = sqrt ((DeltaCloseB.X * DeltaCloseB.X)
                    +(DeltaCloseB.Y * DeltaCloseB.Y)
                    +(DeltaCloseB.Z * DeltaCloseB.Z));
 
   f32 Relation = DistA / (DistA + DistB);
 
   vector3df IntersectionPoint;
   IntersectionPoint.X = ClosePtA.X + ((ClosePtB.X - ClosePtA.X) * Relation);
   IntersectionPoint.Y = ClosePtA.Y + ((ClosePtB.Y - ClosePtA.Y) * Relation);
   IntersectionPoint.Z = ClosePtA.Z + ((ClosePtB.Z - ClosePtA.Z) * Relation);
 
   return IntersectionPoint;
  }
 
 
Last edited by Vectrotek on Thu Feb 09, 2017 11:55 pm, edited 2 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

I hope someone finds this useful!

Cheers!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Nothing to do with Planes etc, but I just figured that if this kind of SSAO depends on Depth and Deferred Rendering also
uses Depth then why not have them both in the same Shader and save a few inter-buffer operations?!
SSAO should block out Specular as well as Diffuse.
So one shader could do Specular, Diffuse and SSAO in one pass..
The only cost would be that Specular and diffuse would not be available in separate
buffers (for whatever reason) which is actually fine..
If we wanted them in separate passes then SSAO would have to be done twice (not a good idea)..

Image
Last edited by Vectrotek on Fri Feb 10, 2017 6:11 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Rethinking..

Sometimes breaking an expression up into all its statements might not be such a great idea because
things like the Dot Product and Acquired Distances get duplicated unnecessarily in the final "Long Math String"
in such a way that skipping inter memory transfers actually takes more GPU/CPU time!
So one must find a balance between simplified math statements and the use of variables in memory..

But one can't try all the thousands of possible combinations and see which takes up less time, so what does one do?
Last edited by Vectrotek on Fri Feb 10, 2017 6:02 pm, edited 1 time in total.
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Advanced Effects

Post by thanhle »

There's actually plenty on the internet.

1) You would find the equation of a plane. Which is simple.

2) Equation of a line, which is simple. Just use the parametric form equation (xt, yt, zt)

3) Subtitute xt, yt, zt into plane equation. Solve for t.
4) Substitute t to line parametric form. Done!

Remember to check for parallel, and to avoid division by zero error. E.g. which is the denominator of equation for t found in 3.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Thanks..

Thinking..
Last edited by Vectrotek on Fri Feb 10, 2017 8:45 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

O.K. I humbly make the following submission..
My brave attempt at doing it myself actually worked, but was bloated and
it did not do the "checks" necessary as "thanhle" pointed out..
(there were some useful spin offs though)

So I think this is how it is..

Where the following is defined in your code..

Code: Select all

 
 #define  NO_INTERSECTION 0
 #define  INTERSECTION_FOUND 1
 #define  PARALLEL_TO_PLANE_AND_ON_PLANE 2   // (a little extra)
 
 float GetDotProduct (vector3df VecA, vector3df VecB)
  {return (VecA.X * VecB.X) + (VecA.Y * VecB.Y) + (VecA.Z * VecB.Z);
  }
 
 vector3df AcquiredIntersection;  // This is what it's all about..
 
 struct Segment // Finite Line with a Start and an End..
  {vector3df P0; // Line Start..
   vector3df P1; // Line End..
  };
 
 struct Plane
  {vector3df Normal; // Plane Direction..
   vector3df V0;      // Any Position on the Plane..
  };
 
 
This does the trick:

Code: Select all

 
 int GetSegmentAndPlaneIntersection(Segment TheSegment, Plane ThePlane, vector3df* Intersection)
  {vector3df    SegVect         = TheSegment.P1 - TheSegment.P0;
   vector3df    SegMinPlaneVect = TheSegment.P0 - ThePlane.V0;
   float        DotProduct      = GetDotProduct(ThePlane.Normal, SegVect);
   float        NegDot          = -GetDotProduct(ThePlane.Normal, SegMinPlaneVect);
   if (fabs(DotProduct) < 0.00001)  // How stringent is the rules applied?
    {if (NegDot == 0.0) return PARALLEL_TO_PLANE_AND_ON_PLANE;
     else
     return NO_INTERSECTION;
    }
   float sI = NegDot / DotProduct;
   if (sI < 0 || sI > 1)   return NO_INTERSECTION;
   *Intersection = TheSegment.P0 + sI * SegVect;
   return INTERSECTION_FOUND;
  }
 
 
The "Usage" would then be something like:

Code: Select all

 
 // Where "Situation" could be one of three things as #defined at the top..
 // and "AcquiredIntersection" is passed by reference (and possibly loaded when there is an intersection)..
 
 int Situation = GetSegmentAndPlaneIntersection(MyLineSegment, MyPlane, &AcquiredIntersection); 
 
 
Image

Thanks thanhle!
Does this look better?
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Image
Post Reply