Search Feedback

10
votes

Fix Frustum Culling to be Exact

Graphics

-

-

The internal frustum culling fails to cull large objects behind the camera, and OnWillRenderObject is sometimes called even when the object is clearly not visible.

Please see https://www.iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm and implement exact frustum culling, this is crucial for large meshes like terrain or planets, ships, etc.

Comments (1)

  1. A252eecd500b0ba734ea17f9ae1fb2da?d=mm

    jjxtra

    Dec 06, 2018 01:58

    // false if fully outside, true if inside or intersects
    bool boxInFrustum( frustum3 const & fru, bound3 const & box )
    {
    // check box outside/inside of frustum
    for( int i=0; i<6; i++ )
    {
    int out = 0;
    out += ((dot( fru.mPlane[i], vec4(box.mMinX, box.mMinY, box.mMinZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMaxX, box.mMinY, box.mMinZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMinX, box.mMaxY, box.mMinZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMaxX, box.mMaxY, box.mMinZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMinX, box.mMinY, box.mMaxZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMaxX, box.mMinY, box.mMaxZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMinX, box.mMaxY, box.mMaxZ, 1.0f) ) < 0.0 )?1:0);
    out += ((dot( fru.mPlane[i], vec4(box.mMaxX, box.mMaxY, box.mMaxZ, 1.0f) ) < 0.0 )?1:0);
    if( out==8 ) return false;
    }

    // check frustum outside/inside box
    int out;
    out=0; for( int i=0; i<8; i++ ) out += ((fru.mPoints[i].x > box.mMaxX)?1:0); if( out==8 ) return false;
    out=0; for( int i=0; i<8; i++ ) out += ((fru.mPoints[i].x < box.mMinX)?1:0); if( out==8 ) return false;
    out=0; for( int i=0; i<8; i++ ) out += ((fru.mPoints[i].y > box.mMaxY)?1:0); if( out==8 ) return false;
    out=0; for( int i=0; i<8; i++ ) out += ((fru.mPoints[i].y < box.mMinY)?1:0); if( out==8 ) return false;
    out=0; for( int i=0; i<8; i++ ) out += ((fru.mPoints[i].z > box.mMaxZ)?1:0); if( out==8 ) return false;
    out=0; for( int i=0; i<8; i++ ) out += ((fru.mPoints[i].z < box.mMinZ)?1:0); if( out==8 ) return false;

    return true;
    }

Your opinion counts

Help us make things better. Share your great idea for improving Unity or vote for other people’s.

Log in to post a new idea

Categories

All

(10886)

2D

(287)

Ads

(57)

AI & Navigation

(81)

Analytics

(130)

Animation

(406)

Asset Store

(364)

Asset Store Publisher

(19)

Assets

(551)

Audio

(185)

Cloud Build

(148)

Collaborate

(67)

Docs & Tutorials

(246)

Editor

(2545)

Everyplay

(17)

Game Performance Reporting

(21)

General

(987)

Graphics

(894)

GUI

(442)

Input

(173)

Licensing

(93)

Networking

(189)

Physics

(387)

Platforms

(445)

Profiling & Optimization

(84)

Runtime

(185)

Scripting

(1141)

Terrain

(174)

WebGL

(142)