//! Inverse model-view-projection matrix.
uniform mat4 uUnviewMat;
-//! Texture buffer of data records of high-level BVH nodes.
+//! Texture buffer of data records of bottom-level BVH nodes.
uniform isamplerBuffer uSceneNodeInfoTexture;
-//! Texture buffer of minimum points of high-level BVH nodes.
+//! Texture buffer of minimum points of bottom-level BVH nodes.
uniform samplerBuffer uSceneMinPointTexture;
-//! Texture buffer of maximum points of high-level BVH nodes.
+//! Texture buffer of maximum points of bottom-level BVH nodes.
uniform samplerBuffer uSceneMaxPointTexture;
//! Texture buffer of transformations of high-level BVH nodes.
uniform samplerBuffer uSceneTransformTexture;
-//! Texture buffer of data records of bottom-level BVH nodes.
-uniform isamplerBuffer uObjectNodeInfoTexture;
-//! Texture buffer of minimum points of bottom-level BVH nodes.
-uniform samplerBuffer uObjectMinPointTexture;
-//! Texture buffer of maximum points of bottom-level BVH nodes.
-uniform samplerBuffer uObjectMaxPointTexture;
-
//! Texture buffer of vertex coords.
uniform samplerBuffer uGeometryVertexTexture;
//! Texture buffer of vertex normals.
float aDdotD = dot (theRay.Direct, theRay.Direct);
float aDdotO = dot (theRay.Direct, theRay.Origin);
float aOdotO = dot (theRay.Origin, theRay.Origin);
-
+
float aD = aDdotO * aDdotO - aDdotD * (aOdotO - theRadius * theRadius);
-
+
if (aD > 0.0f)
{
float aTime = (sqrt (aD) - aDdotO) * (1.0f / aDdotD);
return aTime > 0.0f ? aTime : MAXFLOAT;
}
-
+
return MAXFLOAT;
}
{
vec3 aEdge0 = thePnt1 - thePnt0;
vec3 aEdge1 = thePnt0 - thePnt2;
-
+
theNorm = cross (aEdge1, aEdge0);
vec3 aEdge2 = (1.0f / dot (theNorm, theRay.Direct)) * (thePnt0 - theRay.Origin);
-
+
float aTime = dot (theNorm, aEdge2);
vec3 theVec = cross (theRay.Direct, aEdge2);
-
+
theUV.x = dot (theVec, aEdge1);
theUV.y = dot (theVec, aEdge0);
-
+
return bool (int(aTime >= 0.0f) &
int(theUV.x >= 0.0f) &
int(theUV.y >= 0.0f) &
ivec4 aTriIndex = INALID_HIT;
- while (true)
+ bool toContinue = true;
+
+ while (toContinue)
{
- ivec3 aData = texelFetch (uObjectNodeInfoTexture, aNode).xyz;
+ ivec3 aData = texelFetch (uSceneNodeInfoTexture, aNode).xyz;
if (aData.x == 0) // if inner node
{
float aTimeOut;
float aTimeLft;
float aTimeRgh;
-
+
aData.y += theBVHOffset;
aData.z += theBVHOffset;
-
- vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y).xyz;
- vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y).xyz;
- vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z).xyz;
- vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z).xyz;
+
+ vec3 aNodeMinLft = texelFetch (uSceneMinPointTexture, aData.y).xyz;
+ vec3 aNodeMinRgh = texelFetch (uSceneMinPointTexture, aData.z).xyz;
+ vec3 aNodeMaxLft = texelFetch (uSceneMaxPointTexture, aData.y).xyz;
+ vec3 aNodeMaxRgh = texelFetch (uSceneMaxPointTexture, aData.z).xyz;
vec3 aTime0 = (aNodeMinLft - theRay.Origin) * theInverse;
vec3 aTime1 = (aNodeMaxLft - theRay.Origin) * theInverse;
-
+
vec3 aTimeMax = max (aTime0, aTime1);
vec3 aTimeMin = min (aTime0, aTime1);
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
-
+
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
if (bool(aHitLft & aHitRgh))
{
aNode = (aTimeLft < aTimeRgh) ? aData.y : aData.z;
-
+
Stack[++aHead] = (aTimeLft < aTimeRgh) ? aData.z : aData.y;
}
else
}
else
{
- if (aHead == theSentinel)
- return aTriIndex;
+ toContinue = (aHead != theSentinel);
- aNode = Stack[aHead--];
+ if (toContinue)
+ aNode = Stack[aHead--];
}
}
}
aPoint2,
aParams,
aNormal);
-
+
if (aTime < theHit.Time)
{
aTriIndex = aTriangle;
theHit = SIntersect (aTime, aParams, aNormal);
}
}
-
- if (aHead == theSentinel)
- return aTriIndex;
- aNode = Stack[aHead--];
+ toContinue = (aHead != theSentinel);
+
+ if (toContinue)
+ aNode = Stack[aHead--];
}
}
while (true)
{
- ivec4 aData = texelFetch (uObjectNodeInfoTexture, aNode);
+ ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
if (aData.x == 0) // if inner node
{
aData.y += theBVHOffset;
aData.z += theBVHOffset;
-
- vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y).xyz;
- vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y).xyz;
- vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z).xyz;
- vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z).xyz;
+
+ vec3 aNodeMinLft = texelFetch (uSceneMinPointTexture, aData.y).xyz;
+ vec3 aNodeMaxLft = texelFetch (uSceneMaxPointTexture, aData.y).xyz;
+ vec3 aNodeMinRgh = texelFetch (uSceneMinPointTexture, aData.z).xyz;
+ vec3 aNodeMaxRgh = texelFetch (uSceneMaxPointTexture, aData.z).xyz;
vec3 aTime0 = (aNodeMinLft - theRay.Origin) * theInverse;
vec3 aTime1 = (aNodeMaxLft - theRay.Origin) * theInverse;
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
-
+
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), SMALL);
- aTrsfInverse.x = aTrsfRay.Direct.x < 0.f ? -aTrsfInverse.x : aTrsfInverse.x;
- aTrsfInverse.y = aTrsfRay.Direct.y < 0.f ? -aTrsfInverse.y : aTrsfInverse.y;
- aTrsfInverse.z = aTrsfRay.Direct.z < 0.f ? -aTrsfInverse.z : aTrsfInverse.z;
+ aTrsfInverse = mix (-aTrsfInverse, aTrsfInverse, step (ZERO, aTrsfRay.Direct));
ivec4 aTriIndex = ObjectNearestHit (
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theHit, aHead);
theObjectId = anObjectId;
}
}
-
+
if (aHead < 0)
return aHitObject;
aTimeLft = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
int aHitLft = int(aTimeLft <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeLft <= theHit.Time);
-
+
aTime0 = (aNodeMinRgh - theRay.Origin) * theInverse;
aTime1 = (aNodeMaxRgh - theRay.Origin) * theInverse;
aTimeOut = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
aTimeRgh = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
-
+
int aHitRgh = int(aTimeRgh <= aTimeOut) & int(aTimeOut >= 0.0f) & int(aTimeRgh <= theHit.Time);
if (bool(aHitLft & aHitRgh))
}
}
}
-
+
return aHitObject;
}
vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), SMALL);
- aTrsfInverse.x = aTrsfRay.Direct.x < 0.0f ? -aTrsfInverse.x : aTrsfInverse.x;
- aTrsfInverse.y = aTrsfRay.Direct.y < 0.0f ? -aTrsfInverse.y : aTrsfInverse.y;
- aTrsfInverse.z = aTrsfRay.Direct.z < 0.0f ? -aTrsfInverse.z : aTrsfInverse.z;
+ aTrsfInverse = mix (-aTrsfInverse, aTrsfInverse, step (ZERO, aTrsfRay.Direct));
#ifdef TRANSPARENT_SHADOWS
aFactor *= ObjectAnyHit (
{
vec4 aLight = texelFetch (
uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
-
+
float aDistance = MAXFLOAT;
-
+
if (aLight.w != 0.0f) // point light source
{
aDistance = length (aLight.xyz -= aPoint);
-
+
aLight.xyz *= 1.0f / aDistance;
}
SRay aShadow = SRay (aPoint + aLight.xyz * uSceneEpsilon, aLight.xyz);
-
+
aShadow.Origin += aHit.Normal * uSceneEpsilon *
(dot (aHit.Normal, aLight.xyz) >= 0.0f ? 1.0f : -1.0f);
-
+
float aVisibility = 1.0f;
-
+
if (bool(uShadowsEnable))
{
vec3 aInverse = 1.0f / max (abs (aLight.xyz), SMALL);
- aInverse.x = aLight.x < 0.0f ? -aInverse.x : aInverse.x;
- aInverse.y = aLight.y < 0.0f ? -aInverse.y : aInverse.y;
- aInverse.z = aLight.z < 0.0f ? -aInverse.z : aInverse.z;
-
- aVisibility = SceneAnyHit (aShadow, aInverse, aDistance);
+ aVisibility = SceneAnyHit (
+ aShadow, mix (-aInverse, aInverse, step (ZERO, aLight.xyz)), aDistance);
}
-
+
if (aVisibility > 0.0f)
{
vec3 aIntensity = vec3 (texelFetch (
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;
+ theInverse = mix (-theInverse, theInverse, step (ZERO, theRay.Direct));
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
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;
+ theInverse = mix (-theInverse, theInverse, step (ZERO, theRay.Direct));
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);