mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0024864: Implementing refractions in ray-tracing
Refraction index passed to raytrace shader. For transparent objects implemented ray refraction according to refraction index. Transparent materials modified to look better with refractions.
This commit is contained in:
parent
4bc0bb8ab1
commit
dc9ef964d2
@ -363,6 +363,7 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
|
|||||||
ContextFillArea.Back.Specular = float (aBack.Specular());
|
ContextFillArea.Back.Specular = float (aBack.Specular());
|
||||||
ContextFillArea.Back.Transparency = float (aBack.Transparency());
|
ContextFillArea.Back.Transparency = float (aBack.Transparency());
|
||||||
ContextFillArea.Back.Emission = float (aBack.Emissive());
|
ContextFillArea.Back.Emission = float (aBack.Emissive());
|
||||||
|
ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
|
||||||
|
|
||||||
// Reflection mode
|
// Reflection mode
|
||||||
ContextFillArea.Back.IsAmbient = aBack.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
|
ContextFillArea.Back.IsAmbient = aBack.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
|
||||||
@ -404,6 +405,7 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
|
|||||||
ContextFillArea.Front.Specular = float (aFront.Specular());
|
ContextFillArea.Front.Specular = float (aFront.Specular());
|
||||||
ContextFillArea.Front.Transparency = float (aFront.Transparency());
|
ContextFillArea.Front.Transparency = float (aFront.Transparency());
|
||||||
ContextFillArea.Front.Emission = float (aFront.Emissive());
|
ContextFillArea.Front.Emission = float (aFront.Emissive());
|
||||||
|
ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
|
||||||
|
|
||||||
// Reflection mode
|
// Reflection mode
|
||||||
ContextFillArea.Front.IsAmbient = aFront.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
|
ContextFillArea.Front.IsAmbient = aFront.ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0;
|
||||||
|
@ -219,7 +219,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
|
|||||||
|
|
||||||
const BVH_Vec4f aSize = myRaytraceGeometry.Box().Size();
|
const BVH_Vec4f aSize = myRaytraceGeometry.Box().Size();
|
||||||
|
|
||||||
myRaytraceSceneEpsilon = Max (1e-4f, 1e-4f * sqrtf (
|
myRaytraceSceneEpsilon = Max (1e-7f, 1e-4f * sqrtf (
|
||||||
aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
|
aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
|
||||||
|
|
||||||
return UploadRaytraceData();
|
return UploadRaytraceData();
|
||||||
@ -290,8 +290,8 @@ void CreateMaterial (const OPENGL_SURF_PROP& theProp, OpenGl_RaytraceMaterial& t
|
|||||||
// to produce realistic-looking transparency effect
|
// to produce realistic-looking transparency effect
|
||||||
theMaterial.Transparency = BVH_Vec4f (powf (theProp.trans, 0.75f),
|
theMaterial.Transparency = BVH_Vec4f (powf (theProp.trans, 0.75f),
|
||||||
1.f - theProp.trans,
|
1.f - theProp.trans,
|
||||||
1.f,
|
theProp.index == 0 ? 1.f : theProp.index,
|
||||||
1.f);
|
theProp.index == 0 ? 1.f : 1.f / theProp.index);
|
||||||
|
|
||||||
const float aMaxRefl = Max (theMaterial.Diffuse.x() + theMaterial.Specular.x(),
|
const float aMaxRefl = Max (theMaterial.Diffuse.x() + theMaterial.Specular.x(),
|
||||||
Max (theMaterial.Diffuse.y() + theMaterial.Specular.y(),
|
Max (theMaterial.Diffuse.y() + theMaterial.Specular.y(),
|
||||||
|
@ -92,14 +92,14 @@ struct SIntersect
|
|||||||
|
|
||||||
#define MAXFLOAT 1e15f
|
#define MAXFLOAT 1e15f
|
||||||
|
|
||||||
#define SMALL vec3 (exp2 (-80.f))
|
#define SMALL vec3 (exp2 (-80.0f))
|
||||||
|
|
||||||
#define ZERO vec3 (0.f, 0.f, 0.f)
|
#define ZERO vec3 (0.0f, 0.0f, 0.0f)
|
||||||
#define UNIT vec3 (1.f, 1.f, 1.f)
|
#define UNIT vec3 (1.0f, 1.0f, 1.0f)
|
||||||
|
|
||||||
#define AXIS_X vec3 (1.f, 0.f, 0.f)
|
#define AXIS_X vec3 (1.0f, 0.0f, 0.0f)
|
||||||
#define AXIS_Y vec3 (0.f, 1.f, 0.f)
|
#define AXIS_Y vec3 (0.0f, 1.0f, 0.0f)
|
||||||
#define AXIS_Z vec3 (0.f, 0.f, 1.f)
|
#define AXIS_Z vec3 (0.0f, 0.0f, 1.0f)
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -164,11 +164,11 @@ float IntersectSphere (in SRay theRay, in float theRadius)
|
|||||||
|
|
||||||
float aD = aDdotO * aDdotO - aDdotD * (aOdotO - theRadius * theRadius);
|
float aD = aDdotO * aDdotO - aDdotD * (aOdotO - theRadius * theRadius);
|
||||||
|
|
||||||
if (aD > 0.f)
|
if (aD > 0.0f)
|
||||||
{
|
{
|
||||||
float aTime = (sqrt (aD) - aDdotO) * (1.f / aDdotD);
|
float aTime = (sqrt (aD) - aDdotO) * (1.0f / aDdotD);
|
||||||
|
|
||||||
return aTime > 0.f ? aTime : MAXFLOAT;
|
return aTime > 0.0f ? aTime : MAXFLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MAXFLOAT;
|
return MAXFLOAT;
|
||||||
@ -190,7 +190,7 @@ float IntersectTriangle (in SRay theRay,
|
|||||||
|
|
||||||
theNorm = cross (aEdge1, aEdge0);
|
theNorm = cross (aEdge1, aEdge0);
|
||||||
|
|
||||||
vec3 aEdge2 = (1.f / dot (theNorm, theRay.Direct)) * (thePnt0 - theRay.Origin);
|
vec3 aEdge2 = (1.0f / dot (theNorm, theRay.Direct)) * (thePnt0 - theRay.Origin);
|
||||||
|
|
||||||
float aTime = dot (theNorm, aEdge2);
|
float aTime = dot (theNorm, aEdge2);
|
||||||
|
|
||||||
@ -199,10 +199,10 @@ float IntersectTriangle (in SRay theRay,
|
|||||||
theUV.x = dot (theVec, aEdge1);
|
theUV.x = dot (theVec, aEdge1);
|
||||||
theUV.y = dot (theVec, aEdge0);
|
theUV.y = dot (theVec, aEdge0);
|
||||||
|
|
||||||
return bool (int(aTime >= 0.f) &
|
return bool (int(aTime >= 0.0f) &
|
||||||
int(theUV.x >= 0.f) &
|
int(theUV.x >= 0.0f) &
|
||||||
int(theUV.y >= 0.f) &
|
int(theUV.y >= 0.0f) &
|
||||||
int(theUV.x + theUV.y <= 1.f)) ? aTime : MAXFLOAT;
|
int(theUV.x + theUV.y <= 1.0f)) ? aTime : MAXFLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Identifies the absence of intersection.
|
//! Identifies the absence of intersection.
|
||||||
@ -250,7 +250,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeLft <= theHit.Time);
|
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeLft <= theHit.Time);
|
||||||
|
|
||||||
aTimeMax = max (aTime0, aTime1);
|
aTimeMax = max (aTime0, aTime1);
|
||||||
aTimeMin = min (aTime0, aTime1);
|
aTimeMin = min (aTime0, aTime1);
|
||||||
@ -258,7 +258,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeRgh <= theHit.Time);
|
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeRgh <= theHit.Time);
|
||||||
|
|
||||||
if (bool(aHitLft & aHitRgh))
|
if (bool(aHitLft & aHitRgh))
|
||||||
{
|
{
|
||||||
@ -356,7 +356,7 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeLft <= theDistance);
|
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeLft <= theDistance);
|
||||||
|
|
||||||
aTimeMax = max (aTime0, aTime1);
|
aTimeMax = max (aTime0, aTime1);
|
||||||
aTimeMin = min (aTime0, aTime1);
|
aTimeMin = min (aTime0, aTime1);
|
||||||
@ -364,7 +364,7 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeRgh <= theDistance);
|
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeRgh <= theDistance);
|
||||||
|
|
||||||
if (bool(aHitLft & aHitRgh))
|
if (bool(aHitLft & aHitRgh))
|
||||||
{
|
{
|
||||||
@ -381,7 +381,7 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aHead == theSentinel)
|
if (aHead == theSentinel)
|
||||||
return 1.f;
|
return 1.0f;
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
@ -408,17 +408,17 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
aNormal);
|
aNormal);
|
||||||
|
|
||||||
if (aTime < theDistance)
|
if (aTime < theDistance)
|
||||||
return 0.f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aHead == theSentinel)
|
if (aHead == theSentinel)
|
||||||
return 1.f;
|
return 1.0f;
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1.f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -461,17 +461,17 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
|||||||
|
|
||||||
SRay aNewRay;
|
SRay aNewRay;
|
||||||
|
|
||||||
aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.f),
|
aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.0f),
|
||||||
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
||||||
|
|
||||||
aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.f),
|
aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.0f),
|
||||||
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
||||||
|
|
||||||
vec3 aNewInverse = 1.f / max (abs (aNewRay.Direct), SMALL);
|
vec3 aNewInverse = 1.0f / max (abs (aNewRay.Direct), SMALL);
|
||||||
|
|
||||||
aNewInverse.x = aNewRay.Direct.x < 0.f ? -aNewInverse.x : aNewInverse.x;
|
aNewInverse.x = aNewRay.Direct.x < 0.0f ? -aNewInverse.x : aNewInverse.x;
|
||||||
aNewInverse.y = aNewRay.Direct.y < 0.f ? -aNewInverse.y : aNewInverse.y;
|
aNewInverse.y = aNewRay.Direct.y < 0.0f ? -aNewInverse.y : aNewInverse.y;
|
||||||
aNewInverse.z = aNewRay.Direct.z < 0.f ? -aNewInverse.z : aNewInverse.z;
|
aNewInverse.z = aNewRay.Direct.z < 0.0f ? -aNewInverse.z : aNewInverse.z;
|
||||||
|
|
||||||
ivec4 aTriIndex = ObjectNearestHit (
|
ivec4 aTriIndex = ObjectNearestHit (
|
||||||
aData.y, aData.z, aData.w, aNewRay, aNewInverse, theHit, aHead);
|
aData.y, aData.z, aData.w, aNewRay, aNewInverse, theHit, aHead);
|
||||||
@ -508,7 +508,7 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeLft <= theHit.Time);
|
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeLft <= theHit.Time);
|
||||||
|
|
||||||
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
|
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
|
||||||
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
|
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
|
||||||
@ -519,7 +519,7 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeRgh <= theHit.Time);
|
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeRgh <= theHit.Time);
|
||||||
|
|
||||||
if (bool(aHitLft & aHitRgh))
|
if (bool(aHitLft & aHitRgh))
|
||||||
{
|
{
|
||||||
@ -575,23 +575,23 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
|
|
||||||
SRay aNewRay;
|
SRay aNewRay;
|
||||||
|
|
||||||
aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.f),
|
aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.0f),
|
||||||
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
||||||
|
|
||||||
aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.f),
|
aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.0f),
|
||||||
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
||||||
|
|
||||||
vec3 aNewInverse = 1.f / max (abs (aNewRay.Direct), SMALL);
|
vec3 aNewInverse = 1.0f / max (abs (aNewRay.Direct), SMALL);
|
||||||
|
|
||||||
aNewInverse.x = aNewRay.Direct.x < 0.f ? -aNewInverse.x : aNewInverse.x;
|
aNewInverse.x = aNewRay.Direct.x < 0.0f ? -aNewInverse.x : aNewInverse.x;
|
||||||
aNewInverse.y = aNewRay.Direct.y < 0.f ? -aNewInverse.y : aNewInverse.y;
|
aNewInverse.y = aNewRay.Direct.y < 0.0f ? -aNewInverse.y : aNewInverse.y;
|
||||||
aNewInverse.z = aNewRay.Direct.z < 0.f ? -aNewInverse.z : aNewInverse.z;
|
aNewInverse.z = aNewRay.Direct.z < 0.0f ? -aNewInverse.z : aNewInverse.z;
|
||||||
|
|
||||||
bool isShadow = 0.f == ObjectAnyHit (
|
bool isShadow = 0.0f == ObjectAnyHit (
|
||||||
aData.y, aData.z, aData.w, aNewRay, aNewInverse, theDistance, aHead);
|
aData.y, aData.z, aData.w, aNewRay, aNewInverse, theDistance, aHead);
|
||||||
|
|
||||||
if (aHead < 0 || isShadow)
|
if (aHead < 0 || isShadow)
|
||||||
return isShadow ? 0.f : 1.f;
|
return isShadow ? 0.0f : 1.0f;
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
@ -611,7 +611,7 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeLft <= theDistance);
|
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeLft <= theDistance);
|
||||||
|
|
||||||
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
|
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
|
||||||
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
|
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
|
||||||
@ -622,7 +622,7 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
|
||||||
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
|
||||||
|
|
||||||
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.f) & int(aTimeRgh <= theDistance);
|
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeRgh <= theDistance);
|
||||||
|
|
||||||
if (bool(aHitLft & aHitRgh))
|
if (bool(aHitLft & aHitRgh))
|
||||||
{
|
{
|
||||||
@ -639,7 +639,7 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aHead < 0)
|
if (aHead < 0)
|
||||||
return 1.f;
|
return 1.0f;
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
@ -647,7 +647,7 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1.f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PI 3.1415926f
|
#define PI 3.1415926f
|
||||||
@ -678,7 +678,35 @@ vec3 SmoothNormal (in vec2 theUV, in ivec4 theTriangle)
|
|||||||
|
|
||||||
return normalize (aNormal1 * theUV.x +
|
return normalize (aNormal1 * theUV.x +
|
||||||
aNormal2 * theUV.y +
|
aNormal2 * theUV.y +
|
||||||
aNormal0 * (1.f - theUV.x - theUV.y));
|
aNormal0 * (1.0f - theUV.x - theUV.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Refract
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
vec3 Refract (in vec3 theInput,
|
||||||
|
in vec3 theNormal,
|
||||||
|
in float theRefractIndex,
|
||||||
|
in float theInvRefractIndex)
|
||||||
|
{
|
||||||
|
float aNdotI = dot (theInput, theNormal);
|
||||||
|
|
||||||
|
float anIndex = aNdotI < 0.0f
|
||||||
|
? theInvRefractIndex
|
||||||
|
: theRefractIndex;
|
||||||
|
|
||||||
|
float aSquare = anIndex * anIndex * (1.0f - aNdotI * aNdotI);
|
||||||
|
|
||||||
|
if (aSquare > 1.0f)
|
||||||
|
{
|
||||||
|
return reflect (theInput, theNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
float aNdotT = sqrt (1.0f - aSquare);
|
||||||
|
|
||||||
|
return normalize (anIndex * theInput -
|
||||||
|
(anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define THRESHOLD vec3 (0.1f, 0.1f, 0.1f)
|
#define THRESHOLD vec3 (0.1f, 0.1f, 0.1f)
|
||||||
@ -700,8 +728,8 @@ vec3 SmoothNormal (in vec2 theUV, in ivec4 theTriangle)
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||||
{
|
{
|
||||||
vec3 aResult = vec3 (0.f);
|
vec3 aResult = vec3 (0.0f);
|
||||||
vec4 aWeight = vec4 (1.f);
|
vec4 aWeight = vec4 (1.0f);
|
||||||
|
|
||||||
int anObjectId;
|
int anObjectId;
|
||||||
|
|
||||||
@ -713,7 +741,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
|
|
||||||
if (aTriIndex.x == -1)
|
if (aTriIndex.x == -1)
|
||||||
{
|
{
|
||||||
if (aWeight.w != 0.f)
|
if (aWeight.w != 0.0f)
|
||||||
{
|
{
|
||||||
return vec4 (aResult.x,
|
return vec4 (aResult.x,
|
||||||
aResult.y,
|
aResult.y,
|
||||||
@ -726,7 +754,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
float aTime = IntersectSphere (theRay, uSceneRadius);
|
float aTime = IntersectSphere (theRay, uSceneRadius);
|
||||||
|
|
||||||
aResult.xyz += aWeight.xyz * textureLod (uEnvironmentMapTexture,
|
aResult.xyz += aWeight.xyz * textureLod (uEnvironmentMapTexture,
|
||||||
Latlong (theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.f).xyz;
|
Latlong (theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.0f).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4 (aResult.x,
|
return vec4 (aResult.x,
|
||||||
@ -737,14 +765,14 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
|
|
||||||
vec3 aPoint = theRay.Direct * aHit.Time + theRay.Origin;
|
vec3 aPoint = theRay.Direct * aHit.Time + theRay.Origin;
|
||||||
|
|
||||||
vec3 aAmbient = vec3 (texelFetch (
|
vec3 aAmbient = texelFetch (
|
||||||
uRaytraceMaterialTexture, MATERIAL_AMBN (aTriIndex.w)));
|
uRaytraceMaterialTexture, MATERIAL_AMBN (aTriIndex.w)).rgb;
|
||||||
vec3 aDiffuse = vec3 (texelFetch (
|
vec3 aDiffuse = texelFetch (
|
||||||
uRaytraceMaterialTexture, MATERIAL_DIFF (aTriIndex.w)));
|
uRaytraceMaterialTexture, MATERIAL_DIFF (aTriIndex.w)).rgb;
|
||||||
vec4 aSpecular = vec4 (texelFetch (
|
vec4 aSpecular = texelFetch (
|
||||||
uRaytraceMaterialTexture, MATERIAL_SPEC (aTriIndex.w)));
|
uRaytraceMaterialTexture, MATERIAL_SPEC (aTriIndex.w));
|
||||||
vec2 aOpacity = vec2 (texelFetch (
|
vec4 aOpacity = texelFetch (
|
||||||
uRaytraceMaterialTexture, MATERIAL_TRAN (aTriIndex.w)));
|
uRaytraceMaterialTexture, MATERIAL_TRAN (aTriIndex.w));
|
||||||
|
|
||||||
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
|
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
|
||||||
|
|
||||||
@ -753,7 +781,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
|
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
|
||||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
|
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
|
||||||
|
|
||||||
aNormal = MatrixRowMultiply (vec4 (aNormal, 0.f), aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
aNormal = MatrixRowMultiply (vec4 (aNormal, 0.0f), aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3);
|
||||||
aNormal = normalize (aNormal);
|
aNormal = normalize (aNormal);
|
||||||
|
|
||||||
aHit.Normal = normalize (aHit.Normal);
|
aHit.Normal = normalize (aHit.Normal);
|
||||||
@ -765,47 +793,47 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
|
|
||||||
float aDistance = MAXFLOAT;
|
float aDistance = MAXFLOAT;
|
||||||
|
|
||||||
if (aLight.w != 0.f) // point light source
|
if (aLight.w != 0.0f) // point light source
|
||||||
{
|
{
|
||||||
aDistance = length (aLight.xyz -= aPoint);
|
aDistance = length (aLight.xyz -= aPoint);
|
||||||
|
|
||||||
aLight.xyz *= 1.f / aDistance;
|
aLight.xyz *= 1.0f / aDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRay aShadow = SRay (aPoint + aLight.xyz * uSceneEpsilon, aLight.xyz);
|
SRay aShadow = SRay (aPoint + aLight.xyz * uSceneEpsilon, aLight.xyz);
|
||||||
|
|
||||||
aShadow.Origin += aHit.Normal * uSceneEpsilon *
|
aShadow.Origin += aHit.Normal * uSceneEpsilon *
|
||||||
(dot (aHit.Normal, aLight.xyz) >= 0.f ? 1.f : -1.f);
|
(dot (aHit.Normal, aLight.xyz) >= 0.0f ? 1.0f : -1.0f);
|
||||||
|
|
||||||
float aVisibility = 1.f;
|
float aVisibility = 1.0f;
|
||||||
|
|
||||||
if (bool(uShadowsEnable))
|
if (bool(uShadowsEnable))
|
||||||
{
|
{
|
||||||
vec3 aInverse = 1.f / max (abs (aLight.xyz), SMALL);
|
vec3 aInverse = 1.0f / max (abs (aLight.xyz), SMALL);
|
||||||
|
|
||||||
aInverse.x = aLight.x < 0.f ? -aInverse.x : aInverse.x;
|
aInverse.x = aLight.x < 0.0f ? -aInverse.x : aInverse.x;
|
||||||
aInverse.y = aLight.y < 0.f ? -aInverse.y : aInverse.y;
|
aInverse.y = aLight.y < 0.0f ? -aInverse.y : aInverse.y;
|
||||||
aInverse.z = aLight.z < 0.f ? -aInverse.z : aInverse.z;
|
aInverse.z = aLight.z < 0.0f ? -aInverse.z : aInverse.z;
|
||||||
|
|
||||||
aVisibility = SceneAnyHit (aShadow, aInverse, aDistance);
|
aVisibility = SceneAnyHit (aShadow, aInverse, aDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aVisibility > 0.f)
|
if (aVisibility > 0.0f)
|
||||||
{
|
{
|
||||||
vec3 aIntensity = vec3 (texelFetch (
|
vec3 aIntensity = vec3 (texelFetch (
|
||||||
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx)));
|
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx)));
|
||||||
|
|
||||||
float aLdotN = dot (aShadow.Direct, aNormal);
|
float aLdotN = dot (aShadow.Direct, aNormal);
|
||||||
|
|
||||||
if (aOpacity.y > 0.f) // force two-sided lighting
|
if (aOpacity.y > 0.0f) // force two-sided lighting
|
||||||
aLdotN = abs (aLdotN); // for transparent surfaces
|
aLdotN = abs (aLdotN); // for transparent surfaces
|
||||||
|
|
||||||
if (aLdotN > 0.f)
|
if (aLdotN > 0.0f)
|
||||||
{
|
{
|
||||||
float aRdotV = dot (reflect (aShadow.Direct, aNormal), theRay.Direct);
|
float aRdotV = dot (reflect (aShadow.Direct, aNormal), theRay.Direct);
|
||||||
|
|
||||||
aResult.xyz += aWeight.xyz * aOpacity.x * aIntensity *
|
aResult.xyz += aWeight.xyz * aOpacity.x * aIntensity *
|
||||||
(aDiffuse * aLdotN + aSpecular.xyz * pow (max (0.f, aRdotV), aSpecular.w));
|
(aDiffuse * aLdotN + aSpecular.xyz * pow (max (0.0f, aRdotV), aSpecular.w));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -813,29 +841,39 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
aResult.xyz += aWeight.xyz * uGlobalAmbient.xyz *
|
aResult.xyz += aWeight.xyz * uGlobalAmbient.xyz *
|
||||||
aAmbient * aOpacity.x * max (abs (dot (aNormal, theRay.Direct)), 0.5f);
|
aAmbient * aOpacity.x * max (abs (dot (aNormal, theRay.Direct)), 0.5f);
|
||||||
|
|
||||||
if (aOpacity.x != 1.f)
|
if (aOpacity.x != 1.0f)
|
||||||
{
|
{
|
||||||
aWeight *= aOpacity.y;
|
aWeight *= aOpacity.y;
|
||||||
|
|
||||||
|
theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w);
|
||||||
|
|
||||||
|
theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
|
||||||
|
|
||||||
|
theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
|
||||||
|
theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
|
||||||
|
theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
|
||||||
|
|
||||||
|
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aWeight *= bool(uReflectionsEnable) ?
|
aWeight *= bool(uReflectionsEnable) ?
|
||||||
texelFetch (uRaytraceMaterialTexture, MATERIAL_REFL (aTriIndex.w)) : vec4 (0.f);
|
texelFetch (uRaytraceMaterialTexture, MATERIAL_REFL (aTriIndex.w)) : vec4 (0.0f);
|
||||||
|
|
||||||
theRay.Direct = reflect (theRay.Direct, aNormal);
|
theRay.Direct = reflect (theRay.Direct, aNormal);
|
||||||
|
|
||||||
if (dot (theRay.Direct, aHit.Normal) < 0.f)
|
if (dot (theRay.Direct, aHit.Normal) < 0.0f)
|
||||||
{
|
{
|
||||||
theRay.Direct = reflect (theRay.Direct, aHit.Normal);
|
theRay.Direct = reflect (theRay.Direct, aHit.Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
theInverse = 1.0 / max (abs (theRay.Direct), SMALL);
|
theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
|
||||||
|
|
||||||
theInverse.x = theRay.Direct.x < 0.0 ? -theInverse.x : theInverse.x;
|
theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
|
||||||
theInverse.y = theRay.Direct.y < 0.0 ? -theInverse.y : theInverse.y;
|
theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
|
||||||
theInverse.z = theRay.Direct.z < 0.0 ? -theInverse.z : theInverse.z;
|
theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
|
||||||
|
|
||||||
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.f ? uSceneEpsilon : -uSceneEpsilon);
|
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
|
if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
|
||||||
|
74
tests/v3d/raytrace/refraction
Normal file
74
tests/v3d/raytrace/refraction
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "Ray Tracing - check refraction"
|
||||||
|
puts "========"
|
||||||
|
|
||||||
|
vinit View1
|
||||||
|
vsetdispmode 1
|
||||||
|
vsetgradientbg 180 200 255 180 180 180 2
|
||||||
|
|
||||||
|
box wall1 1 8 8
|
||||||
|
box wall2 1 8 8
|
||||||
|
box wall3 16 8 1
|
||||||
|
|
||||||
|
psphere S1 1.5
|
||||||
|
psphere S2 1.5
|
||||||
|
psphere S3 1.5
|
||||||
|
|
||||||
|
box B1 -1.5 -1.5 -1.5 2.5 2 3
|
||||||
|
box B2 -1.5 -1.5 -1.5 2.5 2 3
|
||||||
|
box B3 -1.5 -1.5 -1.5 2.5 2 3
|
||||||
|
|
||||||
|
vdisplay S1
|
||||||
|
vdisplay S2
|
||||||
|
vdisplay S3
|
||||||
|
|
||||||
|
vdisplay B1
|
||||||
|
vdisplay B2
|
||||||
|
vdisplay B3
|
||||||
|
|
||||||
|
vdisplay wall1
|
||||||
|
vdisplay wall2
|
||||||
|
vdisplay wall3
|
||||||
|
|
||||||
|
vsetlocation S1 2 2 4
|
||||||
|
vsetlocation S2 -2 2 4
|
||||||
|
vsetlocation S3 -6 2 4
|
||||||
|
|
||||||
|
vsetlocation B1 2 6 4
|
||||||
|
vsetlocation B2 -2 6 4
|
||||||
|
vsetlocation B3 -6 6 4
|
||||||
|
|
||||||
|
vsetlocation wall1 -10 0 0
|
||||||
|
vsetlocation wall2 5 0 0
|
||||||
|
vsetlocation wall3 -10 0 -1
|
||||||
|
|
||||||
|
vsetmaterial S1 water
|
||||||
|
vsetmaterial S2 glass
|
||||||
|
vsetmaterial S3 diamond
|
||||||
|
|
||||||
|
vsetmaterial B1 water
|
||||||
|
vsetmaterial B2 glass
|
||||||
|
vsetmaterial B3 diamond
|
||||||
|
|
||||||
|
vsetmaterial wall1 stone
|
||||||
|
vsetmaterial wall2 stone
|
||||||
|
vsetmaterial wall3 stone
|
||||||
|
|
||||||
|
vsetcolor wall1 red
|
||||||
|
vsetcolor wall2 green
|
||||||
|
|
||||||
|
vsettransparency S1 0.8
|
||||||
|
vsettransparency S2 0.8
|
||||||
|
vsettransparency S3 0.8
|
||||||
|
|
||||||
|
vsettransparency B1 0.8
|
||||||
|
vsettransparency B2 0.8
|
||||||
|
vsettransparency B3 0.8
|
||||||
|
|
||||||
|
vright
|
||||||
|
vturnview 0 -0.3 0
|
||||||
|
vfit
|
||||||
|
vlight change 0 pos 1 1 1
|
||||||
|
vlight add directional
|
||||||
|
vraytrace 1
|
||||||
|
vsetraytracemode aa=0 shad=0 refl=0
|
Loading…
x
Reference in New Issue
Block a user