mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 05:53:29 +02:00
Fixed for stereo rendering with resolution level 0
This commit is contained in:
parent
6921e71a9a
commit
b1db7ab403
12 changed files with 67 additions and 50 deletions
|
@ -212,7 +212,7 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
|
|||
#else
|
||||
numSamples{ 16 },
|
||||
#endif
|
||||
resolutionLevel{ 2 },
|
||||
resolutionLevel{ 0 },
|
||||
blurRadius{ 4 },
|
||||
ditheringEnabled{ true },
|
||||
borderingEnabled{ true },
|
||||
|
@ -509,7 +509,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
auto& sample = _aoFrameParametersBuffer[splitId].edit();
|
||||
sample._angleInfo.x = _randomSamples[splitId + SSAO_RANDOM_SAMPLE_COUNT * _frameId];
|
||||
}
|
||||
// TEMPO OP _frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
|
||||
// _frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
|
||||
|
||||
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
|
||||
PROFILE_RANGE_BATCH(batch, "AmbientOcclusion");
|
||||
|
@ -605,27 +605,31 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
{
|
||||
PROFILE_RANGE_BATCH(batch, "Bilateral Blur");
|
||||
// Blur 1st pass
|
||||
model.setScale(resolutionScale);
|
||||
batch.setModelTransform(model);
|
||||
batch.setViewportTransform(firstBlurViewport);
|
||||
batch.setFramebuffer(occlusionBlurredFBO);
|
||||
// Use full resolution depth and normal for bilateral upscaling and blur
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, fullNormalTexture);
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _hblurParametersBuffer);
|
||||
batch.setPipeline(firstHBlurPipeline);
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
batch.pushProfileRange("Horizontal");
|
||||
model.setScale(resolutionScale);
|
||||
batch.setModelTransform(model);
|
||||
batch.setViewportTransform(firstBlurViewport);
|
||||
batch.setFramebuffer(occlusionBlurredFBO);
|
||||
// Use full resolution depth and normal for bilateral upscaling and blur
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, fullNormalTexture);
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _hblurParametersBuffer);
|
||||
batch.setPipeline(firstHBlurPipeline);
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
batch.popProfileRange();
|
||||
|
||||
// Blur 2nd pass
|
||||
model.setScale(glm::vec3(1.0f, resolutionScale, 1.0f));
|
||||
batch.setModelTransform(model);
|
||||
batch.setViewportTransform(sourceViewport);
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _vblurParametersBuffer);
|
||||
batch.setPipeline(lastVBlurPipeline);
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionBlurredFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
batch.pushProfileRange("Vertical");
|
||||
model.setScale(glm::vec3(1.0f, resolutionScale, 1.0f));
|
||||
batch.setModelTransform(model);
|
||||
batch.setViewportTransform(sourceViewport);
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _vblurParametersBuffer);
|
||||
batch.setPipeline(lastVBlurPipeline);
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionBlurredFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
batch.popProfileRange();
|
||||
}
|
||||
|
||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, nullptr);
|
||||
|
|
|
@ -120,8 +120,8 @@ float getStereoSideHeight(int resolutionLevel) {
|
|||
return float(int(frameTransform._pixelInfo.w) >> resolutionLevel);
|
||||
}
|
||||
|
||||
vec2 getSideImageSize(int resolutionLevel) {
|
||||
return vec2(float(int(frameTransform._stereoInfo.y) >> resolutionLevel), float(int(frameTransform._pixelInfo.w) >> resolutionLevel));
|
||||
vec2 getStereoSideSize(int resolutionLevel) {
|
||||
return vec2(getStereoSideWidth(resolutionLevel), getStereoSideHeight(resolutionLevel));
|
||||
}
|
||||
|
||||
ivec4 getStereoSideInfo(int xPos, int resolutionLevel) {
|
||||
|
@ -129,6 +129,14 @@ ivec4 getStereoSideInfo(int xPos, int resolutionLevel) {
|
|||
return ivec4(xPos < sideWidth ? ivec2(0, 0) : ivec2(1, sideWidth), sideWidth, isStereo());
|
||||
}
|
||||
|
||||
int getStereoSide(ivec4 sideInfo) {
|
||||
return sideInfo.x;
|
||||
}
|
||||
|
||||
bool isStereoFromInfo(ivec4 sideInfo) {
|
||||
return sideInfo.w != 0;
|
||||
}
|
||||
|
||||
float evalZeyeFromZdb(float depth) {
|
||||
return frameTransform._depthInfo.x / (depth * frameTransform._depthInfo.y + frameTransform._depthInfo.z);
|
||||
}
|
||||
|
|
|
@ -214,19 +214,23 @@ vec3 getNormalEyeAtUV(vec2 texCoord, int level) {
|
|||
return normalize(texture(normalTex, texCoord, level).xyz*2.0 - vec3(1.0));
|
||||
}
|
||||
|
||||
vec3 getNormalEyeAtPixel(ivec2 pixel, int level) {
|
||||
return normalize(texelFetch(normalTex, pixel, level).xyz*2.0 - vec3(1.0));
|
||||
}
|
||||
|
||||
int evalMipFromRadius(float radius) {
|
||||
const int LOG_MAX_OFFSET = 2;
|
||||
const int MAX_MIP_LEVEL = 5;
|
||||
return clamp(findMSB(int(radius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
|
||||
}
|
||||
|
||||
vec4 fetchTap(ivec4 side, vec2 tapPixelPos, float tapRadius, vec2 sideImageSize) {
|
||||
vec4 fetchTap(ivec4 side, vec2 tapSidePixelPos, float tapRadius, vec2 sideImageSize) {
|
||||
int mipLevel = evalMipFromRadius(tapRadius * float(doFetchMips()));
|
||||
|
||||
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
|
||||
// Manually clamp to the texture size because texelFetch bypasses the texture unit
|
||||
vec2 tapUV = (tapPixelPos + vec2(0.5)) / sideImageSize;
|
||||
vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y);
|
||||
vec2 tapUV = (tapSidePixelPos + vec2(0.5)) / sideImageSize;
|
||||
vec2 fetchUV = mix(tapUV, vec2((tapUV.x + getStereoSide(side)) * 0.5, tapUV.y), isStereoFromInfo(side));
|
||||
|
||||
vec4 P;
|
||||
P.xy = tapUV;
|
||||
|
@ -276,11 +280,11 @@ float computeHorizonFromTap(vec3 tapPositionES, vec3 fragPositionES, vec3 fragNo
|
|||
}
|
||||
|
||||
<@func computeHorizon()@>
|
||||
vec2 tapPixelPos = tapPixelOffset + shadedPixelPos;
|
||||
if (tapPixelPos.x<0 && tapPixelPos.y<0 && tapPixelPos.x>=sideImageSize.x && tapPixelPos.y>=sideImageSize.y) {
|
||||
vec2 tapSidePixelPos = tapPixelOffset + shadedPixelPos;
|
||||
if (tapSidePixelPos.x<0 && tapSidePixelPos.y<0 && tapSidePixelPos.x>=sideImageSize.x && tapSidePixelPos.y>=sideImageSize.y) {
|
||||
break;
|
||||
}
|
||||
vec4 tapUVZ_mip = fetchTap(side, tapPixelPos, radius, sideImageSize);
|
||||
vec4 tapUVZ_mip = fetchTap(side, tapSidePixelPos, radius, sideImageSize);
|
||||
vec3 tapPositionES = evalEyePositionFromZeye(side.x, tapUVZ_mip.z, tapUVZ_mip.xy);
|
||||
float tapCosHorizonAngle = computeHorizonFromTap(tapPositionES, fragPositionES, fragNormalES);
|
||||
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
vec2 sideImageSize = getSideImageSize(0);
|
||||
vec2 sideImageSize = getStereoSideSize(0);
|
||||
|
||||
// Pixel being shaded
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
ivec2 fragPixelPos = ivec2(fragCoord.xy);
|
||||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEyeAtPixel(fragPixelPos, 0);
|
||||
|
||||
// Stereo side info
|
||||
ivec4 side = getStereoSideInfo(fragPixelPos.x, 0);
|
||||
|
||||
|
@ -31,9 +34,6 @@ void main(void) {
|
|||
fragPixelPos.x -= side.y;
|
||||
vec2 fragUVPos = (vec2(fragPixelPos) + vec2(0.5)) / sideImageSize;
|
||||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEyeAtUV(fragUVPos, 0);
|
||||
|
||||
// The position and normal of the pixel fragment in Eye space
|
||||
vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
||||
vec3 fragNormalES = evalEyeNormal(fragPositionES);
|
||||
|
|
|
@ -37,7 +37,7 @@ vec2 getDebugCursorTexcoord(){
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
vec2 imageSize = getSideImageSize(getResolutionLevel());
|
||||
vec2 imageSize = getStereoSideSize(getResolutionLevel());
|
||||
|
||||
// In debug adjust the correct frag pixel based on base resolution
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
|
|
|
@ -25,8 +25,8 @@ void main(void) {
|
|||
// Gather the four splits of the occlusion result back into an interleaved full size
|
||||
// result (at the resolution level, of course)
|
||||
ivec2 destPixelCoord = ivec2(gl_FragCoord.xy);
|
||||
ivec2 sourcePixelCoord = destPixelCoord >> 1;
|
||||
ivec2 splitImageSize = ivec2(getWidthHeight(getResolutionLevel() + 1));
|
||||
ivec2 sourcePixelCoord = destPixelCoord / 2;
|
||||
ivec2 splitImageSize = ivec2(getWidthHeight(getResolutionLevel()+1));
|
||||
|
||||
sourcePixelCoord += (destPixelCoord & ivec2(1)) * splitImageSize;
|
||||
|
||||
|
|
|
@ -24,14 +24,20 @@
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
vec2 sideImageSize = getSideImageSize(getResolutionLevel());
|
||||
vec2 sideImageSize = getStereoSideSize(getResolutionLevel());
|
||||
|
||||
// Pixel being shaded
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
ivec2 fragPixelPos = ivec2(fragCoord.xy);
|
||||
#if SSAO_USE_QUAD_SPLIT
|
||||
ivec2 splitImageSize = ivec2(getWidthHeight(getResolutionLevel() + SSAO_USE_QUAD_SPLIT));
|
||||
fragPixelPos = ((fragPixelPos - getPixelOffset()*splitImageSize) << SSAO_USE_QUAD_SPLIT) + getPixelOffset();
|
||||
ivec2 splitImageSize = ivec2(getWidthHeight(getResolutionLevel()+1));
|
||||
fragPixelPos = ((fragPixelPos - getPixelOffset()*splitImageSize) * 2) + getPixelOffset();
|
||||
#endif
|
||||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEyeAtPixel(fragPixelPos, 0);
|
||||
#if SSAO_USE_QUAD_SPLIT
|
||||
vec3 fragNormalES = getNormalEyeAtPixel(fragPixelPos, 0);
|
||||
#endif
|
||||
|
||||
// Stereo side info
|
||||
|
@ -41,14 +47,9 @@ void main(void) {
|
|||
fragPixelPos.x -= side.y;
|
||||
vec2 fragUVPos = (vec2(fragPixelPos) + vec2(0.5)) / sideImageSize;
|
||||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEyeAtUV(fragUVPos, 0);
|
||||
|
||||
// The position and normal of the pixel fragment in Eye space
|
||||
vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
||||
#if SSAO_USE_QUAD_SPLIT
|
||||
vec3 fragNormalES = getNormalEyeAtUV(fragUVPos, 0);
|
||||
#else
|
||||
#if !SSAO_USE_QUAD_SPLIT
|
||||
vec3 fragNormalES = evalEyeNormal(fragPositionES);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ layout(binding=0) uniform blurParamsBuffer {
|
|||
BlurParameters parameters;
|
||||
};
|
||||
|
||||
vec2 getViewportInvWidthHeight() {
|
||||
vec2 getInvWidthHeight() {
|
||||
return parameters.resolutionInfo.zw;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@ layout(location=0) in vec2 varTexCoord0;
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
outFragColor = pixelShaderGaussianDepthAware(varTexCoord0, vec2(1.0, 0.0), getViewportInvWidthHeight());
|
||||
outFragColor = pixelShaderGaussianDepthAware(varTexCoord0, vec2(1.0, 0.0), getInvWidthHeight());
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@ layout(location=0) in vec2 varTexCoord0;
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
outFragColor = pixelShaderGaussianDepthAware(varTexCoord0, vec2(0.0, 1.0), getViewportInvWidthHeight());
|
||||
outFragColor = pixelShaderGaussianDepthAware(varTexCoord0, vec2(0.0, 1.0), getInvWidthHeight());
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,6 @@ layout(location=0) in vec2 varTexCoord0;
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
outFragColor = pixelShaderGaussian(varTexCoord0, vec2(1.0, 0.0), getViewportInvWidthHeight());
|
||||
outFragColor = pixelShaderGaussian(varTexCoord0, vec2(1.0, 0.0), getInvWidthHeight());
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@ layout(location=0) in vec2 varTexCoord0;
|
|||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
outFragColor = pixelShaderGaussian(varTexCoord0, vec2(0.0, 1.0), getViewportInvWidthHeight());
|
||||
outFragColor = pixelShaderGaussian(varTexCoord0, vec2(0.0, 1.0), getInvWidthHeight());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue