Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ApplicationExeCode/Resources/vs_2dTextureCellFace.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,8 @@ void main()
v_ecNormal = cvfu_normalMatrix * cvfa_normal;

gl_Position = cvfu_modelViewProjectionMatrix*cvfa_vertex;
#ifdef CVF_LOG_DEPTH_IMPL
calcLogDepth(gl_Position);
#endif
}

3 changes: 3 additions & 0 deletions ApplicationExeCode/Resources/vs_CellFace.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,8 @@ void main()
v_ecNormal = cvfu_normalMatrix * cvfa_normal;

gl_Position = cvfu_modelViewProjectionMatrix*cvfa_vertex;
#ifdef CVF_LOG_DEPTH_IMPL
calcLogDepth(gl_Position);
#endif
}

Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#include "cvfRenderState_FF.h"
#include "cvfStructGridGeometryGenerator.h"
#include "cvfTransform.h"
#include "cvfUniform.h"
#include "cvfqtUtils.h"

#include <functional>
Expand Down Expand Up @@ -711,12 +712,14 @@ void RivExtrudedCurveIntersectionPartMgr::createAnnotationSurfaceParts( bool use
// The factor value is defined by enums in
// EffectGenerator::createAndConfigurePolygonOffsetRenderState() Use a factor that is more negative
// than the existing enums
const double offsetFactor = -5;
const float offsetFactor = -5.0f;
const float offsetUnits = static_cast<float>( band->polygonOffsetUnit() );
polyOffset->setFactor( offsetFactor );

polyOffset->setUnits( band->polygonOffsetUnit() );
polyOffset->setUnits( offsetUnits );

geometryOnlyEffect->setRenderState( polyOffset.p() );
geometryOnlyEffect->setUniform( new cvf::UniformFloat( "u_polygonOffsetFactor", offsetFactor ) );
geometryOnlyEffect->setUniform( new cvf::UniformFloat( "u_polygonOffsetUnits", offsetUnits ) );
}

part->setEffect( geometryOnlyEffect.p() );
Expand Down Expand Up @@ -759,11 +762,14 @@ cvf::ref<cvf::Part> RivExtrudedCurveIntersectionPartMgr::createCurvePart( const

cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->enableFillMode( true );
polyOffset->setFactor( -5 );
const double maxOffsetFactor = -1000;
polyOffset->setUnits( maxOffsetFactor );
const float lineFactor = -5.0f;
const float lineUnits = -1000.0f;
polyOffset->setFactor( lineFactor );
polyOffset->setUnits( lineUnits );

eff->setRenderState( polyOffset.p() );
eff->setUniform( new cvf::UniformFloat( "u_polygonOffsetFactor", lineFactor ) );
eff->setUniform( new cvf::UniformFloat( "u_polygonOffsetUnits", lineUnits ) );

part->setEffect( eff.p() );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,8 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering( cvf::Effect* effect
texBind->addBinding( cellTexture.p(), sampler.p(), "u_cellTexture2D" );
eff->setRenderState( texBind.p() );

// Polygon offset

{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->configurePolygonPositiveOffset();
eff->setRenderState( polyOffset.p() );
}
// Polygon offset (render state + shader uniforms for log-depth compatibility)
EffectGenerator::applyPolygonOffset( eff.p(), caf::PO_1 );

// Simple transparency
if ( m_opacityLevel < 1.0f )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,7 @@ void RivTernaryScalarMapperEffectGenerator::updateCommonEffect( cvf::Effect* eff
{
CVF_ASSERT( effect );

if ( m_polygonOffset != caf::PO_NONE )
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState( m_polygonOffset );
effect->setRenderState( polyOffset.p() );
}
EffectGenerator::applyPolygonOffset( effect, m_polygonOffset );

// Simple transparency
if ( m_opacityLevel < 1.0f )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "cvfModelBasicList.h"
#include "cvfPart.h"
#include "cvfScalarMapper.h"
#include "cvfUniform.h"

#include <zgyaccess/seismicslice.h>

Expand Down Expand Up @@ -243,11 +244,14 @@ void RivSeismicSectionPartMgr::appendSurfaceIntersectionLines( cvf::ModelBasicLi

cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->enableFillMode( true );
polyOffset->setFactor( -5 );
const double maxOffsetFactor = -1000;
polyOffset->setUnits( maxOffsetFactor );
const float lineFactor = -5.0f;
const float lineUnits = -1000.0f;
polyOffset->setFactor( lineFactor );
polyOffset->setUnits( lineUnits );

eff->setRenderState( polyOffset.p() );
eff->setUniform( new cvf::UniformFloat( "u_polygonOffsetFactor", lineFactor ) );
eff->setUniform( new cvf::UniformFloat( "u_polygonOffsetUnits", lineUnits ) );

part->setEffect( eff.p() );
part->setPriority( RivPartPriority::PartType::MeshLines );
Expand Down
52 changes: 40 additions & 12 deletions Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,44 @@ cvf::ref<cvf::RenderStatePolygonOffset>
return rs;
}

//--------------------------------------------------------------------------------------------------
/// Sets both the GL polygon offset render state and the equivalent shader uniforms.
/// glPolygonOffset has no effect when gl_FragDepth is written explicitly (as in log-depth
/// rendering), so the uniforms are required for correct depth ordering in that mode.
//--------------------------------------------------------------------------------------------------
void EffectGenerator::applyPolygonOffset( cvf::Effect* effect, PolygonOffset polygonOffset )
{
if ( polygonOffset == PO_NONE ) return;

effect->setRenderState( createAndConfigurePolygonOffsetRenderState( polygonOffset ).p() );

float factor = 0.0f, units = 0.0f;
switch ( polygonOffset )
{
case PO_1:
factor = 1.0f;
units = 1.0f;
break;
case PO_2:
factor = 2.0f;
units = 2.0f;
break;
case PO_POS_LARGE:
factor = 3.0f;
units = 50.0f;
break;
case PO_NEG_LARGE:
factor = -1.0f;
units = -30.0f;
break;
default:
CVF_FAIL_MSG( "Unhandled polygon offset enum" );
return;
}
effect->setUniform( new cvf::UniformFloat( "u_polygonOffsetFactor", factor ) );
effect->setUniform( new cvf::UniformFloat( "u_polygonOffsetUnits", units ) );
}

//==================================================================================================
//
// EffectGenerator Base class
Expand Down Expand Up @@ -347,12 +385,7 @@ void SurfaceEffectGenerator::updateForFixedFunctionRendering( cvf::Effect* effec
//--------------------------------------------------------------------------------------------------
void SurfaceEffectGenerator::updateCommonEffect( cvf::Effect* effect ) const
{
if ( m_polygonOffset != PO_NONE )
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset =
EffectGenerator::createAndConfigurePolygonOffsetRenderState( m_polygonOffset );
effect->setRenderState( polyOffset.p() );
}
EffectGenerator::applyPolygonOffset( effect, m_polygonOffset );

// Simple transparency
if ( m_color.a() < 1.0f )
Expand Down Expand Up @@ -553,12 +586,7 @@ void ScalarMapperEffectGenerator::updateCommonEffect( cvf::Effect* effect ) cons
{
CVF_ASSERT( effect );

if ( m_polygonOffset != PO_NONE )
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset =
EffectGenerator::createAndConfigurePolygonOffsetRenderState( m_polygonOffset );
effect->setRenderState( polyOffset.p() );
}
EffectGenerator::applyPolygonOffset( effect, m_polygonOffset );

// Simple transparency
if ( m_opacityLevel < 1.0f )
Expand Down
4 changes: 4 additions & 0 deletions Fwk/AppFwk/CommonCode/cafEffectGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ class EffectGenerator
static cvf::ref<cvf::RenderStatePolygonOffset>
createAndConfigurePolygonOffsetRenderState( caf::PolygonOffset polygonOffset );

// Sets both the GL polygon offset render state and the shader uniforms needed for log-depth
// rendering (glPolygonOffset is ignored when gl_FragDepth is written explicitly).
static void applyPolygonOffset( cvf::Effect* effect, caf::PolygonOffset polygonOffset );

protected:
// Interface that must be implemented in base classes
virtual bool isEqual( const EffectGenerator* other ) const = 0;
Expand Down
93 changes: 73 additions & 20 deletions Fwk/AppFwk/cafViewer/cafViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,12 @@ class GlobalViewerDynUniformSet : public cvf::DynamicUniformSet
GlobalViewerDynUniformSet()
{
m_headlightPosition = new cvf::UniformFloat( "u_ecLightPosition", cvf::Vec3f( 0.5, 5.0, 7.0 ) );
m_logDepthFC = new cvf::UniformFloat( "u_logDepthFC", 1.0f );
m_useLogDepth = new cvf::UniformFloat( "u_useLogDepth", 1.0f );
m_uniformSet = new cvf::UniformSet();
m_uniformSet->setUniform( m_headlightPosition.p() );
m_uniformSet->setUniform( m_logDepthFC.p() );
m_uniformSet->setUniform( m_useLogDepth.p() );
}

~GlobalViewerDynUniformSet() override {}
Expand All @@ -97,12 +101,20 @@ class GlobalViewerDynUniformSet : public cvf::DynamicUniformSet
m_headlightPosition->set( posRelativeToCamera );
}

// FC = 2.0 / log2(farPlane + 1.0) — update each frame after clip plane calculation
void setLogDepthFarConstant( float fc ) { m_logDepthFC->set( fc ); }

// Enable (1.0) for perspective projection, disable (0.0) for orthographic
void setUseLogDepth( float use ) { m_useLogDepth->set( use ); }

cvf::UniformSet* uniformSet() override { return m_uniformSet.p(); }
void update( cvf::Rendering* rendering ) override {};

private:
cvf::ref<cvf::UniformSet> m_uniformSet;
cvf::ref<cvf::UniformFloat> m_headlightPosition;
cvf::ref<cvf::UniformFloat> m_logDepthFC;
cvf::ref<cvf::UniformFloat> m_useLogDepth;
};

} // namespace caf
Expand Down Expand Up @@ -468,6 +480,14 @@ void caf::Viewer::optimizeClippingPlanes()
{
m_mainCamera->setProjectionAsOrtho( m_mainCamera->frontPlaneFrustumHeight(), nearPlaneDist, farPlaneDist );
}

// Update the logarithmic depth buffer constant: FC = 2 / log2(far + 1).
// Shaders use this to compute gl_FragDepth = log2(v_logz) * FC * 0.5.
// Log depth only works for perspective; orthographic uses linear depth.
const bool isPerspective = ( m_mainCamera->projection() == cvf::Camera::PERSPECTIVE );
float logDepthFC = static_cast<float>( 2.0 / std::log2( farPlaneDist + 1.0 ) );
m_globalUniformSet->setLogDepthFarConstant( logDepthFC );
Comment on lines +484 to +489

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Comparison uses wrong fc 🐞 Bug ✓ Correctness

Viewer uses one global uniform set for both main and comparison renderings, but updates u_logDepthFC
only after computing the main camera near/far. The comparison camera can be assigned different
near/far immediately afterwards without updating u_logDepthFC, making its log-depth mapping
incorrect.
Agent Prompt
### Issue description
`u_logDepthFC` is shared across two renderings but only updated for the main camera, so the comparison pass can render with mismatched log-depth parameters.

### Issue Context
Both renderings are configured to share `m_globalUniformSet`.

### Fix Focus Areas
- Fwk/AppFwk/cafViewer/cafViewer.cpp[205-219]
- Fwk/AppFwk/cafViewer/cafViewer.cpp[460-513]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

m_globalUniformSet->setUseLogDepth( isPerspective ? 1.0f : 0.0f );
}

