how to render correct reflection of Fluctuation water

Started by
0 comments, last by db123 12 years, 1 month ago
yesterdy, i create a topic to find the cliped projection matrix, but it only works with a flat surface, we i apply a wave on the surface by perlin noise, it is wrong.

http://www.gamedev.net/topic/621207-how-to-make-view-matrix-and-projective-matrix-for-reflection-by-a-plane/

// reflection by a flat surface:
[attachment=7560:1.png]

// waved water.
// if y > Plane.y
[attachment=7561:4.png]

// if y < Plane.y
[attachment=7562:3.png]

this is my code to render the reflection.

Plane Class, it is the same with DXPlane.


// ax+by+cz+dw=0
struct FPlane
{
hvar float a; //
hvar float b; //
hvar float c; //
hvar float d; //
FPlane( float _a=0, float _b=0, float _c=0, float _d=0 ):a(_a), b(_b), c(_c),d(_d)
{
}
FPlane( const FVector3& vPosition, const FVector3& vNormal ):a(vNormal.x),b(vNormal.y),c(vNormal.z),d( -vPosition.Dot(vNormal) )
{
}
FPlane( const FVector3& Point1, const FVector3& Point2, const FVector3& Point3 )
{
FVector3 Edge1 = Point2 - Point1;
FVector3 Edge2 = Point3 - Point1;
FVector3 Normal = Edge1.Cross( Edge2 ).AsNormalized();
a = Normal.x;
b = Normal.y;
c = Normal.z;
d = -Point1.Dot(Normal);
}
inline void Normalize()
{
float norm = sqrt( a*a + b*b + c*c );
if( norm > 0.0f )
{
a /= norm;
b /= norm;
c /= norm;
d /= norm;
}
else
{
a = b = c = d = 0.0f;
}
}
inline float Dot( const FVector4& v4 ) const
{
return a*v4.x + b*v4.y + c*v4.z + d*v4.w;
}
inline float DotCoord( const FVector3& v3 ) const
{
return a*v3.x + b*v3.y + c*v3.z + d*1.0f;
}

inline float DotNormal( const FVector3& v3 ) const
{
return a*v3.x + b*v3.y + c*v3.z;
}
inline bool IntersectLine( FVector3& vResult, const FVector3& v1, const FVector3& v2 ) const
{
FVector3 Normal( a, b, c );
FVector3 Direction = v2 - v1;
float dot = Normal.Dot( Direction );
if( !dot )
{
return false;
}
float temp = ( d + Normal.Dot( v1 ) )/ dot;
vResult.x = v1.x - temp * Direction.x;
vResult.y = v1.y - temp * Direction.y;
vResult.z = v1.z - temp * Direction.z;
return true;
}
inline FPlane TransformByIT( const FMatrix& M ) const
{
FPlane Plane;
Plane.a = M[0][0] * a + M[1][0] * b + M[2][0]*c + M[3][0]*d;
Plane.b = M[0][1] * a + M[1][1] * b + M[2][1]*c + M[3][1]*d;
Plane.c = M[0][2] * a + M[1][2] * b + M[2][2]*c + M[3][2]*d;
Plane.d = M[0][3] * a + M[1][3] * b + M[2][3]*c + M[3][3]*d;
return Plane;
}
inline FPlane TransformBy( const FMatrix& M ) const
{
FMatrix mIT = M.Inverse().Transpose();
return this->TransformByIT( mIT );
}
FMatrix ReflectMatrix() const
{
FPlane P( a, b, c, d );
P.Normalize();
return FMatrix(
-2*P.a*P.a + 1, -2*P.b*P.a, -2*P.c*P.a, 0,
-2*P.a*P.b, -2*P.b*P.b +1, -2*P.c*P.b, 0,
-2*P.a*P.c, -2*P.b*P.c, -2*P.c*P.c+1, 0,
-2*P.a*P.d, -2*P.b*P.d, -2*P.c*P.d, 1 );
}
};


this is the new projective matrix.

struct FClipProjectionMatrix : public FMatrix
{
FClipProjectionMatrix( const FMatrix& mProj, const FPlane& ViewSpacePlane ) : \
FMatrix(mProj)
{
FPlane Plane( ViewSpacePlane );
Plane.Normalize();
FMatrix mProjIT = mProj.Inverse().Transpose();
FPlane ClipPlane = Plane.TransformByIT(mProjIT);
if( abs( ClipPlane.d ) <= 0.00001f )
{
return;
}
if( ClipPlane.d > 0 )
{
ClipPlane.a = -Plane.a;
ClipPlane.b = -Plane.b;
ClipPlane.c = -Plane.c;
ClipPlane.d = -Plane.d;
ClipPlane = ClipPlane.TransformByIT(mProjIT);
}
mProjIT.Identity();
mProjIT[0][2] = ClipPlane.a;
mProjIT[1][2] = ClipPlane.b;
mProjIT[2][2] = ClipPlane.c;
mProjIT[3][2] = ClipPlane.d;
((FMatrix&)*this) = this->Multipy( mProjIT );
}
};


/// the render code

FMatrix ReflectMatrix = Plane.ReflectMatrix();
FMatrix newMatrix = ReflectMatrix.Multipy( ViewInfo.mView );
ViewInfo.mView = newMatrix;
float3 vPos = this->GetLocation();
float3 vNormal = GetCapturePlaneNormal();
FPlane Plane( vPos, vNormal );
FPlane ReflectionPlane = Plane.TransformBy( ViewInfo.mView );
FClipProjectionMatrix mClipProj( ViewInfo.mProj, ReflectionPlane );
ViewInfo.mProj = mClipProj;
// ViewInfo.mView ViewInfo.mProj is the new view matrix and projective matrix.


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if i render the water first and make a depth buffer, how to clip other primitive by this buffer ?
sad.png sad.png sad.png
Advertisement
please delete this topic.

This topic is closed to new replies.

Advertisement