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

(10781)

2D

(281)

Ads

(55)

AI & Navigation

(82)

Analytics

(133)

Animation

(396)

Asset Store

(355)

Asset Store Publisher

(17)

Assets

(543)

Audio

(184)

Cloud Build

(145)

Collaborate

(64)

Docs & Tutorials

(240)

Editor

(2507)

Everyplay

(19)

Game Performance Reporting

(22)

General

(980)

Graphics

(870)

GUI

(432)

Input

(173)

Licensing

(92)

Networking

(189)

Physics

(384)

Platforms

(442)

Profiling & Optimization

(85)

Runtime

(182)

Scripting

(1168)

Terrain

(172)

WebGL

(143)