SL-18190 WIP - Add refraction to water without splitting scene between above and below water
parent
1e72e3d82c
commit
30bcc7d6d5
|
|
@ -623,6 +623,8 @@ void LLRenderTarget::flush(bool fetch_depth)
|
|||
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("LLRenderTarget::copyContents");
|
||||
|
||||
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
|
||||
|
||||
LLGLDepthTest depth(write_depth, write_depth);
|
||||
|
|
|
|||
|
|
@ -310,16 +310,21 @@ vec4 getPosition(vec2 pos_screen)
|
|||
return pos;
|
||||
}
|
||||
|
||||
// get position given a normalized device coordinate
|
||||
vec3 getPositionWithNDC(vec3 ndc)
|
||||
{
|
||||
vec4 pos = inv_proj * vec4(ndc, 1.0);
|
||||
return pos.xyz / pos.w;
|
||||
}
|
||||
|
||||
vec4 getPositionWithDepth(vec2 pos_screen, float depth)
|
||||
{
|
||||
vec2 sc = getScreenCoordinate(pos_screen);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
vec3 ndc = vec3(sc.x, sc.y, 2.0*depth-1.0);
|
||||
return vec4(getPositionWithNDC(ndc), 1.0);
|
||||
}
|
||||
|
||||
|
||||
vec2 getScreenXY(vec4 clip)
|
||||
{
|
||||
vec4 ndc = clip;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ uniform float waterFogKS;
|
|||
|
||||
vec3 getPositionEye();
|
||||
|
||||
vec3 srgb_to_linear(vec3 col);
|
||||
|
||||
vec4 applyWaterFogView(vec3 pos, vec4 color)
|
||||
{
|
||||
vec3 view = normalize(pos);
|
||||
|
|
@ -71,6 +73,46 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
|
|||
return color;
|
||||
}
|
||||
|
||||
vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
|
||||
{
|
||||
vec3 view = normalize(pos);
|
||||
//normalize view vector
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w / es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
kc.rgb = srgb_to_linear(kc.rgb); // TODO -- pass in waterFogColor linear
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2 * l) - 1.0;
|
||||
|
||||
float L = min(t1 / t2 * t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l * kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 applyWaterFog(vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ out vec3 vary_position;
|
|||
out vec3 vary_light_dir;
|
||||
out vec3 vary_tangent;
|
||||
out vec3 vary_normal;
|
||||
out vec2 vary_fragcoord;
|
||||
|
||||
float wave(vec2 v, float t, float f, vec2 d, float s)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ out vec4 frag_color;
|
|||
vec3 scaleSoftClipFragLinear(vec3 l);
|
||||
vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
|
||||
void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
|
||||
vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
|
||||
|
||||
// PBR interface
|
||||
vec3 pbrIbl(vec3 diffuseColor,
|
||||
|
|
@ -53,6 +54,8 @@ uniform sampler2D bumpMap;
|
|||
uniform sampler2D bumpMap2;
|
||||
uniform float blend_factor;
|
||||
uniform sampler2D screenTex;
|
||||
uniform sampler2D screenDepth;
|
||||
|
||||
uniform sampler2D refTex;
|
||||
|
||||
uniform float sunAngle;
|
||||
|
|
@ -100,6 +103,8 @@ vec3 transform_normal(vec3 vNt)
|
|||
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
|
||||
vec3 pos, vec3 norm, float glossiness);
|
||||
|
||||
vec3 getPositionWithNDC(vec3 ndc);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color;
|
||||
|
|
@ -110,7 +115,7 @@ void main()
|
|||
|
||||
vec3 pos = vary_position.xyz;
|
||||
|
||||
float dist = length(view.xy);
|
||||
float dist = length(pos.xyz);
|
||||
|
||||
//normalize view vector
|
||||
vec3 viewVec = normalize(pos.xyz);
|
||||
|
|
@ -121,7 +126,6 @@ void main()
|
|||
vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
|
||||
vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
|
||||
|
||||
|
||||
vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
|
||||
vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
|
||||
vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
|
||||
|
|
@ -142,11 +146,11 @@ void main()
|
|||
|
||||
//get base fresnel components
|
||||
|
||||
/*vec3 df = vec3(
|
||||
vec3 df = vec3(
|
||||
dot(viewVec, wave1),
|
||||
dot(viewVec, (wave2 + wave3) * 0.5),
|
||||
dot(viewVec, wave3)
|
||||
) * fresnelScale + fresnelOffset;*/
|
||||
) * fresnelScale + fresnelOffset;
|
||||
|
||||
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
|
||||
|
||||
|
|
@ -157,20 +161,33 @@ void main()
|
|||
|
||||
vec2 dmod_scale = vec2(dmod*dmod, dmod);
|
||||
|
||||
//float df1 = df.x + df.y + df.z;
|
||||
float df1 = df.x + df.y + df.z;
|
||||
|
||||
vec4 refcol = vec4(0, 0, 0, 0);
|
||||
wavef = normalize(wavef + vary_normal);
|
||||
//wavef = vary_normal;
|
||||
|
||||
//get specular component
|
||||
float spec = clamp(dot(vary_light_dir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
|
||||
//harden specular
|
||||
spec = pow(spec, 128.0);
|
||||
vec3 waver = reflect(viewVec, -wavef)*3;
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
//vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
|
||||
|
||||
//vec4 fb = texture2D(screenTex, distort2);
|
||||
vec2 distort2 = distort + waver.xy * refScale / max(dmod * df1, 1.0);
|
||||
distort2 = clamp(distort2, vec2(0), vec2(0.99));
|
||||
|
||||
vec4 fb = texture2D(screenTex, distort2);
|
||||
float depth = texture2D(screenDepth, distort2).r;
|
||||
vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
|
||||
|
||||
#if 1
|
||||
if (refPos.z > pos.z-0.05)
|
||||
{
|
||||
//we sampled an above water sample, don't distort
|
||||
distort2 = distort;
|
||||
fb = texture2D(screenTex, distort2);
|
||||
depth = texture2D(screenDepth, distort2).r;
|
||||
refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
fb = applyWaterFogViewLinear(refPos, fb);
|
||||
|
||||
vec3 sunlit;
|
||||
vec3 amblit;
|
||||
|
|
@ -186,48 +203,43 @@ void main()
|
|||
float roughness = 0.08;
|
||||
float gloss = 1.0 - roughness;
|
||||
|
||||
vec3 baseColor = vec3(0);
|
||||
vec3 baseColor = vec3(0.25);
|
||||
vec3 f0 = vec3(0.04);
|
||||
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
|
||||
diffuseColor *= gloss;
|
||||
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
|
||||
//vec3 refnorm = normalize(wavef + vary_normal);
|
||||
vec3 refnorm = wavef;
|
||||
|
||||
vec3 refnorm = normalize(wavef + vary_normal);
|
||||
|
||||
|
||||
vec3 irradiance = vec3(0);
|
||||
vec3 radiance = vec3(0);
|
||||
sampleReflectionProbes(irradiance, radiance, pos, refnorm, gloss);
|
||||
|
||||
// fudge -- use refracted color as irradiance
|
||||
irradiance = srgb_to_linear(waterFogColor.rgb);
|
||||
radiance *= 0.5;
|
||||
irradiance = fb.rgb;
|
||||
|
||||
color.rgb = pbrIbl(diffuseColor, specularColor, radiance, irradiance, gloss, NdotV, 0.0);
|
||||
|
||||
//vec4 fb = waterFogColor;
|
||||
//fb.rgb = srgb_to_linear(fb.rgb);
|
||||
|
||||
//refcol.rgb = vec3(0, 1, 0);
|
||||
|
||||
//mix with reflection
|
||||
//color.rgb = mix(fb.rgb, refcol.rgb, df1);
|
||||
|
||||
//color.rgb += spec * specular;
|
||||
|
||||
|
||||
// fudge -- for punctual lighting, pretend water is metallic
|
||||
diffuseColor = vec3(0);
|
||||
specularColor = vec3(1);
|
||||
roughness = 0.1;
|
||||
color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir);
|
||||
float scol = 1.0; // TODO -- incorporate shadow map
|
||||
|
||||
//color.rgb += pbrPunctual(diffuseColor, specularColor, roughness, metallic, wavef, v, vary_light_dir) * sunlit * 2.75 * scol;
|
||||
color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
|
||||
color.rgb = scaleSoftClipFragLinear(color.rgb);
|
||||
|
||||
color.a = 0.f;
|
||||
|
||||
//color.a = spec * sunAngle2;
|
||||
|
||||
frag_color = color;
|
||||
//color.rgb = fb.rgb;
|
||||
//color.rgb = vec3(depth*depth*depth*depth);
|
||||
//color.rgb = srgb_to_linear(normalize(refPos) * 0.5 + 0.5);
|
||||
//color.rgb = srgb_to_linear(normalize(pos) * 0.5 + 0.5);
|
||||
//color.rgb = srgb_to_linear(wavef * 0.5 + 0.5);
|
||||
frag_color = color;
|
||||
|
||||
#if defined(WATER_EDGE)
|
||||
gl_FragDepth = 0.9999847f;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ public:
|
|||
enum
|
||||
{
|
||||
// Correspond to LLPipeline render type
|
||||
// Also controls render order, so passes that don't use alpha masking/blending should come before
|
||||
// other passes and occlusion culling should happen just before rendering alpha masked passes
|
||||
// in order to take advantage of hierarchical Z
|
||||
// NOTE: Keep in sync with gPoolNames
|
||||
POOL_SIMPLE = 1,
|
||||
POOL_GROUND,
|
||||
|
|
|
|||
|
|
@ -122,6 +122,19 @@ S32 LLDrawPoolWater::getNumPostDeferredPasses()
|
|||
return 1;
|
||||
}
|
||||
|
||||
void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
|
||||
{
|
||||
// copy framebuffer contents so far to a texture to be used for
|
||||
// reflections and refractions
|
||||
LLRenderTarget& src = gPipeline.mRT->screen;
|
||||
LLRenderTarget& dst = gPipeline.mWaterDis;
|
||||
dst.copyContents(src,
|
||||
0, 0, src.getWidth(), src.getHeight(),
|
||||
0, 0, dst.getWidth(), dst.getHeight(),
|
||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
|
||||
GL_NEAREST);
|
||||
}
|
||||
|
||||
void LLDrawPoolWater::renderPostDeferred(S32 pass)
|
||||
{
|
||||
renderWater();
|
||||
|
|
@ -587,6 +600,8 @@ void LLDrawPoolWater::renderWater()
|
|||
|
||||
// bind reflection texture from RenderTarget
|
||||
S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
|
||||
S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
|
||||
|
||||
F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
|
||||
|
||||
S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
|
||||
|
|
@ -613,6 +628,11 @@ void LLDrawPoolWater::renderWater()
|
|||
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
|
||||
}
|
||||
|
||||
if (screenDepth > -1)
|
||||
{
|
||||
gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
|
||||
}
|
||||
|
||||
if (mShaderLevel == 1)
|
||||
{
|
||||
fog_color.mV[VW] = log(fog_density) / log(2);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@ public:
|
|||
|
||||
static void restoreGL();
|
||||
|
||||
|
||||
S32 getNumPostDeferredPasses() override;
|
||||
void beginPostDeferredPass(S32 pass) override;
|
||||
void renderPostDeferred(S32 pass) override;
|
||||
S32 getNumDeferredPasses() override;
|
||||
void renderDeferred(S32 pass = 0) override;
|
||||
|
|
|
|||
|
|
@ -681,6 +681,13 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (did_update)
|
||||
{
|
||||
// some patches changed, update region reflection probes
|
||||
mRegionp->updateReflectionProbes();
|
||||
}
|
||||
|
||||
return did_update;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1007,7 +1007,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
gPipeline.renderDeferredLighting(&gPipeline.mRT->screen);
|
||||
gPipeline.renderDeferredLighting();
|
||||
}
|
||||
|
||||
LLPipeline::sUnderWaterRender = FALSE;
|
||||
|
|
@ -1146,7 +1146,7 @@ void display_cube_face()
|
|||
|
||||
gPipeline.mRT->deferredScreen.flush();
|
||||
|
||||
gPipeline.renderDeferredLighting(&gPipeline.mRT->screen);
|
||||
gPipeline.renderDeferredLighting();
|
||||
|
||||
LLPipeline::sUnderWaterRender = FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -830,9 +830,6 @@ void LLViewerRegion::sendReliableMessage()
|
|||
void LLViewerRegion::setWaterHeight(F32 water_level)
|
||||
{
|
||||
mImpl->mLandp->setWaterHeight(water_level);
|
||||
|
||||
// reflection probes move with the water height
|
||||
updateReflectionProbes();
|
||||
}
|
||||
|
||||
F32 LLViewerRegion::getWaterHeight() const
|
||||
|
|
|
|||
|
|
@ -1021,6 +1021,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
|
|||
gWaterProgram.mName = "Water Shader";
|
||||
gWaterProgram.mFeatures.calculatesAtmospherics = true;
|
||||
gWaterProgram.mFeatures.hasAtmospherics = true;
|
||||
gWaterProgram.mFeatures.hasWaterFog = true;
|
||||
gWaterProgram.mFeatures.hasGamma = true;
|
||||
gWaterProgram.mFeatures.hasTransport = true;
|
||||
gWaterProgram.mFeatures.hasSrgb = true;
|
||||
|
|
@ -1040,6 +1041,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
|
|||
gWaterEdgeProgram.mName = "Water Edge Shader";
|
||||
gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
|
||||
gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
|
||||
gWaterEdgeProgram.mFeatures.hasWaterFog = true;
|
||||
gWaterEdgeProgram.mFeatures.hasGamma = true;
|
||||
gWaterEdgeProgram.mFeatures.hasTransport = true;
|
||||
gWaterEdgeProgram.mFeatures.hasSrgb = true;
|
||||
|
|
|
|||
|
|
@ -8442,7 +8442,7 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f)
|
|||
return v;
|
||||
}
|
||||
|
||||
void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
|
||||
void LLPipeline::renderDeferredLighting()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
|
||||
LL_PROFILE_GPU_ZONE("renderDeferredLighting");
|
||||
|
|
@ -8451,6 +8451,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
|
|||
return;
|
||||
}
|
||||
|
||||
LLRenderTarget *screen_target = &mRT->screen;
|
||||
LLRenderTarget *deferred_target = &mRT->deferredScreen;
|
||||
LLRenderTarget *deferred_depth_target = &mRT->deferredDepth;
|
||||
LLRenderTarget *deferred_light_target = &mRT->deferredLight;
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ public:
|
|||
|
||||
|
||||
|
||||
void renderDeferredLighting(LLRenderTarget* light_target);
|
||||
void renderDeferredLighting();
|
||||
void postDeferredGammaCorrect(LLRenderTarget* screen_target);
|
||||
|
||||
void generateWaterReflection(LLCamera& camera);
|
||||
|
|
|
|||
Loading…
Reference in New Issue