mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0024819: TKOpenGl - extend the ray-tracing core by visualization of lines, text and point sprites
OpenGl_GraphicDriver::Redraw() - do not recompute structures more than required OpenGl_Workspace::Raytrace() - bind proper FBO before clearing it Visual3d_View::Redraw() - perform automatic 2nd redraw on device lost
This commit is contained in:
@@ -19,6 +19,8 @@ uniform vec3 uDirectRT;
|
||||
//! Direction of viewing ray in right-bottom corner.
|
||||
uniform vec3 uDirectRB;
|
||||
|
||||
//! Inverse model-view-projection matrix.
|
||||
uniform mat4 uInvModelProj;
|
||||
//! Texture buffer of data records of high-level BVH nodes.
|
||||
uniform isamplerBuffer uSceneNodeInfoTexture;
|
||||
//! Texture buffer of minimum points of high-level BVH nodes.
|
||||
@@ -49,6 +51,11 @@ uniform samplerBuffer uRaytraceLightSrcTexture;
|
||||
//! Environment map texture.
|
||||
uniform sampler2D uEnvironmentMapTexture;
|
||||
|
||||
//! Input pre-raytracing image rendered by OpenGL.
|
||||
uniform sampler2D uOpenGlColorTexture;
|
||||
//! Input pre-raytracing depth image rendered by OpenGL.
|
||||
uniform sampler2D uOpenGlDepthTexture;
|
||||
|
||||
//! Total number of light sources.
|
||||
uniform int uLightCount;
|
||||
//! Intensity of global ambient light.
|
||||
@@ -160,9 +167,44 @@ SRay GenerateRay (in vec2 thePixel)
|
||||
|
||||
vec3 aD0 = mix (uDirectLB, uDirectRB, thePixel.x);
|
||||
vec3 aD1 = mix (uDirectLT, uDirectRT, thePixel.x);
|
||||
|
||||
return SRay (mix (aP0, aP1, thePixel.y),
|
||||
mix (aD0, aD1, thePixel.y));
|
||||
|
||||
vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));
|
||||
|
||||
return SRay (mix (aP0, aP1, thePixel.y), aDirection);
|
||||
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ComputeOpenGlDepth
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float ComputeOpenGlDepth (in SRay theRay)
|
||||
{
|
||||
// a depth in range [0,1]
|
||||
float anOpenGlDepth = texelFetch (uOpenGlDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
|
||||
// pixel point in NDC-space [-1,1]
|
||||
vec4 aPoint = vec4 (2.0f * vPixel.x - 1.0f,
|
||||
2.0f * vPixel.y - 1.0f,
|
||||
2.0f * anOpenGlDepth - 1.0f,
|
||||
1.0f);
|
||||
vec4 aFinal = uInvModelProj * aPoint;
|
||||
aFinal.xyz *= 1.f / aFinal.w;
|
||||
|
||||
return (anOpenGlDepth < 1.f) ? length (aFinal.xyz - theRay.Origin) : MAXFLOAT;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ComputeOpenGlColor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
vec4 ComputeOpenGlColor (in SRay theRay)
|
||||
{
|
||||
vec4 anOpenGlColor = texelFetch (uOpenGlColorTexture, ivec2 (gl_FragCoord.xy), 0);
|
||||
// During blending with factors GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA (for text and markers)
|
||||
// the alpha channel (written in the color buffer) was squared.
|
||||
anOpenGlColor.a = 1.f - sqrt (anOpenGlColor.a);
|
||||
|
||||
return anOpenGlColor;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -320,7 +362,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
|
||||
if (aTime < theHit.Time)
|
||||
{
|
||||
aTriIndex = aTriangle;
|
||||
|
||||
|
||||
theHit = SIntersect (aTime, aParams, aNormal);
|
||||
}
|
||||
}
|
||||
@@ -776,6 +818,9 @@ vec3 Refract (in vec3 theInput,
|
||||
(anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
|
||||
}
|
||||
|
||||
#define MIN_SLOPE 0.0001f
|
||||
#define EPS_SCALE 8.0000f
|
||||
|
||||
#define THRESHOLD vec3 (0.1f)
|
||||
|
||||
#define LIGHT_POS(index) (2 * index + 1)
|
||||
@@ -791,17 +836,27 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
vec4 aWeight = vec4 (1.0f);
|
||||
|
||||
int anObjectId;
|
||||
|
||||
|
||||
float anOpenGlDepth = ComputeOpenGlDepth (theRay);
|
||||
|
||||
vec3 aViewDir = theRay.Direct;
|
||||
|
||||
for (int aDepth = 0; aDepth < TRACE_DEPTH; ++aDepth)
|
||||
{
|
||||
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
|
||||
|
||||
|
||||
ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, anObjectId);
|
||||
|
||||
if (aTriIndex.x == -1)
|
||||
{
|
||||
if (aWeight.w != 0.0f)
|
||||
{
|
||||
if (anOpenGlDepth < MAXFLOAT)
|
||||
{
|
||||
vec4 anOpenGlColor = ComputeOpenGlColor (theRay);
|
||||
aResult.xyz += aWeight.xyz * anOpenGlColor.xyz;
|
||||
aWeight.w *= anOpenGlColor.w;
|
||||
}
|
||||
return vec4 (aResult.x,
|
||||
aResult.y,
|
||||
aResult.z,
|
||||
@@ -821,7 +876,36 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
aResult.z,
|
||||
aWeight.w);
|
||||
}
|
||||
|
||||
aHit.Normal = normalize (aHit.Normal);
|
||||
|
||||
if (anOpenGlDepth != MAXFLOAT)
|
||||
{
|
||||
float aDepthSlope = dot (theRay.Direct, aHit.Normal);
|
||||
|
||||
// For polygons that are parallel to the screen plane, the depth slope
|
||||
// is equal to 1, resulting in small polygon offset. For polygons that
|
||||
// that are at a large angle to the screen, the depth slope tends to 1,
|
||||
// resulting in a larger polygon offset
|
||||
float aPolygonOffset = uSceneEpsilon * EPS_SCALE / max (MIN_SLOPE, abs (aDepthSlope));
|
||||
|
||||
if (anOpenGlDepth - aPolygonOffset < aHit.Time)
|
||||
{
|
||||
vec4 aColor = ComputeOpenGlColor (theRay);
|
||||
|
||||
aResult.xyz += aWeight.xyz * aColor.xyz;
|
||||
aWeight *= aColor.w;
|
||||
|
||||
if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
|
||||
{
|
||||
return vec4 (aResult.x,
|
||||
aResult.y,
|
||||
aResult.z,
|
||||
aWeight.w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec3 aPoint = theRay.Direct * aHit.Time + theRay.Origin;
|
||||
|
||||
vec3 aAmbient = texelFetch (
|
||||
@@ -841,9 +925,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
|
||||
aNormal = normalize (MatrixRowMultiplyDir (
|
||||
aNormal, aInvTransf0, aInvTransf1, aInvTransf2));
|
||||
|
||||
aHit.Normal = normalize (aHit.Normal);
|
||||
|
||||
|
||||
for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)
|
||||
{
|
||||
vec4 aLight = texelFetch (
|
||||
@@ -902,18 +984,25 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
if (aOpacity.x != 1.0f)
|
||||
{
|
||||
aWeight *= aOpacity.y;
|
||||
|
||||
|
||||
if (aOpacity.z != 1.0f)
|
||||
{
|
||||
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);
|
||||
|
||||
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
|
||||
|
||||
// Disable combining image with OpenGL output
|
||||
anOpenGlDepth = MAXFLOAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
anOpenGlDepth -= aHit.Time + uSceneEpsilon;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -925,7 +1014,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
|
||||
if (dot (theRay.Direct, aHit.Normal) < 0.0f)
|
||||
{
|
||||
theRay.Direct = reflect (theRay.Direct, aHit.Normal);
|
||||
theRay.Direct = reflect (theRay.Direct, aHit.Normal);
|
||||
}
|
||||
|
||||
theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
|
||||
@@ -935,6 +1024,9 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
|
||||
|
||||
aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
|
||||
|
||||
// Disable combining image with OpenGL output
|
||||
anOpenGlDepth = MAXFLOAT;
|
||||
}
|
||||
|
||||
if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
|
||||
|
Reference in New Issue
Block a user