Advanced Effects
Re: Advanced Effects
Now Irrlricht GLSL Screen Space Reflection is another matter!
But before that I'd like to get Normal Maps etc working with Deferred Rendering..
But before that I'd like to get Normal Maps etc working with Deferred Rendering..
Re: Advanced Effects
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.
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.
Last edited by Vectrotek on Thu Feb 09, 2017 11:45 pm, edited 1 time in total.
Re: Advanced Effects
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)
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.
Re: Advanced Effects
STEP 1:
(I now know that there is an much easier way thanks to "thanhle")
(I now know that there is an much easier way thanks to "thanhle")
Last edited by Vectrotek on Fri Feb 10, 2017 8:44 pm, edited 1 time in total.
Re: Advanced Effects
STEP 3: (The logic of all the Math Steps is converted to a C++ function following this)
Re: Advanced Effects
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..
(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.
Re: Advanced Effects
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)..
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)..
Last edited by Vectrotek on Fri Feb 10, 2017 6:11 pm, edited 1 time in total.
Re: Advanced Effects
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?
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.
Re: Advanced Effects
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.
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.
Re: Advanced Effects
Thanks..
Thinking..
Thinking..
Last edited by Vectrotek on Fri Feb 10, 2017 8:45 pm, edited 1 time in total.
Re: Advanced Effects
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..
This does the trick:
The "Usage" would then be something like:
Thanks thanhle!
Does this look better?
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..
};
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;
}
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);
Thanks thanhle!
Does this look better?