Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions indra/newview/app_settings/settings_alchemy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2446,13 +2446,13 @@
<key>AlchemyRenderTerrainTessDensity</key>
<map>
<key>Comment</key>
<string>Base density of the terrain tessellation: metres of patch edge per level, divided by the distance to the camera, so at 64 a 16 m patch is split 64 ways (25 cm) within 16 m of the camera, 16 ways (1 m) at 64 m and not at all past 1 km. The terrain detail slider multiplies it. Triangle count grows with the square; clamped to 8 to 256.</string>
<string>Base density of the terrain tessellation: metres of patch edge per level, divided by the distance to the camera, so at 48 a 16 m patch is split 48 ways (33 cm) within 16 m of the camera, 12 ways (1.3 m) at 64 m and not at all past 768 m. The terrain detail slider multiplies it. Triangle count grows with the square; clamped to 8 to 256.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>64</real>
<real>48</real>
</map>
<key>AlchemyRenderTerrainTessRasterSegment</key>
<map>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ bool isFarDepth(float d); // deferredUtil.glsl -- depth-convention a

vec4 getWaterFogView(vec3 pos);

uniform int above_water;

// Void water has no floor. The sky behind it keeps the cleared far depth, which an infinite projection
// reconstructs a thousand km out and a finite one at its far plane, wherever that falls relative to the surface;
// it is fogged instead as water this deep past where the ray enters, at any distance.
Expand All @@ -45,28 +43,8 @@ uniform vec4 waterPlane;
void main()
{
vec2 tc = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
// From above, the hardware depth test (LLPipeline::doWaterHaze) keeps the field off what lies in front of it.
float depth = getDepth(tc.xy);
if (above_water > 0)
{
// we want to depth test when the camera is above water, but some GPUs have a hard time
// with depth testing against render targets that are bound for sampling in the same shader
// so we do it manually here

// The matching hardware LLGLDepthTest in pipeline.cpp auto-translates its func under
// reverse-Z; keep this in sync. Under reverse-Z clip.z/clip.w is already the [0,1]
// ndc z (no *0.5+0.5), and "fragment behind stored geometry" is the smaller depth.
#ifdef REVERSE_Z
float cur_depth = vary_fragcoord.z/vary_fragcoord.w;
if (cur_depth < depth)
#else
float cur_depth = vary_fragcoord.z/vary_fragcoord.w*0.5+0.5;
if (cur_depth > depth)
#endif
{
discard;
}

}

vec4 pos = getPositionWithDepth(tc, depth);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ in vec3 view;
in vec3 vary_position;

vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color);
void mirrorClip(vec3 position);
bool mirrorClipped(vec3 position);
void water_wave_normals(sampler2D map_a, sampler2D map_b, vec2 r, out vec3 big, out vec3 little_xy, out vec3 little_zw);

void main()
{
mirrorClip(vary_position);
// Discarded at the end: the wave normals take derivatives.
bool clipped = mirrorClipped(vary_position);
vec2 screen_tc = gl_FragCoord.xy / screen_res;

vec4 color;
Expand All @@ -84,5 +85,14 @@ void main()

fb = applyWaterFogViewLinearNoClip(vary_position, fb);

// Compiled only in the mirror variant: a discard the compiler cannot see is dead costs every fragment its early
// depth test.
#ifdef MIRROR_CLIP
if (clipped)
{
discard;
}
#endif

frag_color = max(fb, vec4(0));
}
14 changes: 12 additions & 2 deletions indra/newview/app_settings/shaders/class3/environment/waterF.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color);

void mirrorClip(vec3 pos);
bool mirrorClipped(vec3 pos);

// PBR interface
vec2 BRDF(float NoV, float roughness);
Expand Down Expand Up @@ -130,7 +130,8 @@ void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave

void main()
{
mirrorClip(vary_position);
// Discarded at the end: the wave normals and the shadow take derivatives.
bool clipped = mirrorClipped(vary_position);

// The plane's frame and the light in eye space, the same at every point: agent z and x through the view.
vec3 vN = normal_matrix[2];
Expand Down Expand Up @@ -326,6 +327,15 @@ void main()
}
}

// Compiled only in the mirror variant: a discard the compiler cannot see is dead costs every fragment its early
// depth test.
#ifdef MIRROR_CLIP
if (clipped)
{
discard;
}
#endif

// Not capped at 1: the glint and bright reflections are HDR and have to reach white and bloom, and
// what shows through the surface must match the shore beside it. The alpha is the glint's glow, which
// the pool adds to the glow of what lies beneath.
Expand Down
2 changes: 1 addition & 1 deletion indra/newview/lldrawpoolterrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace
// Pinned (density 0, which terrainTC reads as the grid's level) exactly when the programs were built with the
// spacing that cuts the grid's level into its segments (TERRAIN_TESS_PINNED), from the same latched input, and
// above 0 otherwise whatever a debug RenderTerrainLODFactor says.
static LLCachedControl<F32> tess_density(gSavedSettings, "AlchemyRenderTerrainTessDensity", 64.f);
static LLCachedControl<F32> tess_density(gSavedSettings, "AlchemyRenderTerrainTessDensity", 48.f);
static LLCachedControl<F32> raster_segment(gSavedSettings, "AlchemyRenderTerrainTessRasterSegment", 8.f);
const F32 density = gPipeline.shaderInputs().mLocal.mTerrainTessPinned
? 0.f
Expand Down
7 changes: 7 additions & 0 deletions indra/newview/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12420,6 +12420,13 @@ void LLPipeline::doWaterHaze()
return;
}

// Nor where this view's water does not refract (ALRenderResourcePlan::refractsWater): its opaque surface hides what
// lies under it, which is all the haze fogs, and where an exclusion prim removed it the haze fogs nothing either.
if (!sUnderWaterRender && !ALRenderResourcePlan::refractsWater(renderPack(), sRenderTransparentWater))
{
return;
}

if (RenderDeferredAtmospheric)
{
// The scene's depth as the haze reads it, after the pools before it wrote it in this binding.
Expand Down
Loading