diff options
author | Runitai Linden <davep@lindenlab.com> | 2021-12-07 16:32:38 -0600 |
---|---|---|
committer | Runitai Linden <davep@lindenlab.com> | 2021-12-07 16:32:38 -0600 |
commit | 8a18b5e427e261ccc60eeb673f140eff3690bf7b (patch) | |
tree | 36d6d1a050a8c9483593e6d0d04ce472e87518d2 /indra | |
parent | 66d88733ee987362dd9efb807faa6198ec655175 (diff) |
SL-16462 Fix for broken water clip plane during water reflection/refraction map render.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llrender/llgl.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llviewerdisplay.cpp | 17 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 48 | ||||
-rw-r--r-- | indra/newview/pipeline.h | 2 |
4 files changed, 36 insertions, 34 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 64db095dec..18a79d5264 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -2112,7 +2112,8 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode mModelview = modelview; mProjection = projection; - setPlane(p[0], p[1], p[2], p[3]); + //flip incoming LLPlane to get consistent behavior compared to frustum culling + setPlane(-p[0], -p[1], -p[2], -p[3]); } } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 046187cf4f..c84a8c70fa 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -683,21 +683,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) stop_glerror(); - S32 water_clip = 0; - if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && - (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || - gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER))) - { - if (LLViewerCamera::getInstance()->cameraUnderWater()) - { - water_clip = -1; - } - else - { - water_clip = 1; - } - } - LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); //Increment drawable frame counter @@ -719,7 +704,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) static LLCullResult result; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater(); - gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); + gPipeline.updateCull(*LLViewerCamera::getInstance(), result); stop_glerror(); LLGLState::checkStates(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d3b2443116..dce63e06fb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2321,7 +2321,7 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) { static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") @@ -2413,7 +2413,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLVOCachePartition* vo_part = region->getVOCachePartition(); if(vo_part) { - bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe; // && 0 > water_clip + bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe; vo_part->cull(camera, do_occlusion_cull); } } @@ -9158,22 +9158,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) //plane params LLPlane plane; LLVector3 pnorm; - S32 water_clip = 0; - if (!camera_is_underwater) + + if (camera_is_underwater) { - //camera is above water, clip plane points up - pnorm.setVec(0,0,1); - plane.setVec(pnorm, -water_height); - water_clip = 1; + //camera is below water, cull above water + pnorm.setVec(0, 0, 1); } else { - //camera is below water, clip plane points down - pnorm = LLVector3(0,0,-1); - plane.setVec(pnorm, water_height); - water_clip = -1; + //camera is above water, cull below water + pnorm = LLVector3(0, 0, -1); } + plane.setVec(LLVector3(0, 0, water_height), pnorm); + if (!camera_is_underwater) { //generate planar reflection map @@ -9271,7 +9269,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection); LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, mReflectedObjects, -water_clip, &plane); + updateCull(camera, mReflectedObjects, &plane); stateSort(camera, mReflectedObjects); renderGeom(camera); } @@ -9336,11 +9334,29 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) mWaterDis.clear(); gGL.setColorMask(true, false); - F32 water_dist = water_height * LLPipeline::sDistortionWaterClipPlaneMargin; + F32 water_dist = water_height; //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself, // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map - LLPlane plane(-pnorm, camera_is_underwater ? -water_height : water_dist); + LLPlane plane; + + if (camera_is_underwater) + { + //nudge clip plane below water to avoid visible holes in objects intersecting water surface + water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin; + //camera is below water, clip plane points up + pnorm.setVec(0, 0, -1); + } + else + { + //nudge clip plane above water to avoid visible holes in objects intersecting water surface + water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin; + //camera is above water, clip plane points down + pnorm = LLVector3(0, 0, 1); + } + + plane.setVec(LLVector3(0, 0, water_dist), pnorm); + LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection); gGL.setColorMask(true, true); @@ -9349,7 +9365,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT) { - updateCull(camera, mRefractedObjects, water_clip, &plane); + updateCull(camera, mRefractedObjects, &plane); stateSort(camera, mRefractedObjects); renderGeom(camera); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 794d806d0c..fdc3738472 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -240,7 +240,7 @@ public: bool visibleObjectsInFrustum(LLCamera& camera); bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0)); - void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane + void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void processPartitionQ(); |