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 | |
| parent | 66d88733ee987362dd9efb807faa6198ec655175 (diff) | |
SL-16462 Fix for broken water clip plane during water reflection/refraction map render.
| -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();  | 
