5656#include " Common/Xfer.h"
5757#include " Common/GameLOD.h"
5858
59+ #include " GameClient/Color.h"
5960#include " GameClient/Water.h"
6061#include " GameLogic/GameLogic.h"
6162#include " GameLogic/PolygonTrigger.h"
@@ -165,6 +166,22 @@ static ShaderClass blendStagesShader(SC_DETAIL_BLEND);
165166
166167WaterRenderObjClass *TheWaterRenderObj=nullptr ; // /<global water rendering object
167168
169+ static Int getRiverVertexDiffuse (W3DShroud *shroud, Real x, Real y, Real shadeR, Real shadeG, Real shadeB, Int diffuse)
170+ {
171+ if (!shroud)
172+ return diffuse;
173+
174+ Int cellX = (Int)(x / shroud->getCellWidth ());
175+ Int cellY = (Int)(y / shroud->getCellHeight ());
176+ W3DShroudLevel level = shroud->getShroudLevel (cellX, cellY);
177+ Real shroudScale = (Real)level / 255 .0f ;
178+ return GameMakeColor (
179+ (Int)(shadeR * shroudScale),
180+ (Int)(shadeG * shroudScale),
181+ (Int)(shadeB * shroudScale),
182+ (diffuse >> 24 ) & 0xff );
183+ }
184+
168185void doSkyBoxSet (Bool startDraw)
169186{
170187 if (TheWritableGlobalData)
@@ -2814,6 +2831,10 @@ void WaterRenderObjClass::drawRiverWater(PolygonTrigger *pTrig)
28142831
28152832 Real constA=3 *m_riverVOrigin;
28162833
2834+ // TheSuperHackers @bugfix afc-afc0 14/04/2026 Apply shroud per-vertex to avoid double-darkening
2835+ // at river borders.
2836+ W3DShroud *shroud = TheTerrainRenderObject ? TheTerrainRenderObject->getShroud () : nullptr ;
2837+
28172838 for (i=0 ; i<(pTrig->getNumPoints ()/2 ); i++)
28182839 {
28192840 Real x,y;
@@ -2834,7 +2855,8 @@ void WaterRenderObjClass::drawRiverWater(PolygonTrigger *pTrig)
28342855 vb->y =y;
28352856
28362857 vb->z =innerPt.z ;
2837- vb->diffuse = diffuse;
2858+
2859+ vb->diffuse = getRiverVertexDiffuse (shroud, x, y, shadeR, shadeG, shadeB, diffuse);
28382860
28392861 Real wobbleConst=-m_riverVOrigin+vScale*(Real)i + WWMath::Fast_Sin (2 *PI*(vScale*(Real)i) - constA)/22 .0f ;
28402862 // old slower version
@@ -2856,7 +2878,8 @@ void WaterRenderObjClass::drawRiverWater(PolygonTrigger *pTrig)
28562878 vb->x =x;
28572879 vb->y =y;
28582880 vb->z =outerPt.z ;
2859- vb->diffuse = diffuse;
2881+
2882+ vb->diffuse = getRiverVertexDiffuse (shroud, x, y, shadeR, shadeG, shadeB, diffuse);
28602883 // old slower version
28612884 // vb->v1=-m_riverVOrigin+vScale*(Real)i + wobble(vScale*i, m_riverVOrigin, doWobble);
28622885 vb->v1 =wobbleConst;
@@ -2908,19 +2931,6 @@ void WaterRenderObjClass::drawRiverWater(PolygonTrigger *pTrig)
29082931 if (TheWaterTransparency->m_additiveBlend )
29092932 DX8Wrapper::Set_DX8_Render_State (D3DRS_SRCBLEND, D3DBLEND_ONE );
29102933
2911- // do second pass to apply the shroud on water plane
2912- if (TheTerrainRenderObject->getShroud ())
2913- {
2914- W3DShaderManager::setTexture (0 ,TheTerrainRenderObject->getShroud ()->getShroudTexture ());
2915- W3DShaderManager::setShader (W3DShaderManager::ST_SHROUD_TEXTURE, 0 );
2916- DX8Wrapper::_Get_D3D_Device8 ()->SetRenderState (D3DRS_CULLMODE, D3DCULL_NONE);
2917- // Shroud shader uses z-compare of EQUAL which wouldn't work on water because it doesn't
2918- // write to the zbuffer. Change to LESSEQUAL.
2919- DX8Wrapper::_Get_D3D_Device8 ()->SetRenderState (D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2920- DX8Wrapper::Draw_Triangles ( 0 ,rectangleCount*2 , 0 , (rectangleCount+1 )*2 );
2921- DX8Wrapper::_Get_D3D_Device8 ()->SetRenderState (D3DRS_ZFUNC, D3DCMP_EQUAL);
2922- W3DShaderManager::resetShader (W3DShaderManager::ST_SHROUD_TEXTURE);
2923- }
29242934 DX8Wrapper::_Get_D3D_Device8 ()->SetRenderState (D3DRS_CULLMODE, cull);
29252935
29262936
0 commit comments