copyCameraView( m_mainCamera.p(), m_comparisonMainCamera.p() );
Expand Down Expand Up @@ -509,32 +529,56 @@ bool caf::Viewer::calculateNearFarPlanes( const cvf::Rendering* rendering,
double* farPlaneDist,
double* nearPlaneDist )
{
cvf::BoundingBox bb = rendering->boundingBox();

if ( !bb.isValid() ) return false;
if ( !rendering->boundingBox().isValid() ) return false;

cvf::Vec3d eye = rendering->camera()->position();
cvf::Vec3d viewdir = rendering->camera()->direction();

cvf::Vec3d bboxCorners[8];
bb.cornerVertices( bboxCorners );

// Find the distance to the bbox corners most behind and most in front of camera
// Iterate per-model bounding boxes and skip models that are entirely outside the
// camera frustum. This avoids distant off-screen objects inflating the far plane,
// which would degrade depth buffer precision and cause z-fighting.
// Fall back to the scene-wide bounding box if no model contributes.

double maxDistEyeToCornerAlongViewDir = -HUGE_VAL;
double minDistEyeToCornerAlongViewDir = HUGE_VAL;
for ( int bcIdx = 0; bcIdx < 8; ++bcIdx )
{
double distEyeBoxCornerAlongViewDir = ( bboxCorners[bcIdx] - eye ) * viewdir;

if ( distEyeBoxCornerAlongViewDir > maxDistEyeToCornerAlongViewDir )
cvf::Frustum viewFrustum = rendering->camera()->frustum();
const cvf::Scene* scene = rendering->scene();
bool anyModelContributed = false;

if ( scene )
{
for ( cvf::uint mIdx = 0; mIdx < scene->modelCount(); ++mIdx )
{
maxDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir;
const cvf::Model* model = scene->model( mIdx );
cvf::BoundingBox modelBB = model->boundingBox();

if ( !modelBB.isValid() ) continue;
if ( viewFrustum.isOutside( modelBB ) ) continue;

cvf::Vec3d corners[8];
modelBB.cornerVertices( corners );
for ( int cIdx = 0; cIdx < 8; ++cIdx )
{
double dist = ( corners[cIdx] - eye ) * viewdir;
maxDistEyeToCornerAlongViewDir = CVF_MAX( maxDistEyeToCornerAlongViewDir, dist );
minDistEyeToCornerAlongViewDir = CVF_MIN( minDistEyeToCornerAlongViewDir, dist );
}
anyModelContributed = true;
}
}

if ( distEyeBoxCornerAlongViewDir < minDistEyeToCornerAlongViewDir )
if ( !anyModelContributed )
{
// Fallback: use the scene-wide bounding box (original behaviour)
cvf::BoundingBox bb = rendering->boundingBox();
cvf::Vec3d bboxCorners[8];
bb.cornerVertices( bboxCorners );
for ( int bcIdx = 0; bcIdx < 8; ++bcIdx )
{
minDistEyeToCornerAlongViewDir = distEyeBoxCornerAlongViewDir; // Sometimes negative-> behind camera
double dist = ( bboxCorners[bcIdx] - eye ) * viewdir;
maxDistEyeToCornerAlongViewDir = CVF_MAX( maxDistEyeToCornerAlongViewDir, dist );
minDistEyeToCornerAlongViewDir = CVF_MIN( minDistEyeToCornerAlongViewDir, dist );
}
}

Expand All @@ -548,16 +592,16 @@ bool caf::Viewer::calculateNearFarPlanes( const cvf::Rendering* rendering,

if ( rendering->camera()->projection() == cvf::Camera::PERSPECTIVE || isOrthoNearPlaneFollowingCamera )
{
// Choose the one furthest from the camera of: 0.8*bbox distance, m_minPerspectiveNearPlaneDistance.
// Choose the one furthest from the camera of: 0.8*bbox distance, m_defaultPerspectiveNearPlaneDistance.
( *nearPlaneDist ) = CVF_MAX( m_defaultPerspectiveNearPlaneDistance, 0.8 * minDistEyeToCornerAlongViewDir );

// If we are zooming into a detail, allow the near-plane to move towards camera beyond the
// m_minPerspectiveNearPlaneDistance
if ( ( *nearPlaneDist ) == m_defaultPerspectiveNearPlaneDistance // We are inside the bounding box
&& m_navigationPolicy.notNull() && m_navigationPolicyEnabled )
// If the camera is inside (or past) the bounding box, allow the near plane to move
// closer to the camera based on the point of interest distance, so zooming into details
// does not clip geometry.
if ( minDistEyeToCornerAlongViewDir <= 0 && m_navigationPolicy.notNull() && m_navigationPolicyEnabled )
{
double pointOfInterestDist = ( eye - navPointOfinterest ).length();
( *nearPlaneDist ) = CVF_MIN( ( *nearPlaneDist ), pointOfInterestDist * 0.2 );
( *nearPlaneDist ) = CVF_MAX( m_defaultPerspectiveNearPlaneDistance, pointOfInterestDist * 0.1 );
}

// Guard against the zero nearplane possibility
Expand All @@ -577,6 +621,15 @@ bool caf::Viewer::calculateNearFarPlanes( const cvf::Rendering* rendering,

if ( ( *farPlaneDist ) <= ( *nearPlaneDist ) ) ( *farPlaneDist ) = ( *nearPlaneDist ) + 1.0;

// Enforce a maximum far/near ratio to preserve depth buffer precision.
// A 24-bit depth buffer loses effective precision rapidly as far/near grows.
// Pushing the near plane forward is preferable to allowing z-fighting.
const double maxFarNearRatio = 3000.0;
if ( ( *nearPlaneDist ) > 0 && ( ( *farPlaneDist ) / ( *nearPlaneDist ) ) > maxFarNearRatio )
{
( *nearPlaneDist ) = ( *farPlaneDist ) / maxFarNearRatio;
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,12 +542,7 @@ void WBTransparencySurfaceEffectGenerator::updateForFixedFunctionRendering( cvf:
//--------------------------------------------------------------------------------------------------
void WBTransparencySurfaceEffectGenerator::updateCommonEffect( cvf::Effect* effect ) const
{
if ( m_polygonOffset != PO_NONE )
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset =
EffectGenerator::createAndConfigurePolygonOffsetRenderState( m_polygonOffset );
effect->setRenderState( polyOffset.p() );
}
EffectGenerator::applyPolygonOffset( effect, m_polygonOffset );

if ( m_color.a() < 1.0f )
{
Expand Down
Loading
Loading