mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 09:23:17 +02:00
More changes
This commit is contained in:
parent
e96fd92f32
commit
e92e69d963
8 changed files with 68 additions and 115 deletions
|
@ -111,13 +111,6 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionBlurredTexture() {
|
|||
return _occlusionBlurredTexture;
|
||||
}
|
||||
|
||||
void AmbientOcclusionFramebuffer::setResolutionLevel(int resolutionLevel) {
|
||||
if (resolutionLevel != getResolutionLevel()) {
|
||||
clear();
|
||||
_resolutionLevel = resolutionLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GaussianDistribution {
|
||||
public:
|
||||
|
@ -240,20 +233,11 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
|||
if (config.perspectiveScale != _parametersBuffer->getPerspectiveScale()) {
|
||||
_parametersBuffer->resolutionInfo.z = config.perspectiveScale;
|
||||
}
|
||||
_framebuffer->setResolutionLevel(config.resolutionLevel);
|
||||
if (config.resolutionLevel != _parametersBuffer->getResolutionLevel()) {
|
||||
_parametersBuffer->resolutionInfo.w = config.resolutionLevel;
|
||||
auto& current = _parametersBuffer->resolutionInfo;
|
||||
current.x = (float) config.resolutionLevel;
|
||||
}
|
||||
|
||||
const auto& resolutionLevel = config.resolutionLevel;
|
||||
if (resolutionLevel != _parametersBuffer->getResolutionLevel()) {
|
||||
auto& current = _parametersBuffer->resolutionInfo;
|
||||
current.x = (float)resolutionLevel;
|
||||
|
||||
// Communicate the change to the Framebuffer cache
|
||||
// DependencyManager::get<FramebufferCache>()->setAmbientOcclusionResolutionLevel(resolutionLevel);
|
||||
}
|
||||
|
||||
if (config.blurRadius != _parametersBuffer->getBlurRadius()) {
|
||||
auto& current = _parametersBuffer->blurInfo;
|
||||
current.y = (float)config.blurRadius;
|
||||
|
@ -355,17 +339,11 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
// FIXME: Different render modes should have different tasks
|
||||
// if (args->_renderMode != RenderArgs::DEFAULT_RENDER_MODE) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const auto frameTransform = inputs.get0();
|
||||
const auto deferredFramebuffer = inputs.get1();
|
||||
const auto linearDepthFramebuffer = inputs.get2();
|
||||
|
||||
auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture();
|
||||
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||
auto sourceViewport = args->_viewport;
|
||||
auto occlusionViewport = sourceViewport;
|
||||
|
||||
|
@ -373,10 +351,9 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
_framebuffer = std::make_shared<AmbientOcclusionFramebuffer>();
|
||||
}
|
||||
|
||||
if (_framebuffer->getResolutionLevel() > 0) {
|
||||
if (_parametersBuffer->getResolutionLevel() > 0) {
|
||||
linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
|
||||
normalTexture = linearDepthFramebuffer->getHalfNormalTexture();
|
||||
occlusionViewport = occlusionViewport >> _framebuffer->getResolutionLevel();
|
||||
occlusionViewport = occlusionViewport >> _parametersBuffer->getResolutionLevel();
|
||||
}
|
||||
|
||||
_framebuffer->updateLinearDepth(linearDepthTexture);
|
||||
|
@ -390,10 +367,10 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
|
||||
auto framebufferSize = _framebuffer->getSourceFrameSize();
|
||||
|
||||
float sMin = args->_viewport.x / (float)framebufferSize.x;
|
||||
float sWidth = args->_viewport.z / (float)framebufferSize.x;
|
||||
float tMin = args->_viewport.y / (float)framebufferSize.y;
|
||||
float tHeight = args->_viewport.w / (float)framebufferSize.y;
|
||||
float sMin = occlusionViewport.x / (float)framebufferSize.x;
|
||||
float sWidth = occlusionViewport.z / (float)framebufferSize.x;
|
||||
float tMin = occlusionViewport.y / (float)framebufferSize.y;
|
||||
float tHeight = occlusionViewport.w / (float)framebufferSize.y;
|
||||
|
||||
auto resolutionLevel = _parametersBuffer->getResolutionLevel();
|
||||
|
||||
|
@ -536,10 +513,10 @@ void DebugAmbientOcclusion::run(const render::SceneContextPointer& sceneContext,
|
|||
|
||||
auto framebufferSize = glm::ivec2(linearDepthTexture->getDimensions());
|
||||
|
||||
float sMin = args->_viewport.x / (float)framebufferSize.x;
|
||||
float sWidth = args->_viewport.z / (float)framebufferSize.x;
|
||||
float tMin = args->_viewport.y / (float)framebufferSize.y;
|
||||
float tHeight = args->_viewport.w / (float)framebufferSize.y;
|
||||
float sMin = occlusionViewport.x / (float)framebufferSize.x;
|
||||
float sWidth = occlusionViewport.z / (float)framebufferSize.x;
|
||||
float tMin = occlusionViewport.y / (float)framebufferSize.y;
|
||||
float tHeight = occlusionViewport.w / (float)framebufferSize.y;
|
||||
|
||||
|
||||
// Running in stero ?
|
||||
|
@ -562,19 +539,13 @@ void DebugAmbientOcclusion::run(const render::SceneContextPointer& sceneContext,
|
|||
batch.setUniformBuffer(AmbientOcclusionEffect_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
|
||||
batch.setUniformBuffer(AmbientOcclusionEffect_ParamsSlot, ambientOcclusionUniforms);
|
||||
batch.setUniformBuffer(2, _parametersBuffer);
|
||||
|
||||
|
||||
// We need this with the mips levels
|
||||
batch.generateTextureMips(linearDepthTexture);
|
||||
|
||||
batch.setPipeline(debugPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, linearDepthTexture);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, nullptr);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, nullptr);
|
||||
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, nullptr);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -34,10 +34,7 @@ public:
|
|||
void updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
|
||||
gpu::TexturePointer getLinearDepthTexture();
|
||||
const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
|
||||
|
||||
void setResolutionLevel(int level);
|
||||
int getResolutionLevel() const { return _resolutionLevel; }
|
||||
|
||||
|
||||
protected:
|
||||
void clear();
|
||||
void allocate();
|
||||
|
@ -52,7 +49,6 @@ protected:
|
|||
|
||||
|
||||
glm::ivec2 _frameSize;
|
||||
int _resolutionLevel{ 0 };
|
||||
};
|
||||
|
||||
using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;
|
||||
|
@ -98,7 +94,7 @@ public:
|
|||
float blurDeviation{ 2.5f };
|
||||
float numSpiralTurns{ 7.0f }; // defining an angle span to distribute the samples ray directions
|
||||
int numSamples{ 11 };
|
||||
int resolutionLevel{ 0 };
|
||||
int resolutionLevel{ 1 };
|
||||
int blurRadius{ 3 }; // 0 means no blurring
|
||||
bool ditheringEnabled{ true }; // randomize the distribution of taps per pixel, should always be true
|
||||
bool borderingEnabled{ true }; // avoid evaluating information from non existing pixels out of the frame, should always be true
|
||||
|
|
|
@ -71,7 +71,7 @@ void LinearDepthFramebuffer::allocate() {
|
|||
// For Linear Depth:
|
||||
_linearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
_linearDepthTexture->autoGenerateMips(1);
|
||||
_linearDepthTexture->autoGenerateMips(5);
|
||||
_linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture);
|
||||
_linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat());
|
||||
|
@ -79,6 +79,7 @@ void LinearDepthFramebuffer::allocate() {
|
|||
// For Downsampling:
|
||||
_halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
_halfLinearDepthTexture->autoGenerateMips(-1);
|
||||
|
||||
_halfNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
|
|
|
@ -133,11 +133,11 @@ float getBlurCoef(int c) {
|
|||
<@func declareSamplingDisk()@>
|
||||
|
||||
float getAngleDitheringWorldPos(in vec3 pixelWorldPos) {
|
||||
vec3 worldPosFract = fract(pixelWorldPos * 0.2);
|
||||
vec3 worldPosFract = fract(pixelWorldPos * 0.4);
|
||||
|
||||
ivec3 pixelPos = ivec3(worldPosFract * 256);
|
||||
|
||||
return isDitheringEnabled() * (3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10 + getFrameDithering();
|
||||
return isDitheringEnabled() * ((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) + (3 * pixelPos.y ^ pixelPos.z + pixelPos.x * pixelPos.z)) * 10 + getFrameDithering();
|
||||
}
|
||||
|
||||
float getAngleDithering(in ivec2 pixelPos) {
|
||||
|
@ -217,7 +217,8 @@ vec3 getTapLocationClamped(int sampleNumber, float spinAngle, float outerRadius,
|
|||
if (redoTap) {
|
||||
tap.xy = tapPos - pixelPos;
|
||||
tap.z = length(tap.xy);
|
||||
}
|
||||
tap.z = 0;
|
||||
}
|
||||
|
||||
return tap;
|
||||
}
|
||||
|
@ -231,8 +232,8 @@ vec3 getTapLocationClamped(int sampleNumber, float spinAngle, float outerRadius,
|
|||
// the depth pyramid texture
|
||||
uniform sampler2D pyramidMap;
|
||||
|
||||
float getZEye(ivec2 pixel) {
|
||||
return -texelFetch(pyramidMap, pixel, getResolutionLevel()).x;
|
||||
float getZEye(ivec2 pixel, int level) {
|
||||
return -texelFetch(pyramidMap, pixel, level).x;
|
||||
}
|
||||
|
||||
const int LOG_MAX_OFFSET = 3;
|
||||
|
@ -269,6 +270,22 @@ vec3 getOffsetPosition(ivec3 side, ivec2 ssC, vec3 tap, vec2 imageSize) {
|
|||
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
<@func declareEvalObscurance()@>
|
||||
|
||||
float evalAO(in vec3 C, in vec3 n_C, in vec3 Q) {
|
||||
vec3 v = Q - C;
|
||||
float vv = dot(v, v);
|
||||
float vn = dot(v, n_C);
|
||||
|
||||
// Fall off function as recommended in SAO paper
|
||||
const float epsilon = 0.01;
|
||||
float f = max(getRadius2() - vv, 0.0);
|
||||
return f * f * f * max((vn - getFalloffBias()) / (epsilon + vv), 0.0);
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareBlurPass(axis)@>
|
||||
|
||||
<$declarePackOcclusionDepth()$>
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<$declareAmbientOcclusion()$>
|
||||
<$declareFetchDepthPyramidMap()$>
|
||||
<$declareSamplingDisk()$>
|
||||
<$declareEvalObscurance()$>
|
||||
|
||||
<$declarePackOcclusionDepth()$>
|
||||
|
||||
|
@ -33,32 +34,23 @@ vec2 getDebugCursorTexcoord(){
|
|||
|
||||
out vec4 outFragColor;
|
||||
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
|
||||
float evalAO(in vec3 C, in vec3 n_C, vec3 Q) {
|
||||
vec3 v = Q - C;
|
||||
float vv = dot(v, v);
|
||||
float vn = dot(v, n_C);
|
||||
|
||||
// Fall off function as recommended in SAO paper
|
||||
const float epsilon = 0.01;
|
||||
float f = max(getRadius2() - vv, 0.0);
|
||||
return f * f * f * max((vn - getFalloffBias()) / (epsilon + vv), 0.0);
|
||||
}
|
||||
|
||||
|
||||
void main(void) {
|
||||
vec2 imageSize = getSideImageSize(getResolutionLevel());
|
||||
|
||||
// In debug adjust the correct frag pixel based on base resolution
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
if (getResolutionLevel() > 0) {
|
||||
fragCoord /= float (1 << getResolutionLevel());
|
||||
}
|
||||
|
||||
// Pixel Debugged
|
||||
vec2 cursorUV = getDebugCursorTexcoord();
|
||||
vec2 imageSize = getSideImageSize(getResolutionLevel());
|
||||
vec2 cursorPixelPos = cursorUV * imageSize;
|
||||
ivec2 ssC = ivec2(cursorPixelPos);
|
||||
// Pixel being shaded
|
||||
//ivec2 ssC = ivec2(gl_FragCoord.xy);
|
||||
|
||||
ivec2 ssC = ivec2(cursorPixelPos);
|
||||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEye(ssC);
|
||||
float Zeye = getZEye(ssC, 0);
|
||||
|
||||
// Stereo side info
|
||||
ivec4 side = getStereoSideInfo(ssC.x, getResolutionLevel());
|
||||
|
@ -74,7 +66,7 @@ void main(void) {
|
|||
// Choose the screen-space sample radius
|
||||
float ssDiskRadius = evalDiskRadius(Cp.z, imageSize);
|
||||
|
||||
vec2 fragToCursor = cursorPixelPos - gl_FragCoord.xy;
|
||||
vec2 fragToCursor = cursorPixelPos - fragCoord.xy;
|
||||
if (dot(fragToCursor,fragToCursor) > ssDiskRadius * ssDiskRadius) {
|
||||
discard;
|
||||
}
|
||||
|
@ -93,7 +85,7 @@ void main(void) {
|
|||
for (int i = 0; i < getNumSamples(); ++i) {
|
||||
vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, cursorPixelPos, imageSize);
|
||||
// The occluding point in camera space
|
||||
vec2 fragToTap = vec2(ssC) + tap.xy - gl_FragCoord.xy;
|
||||
vec2 fragToTap = vec2(ssC) + tap.xy - fragCoord.xy;
|
||||
if (dot(fragToTap,fragToTap) < keepTapRadius) {
|
||||
keep = true;
|
||||
keepedMip = evalMipFromRadius(tap.z);
|
||||
|
@ -101,7 +93,7 @@ void main(void) {
|
|||
|
||||
vec3 Q = getOffsetPosition(side.xyz, ssC, tap, imageSize);
|
||||
|
||||
sum += evalAO(Cp, Cn, Q);
|
||||
sum += float(tap.z > 0.0) * evalAO(Cp, Cn, Q);
|
||||
}
|
||||
|
||||
|
||||
|
@ -134,7 +126,8 @@ void main(void) {
|
|||
// outFragColor = vec4((Cn + vec3(1.0))* 0.5, 1.0);
|
||||
//outFragColor = vec4(vec3(ssDiskRadius / 100.0), 1.0);
|
||||
|
||||
if ((dot(fragToCursor,fragToCursor) < (4.0 * keepTapRadius * keepTapRadius) )) {
|
||||
if ((dot(fragToCursor,fragToCursor) < (100.0 * keepTapRadius * keepTapRadius) )) {
|
||||
// outFragColor = vec4(vec3(A), 1.0);
|
||||
outFragColor = vec4(vec3(A), 1.0);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,41 +13,28 @@
|
|||
<$declareAmbientOcclusion()$>
|
||||
<$declareFetchDepthPyramidMap()$>
|
||||
<$declareSamplingDisk()$>
|
||||
<$declareEvalObscurance()$>
|
||||
|
||||
<$declarePackOcclusionDepth()$>
|
||||
|
||||
|
||||
out vec4 outFragColor;
|
||||
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
|
||||
float evalAO(in vec3 C, in vec3 n_C, in vec3 Q) {
|
||||
vec3 v = Q - C;
|
||||
float vv = dot(v, v);
|
||||
float vn = dot(v, n_C);
|
||||
|
||||
// Fall off function as recommended in SAO paper
|
||||
const float epsilon = 0.01;
|
||||
float f = max(getRadius2() - vv, 0.0);
|
||||
return f * f * f * max((vn - getFalloffBias()) / (epsilon + vv), 0.0);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
// Pixel being shaded
|
||||
ivec2 ssC = ivec2(gl_FragCoord.xy);
|
||||
|
||||
vec2 imageSize = getSideImageSize(getResolutionLevel());
|
||||
|
||||
// Pixel being shaded
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
ivec2 ssC = ivec2(fragCoord.xy);
|
||||
|
||||
// Fetch the z under the pixel (stereo or not)
|
||||
float Zeye = getZEye(ssC);
|
||||
float Zeye = getZEye(ssC, 0);
|
||||
|
||||
// Stereo side info
|
||||
ivec4 side = getStereoSideInfo(ssC.x, getResolutionLevel());
|
||||
|
||||
// From now on, ssC is the pixel pos in the side
|
||||
ssC.x -= side.y;
|
||||
vec2 fragPos = (vec2(ssC) + vec2(0.5)) / vec2(getStereoSideWidth(getResolutionLevel()), getStereoSideHeight(getResolutionLevel()));
|
||||
vec2 fragPos = (vec2(ssC) + vec2(0.5)) / imageSize;
|
||||
|
||||
// The position and normal of the pixel fragment in Eye space
|
||||
vec3 Cp = evalEyePositionFromZeye(side.x, Zeye, fragPos);
|
||||
|
@ -57,7 +44,7 @@ void main(void) {
|
|||
float ssDiskRadius = evalDiskRadius(Cp.z, imageSize);
|
||||
|
||||
// Let's make noise
|
||||
// float randomPatternRotationAngle = getAngleDithering(ssC);
|
||||
//float randomPatternRotationAngle = getAngleDithering(ssC);
|
||||
float randomPatternRotationAngle = getAngleDitheringWorldPos(Cp);
|
||||
|
||||
// Accumulate the Obscurance for each samples
|
||||
|
@ -65,9 +52,9 @@ void main(void) {
|
|||
for (int i = 0; i < getNumSamples(); ++i) {
|
||||
vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, ssC, imageSize);
|
||||
|
||||
vec3 Q = getOffsetPosition(side.xyz, ssC, tap, imageSize);
|
||||
vec3 Q = getOffsetPosition(side.xyz, ssC, tap, imageSize);
|
||||
|
||||
sum += evalAO(Cp, Cn, Q);
|
||||
sum += float(tap.z > 0.0) * evalAO(Cp, Cn, Q);
|
||||
}
|
||||
|
||||
float A = max(0.0, 1.0 - sum * getObscuranceScaling() * 5.0 * getInvNumSamples());
|
||||
|
@ -84,18 +71,4 @@ void main(void) {
|
|||
!>
|
||||
|
||||
outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0);
|
||||
|
||||
// KEEP IT for Debugging
|
||||
// Debug Normal: outFragColor = vec4((Cn + vec3(1.0))* 0.5, 1.0);
|
||||
// Debug Radius outFragColor = vec4(vec3(ssDiskRadius / 100.0), 1.0);
|
||||
// Debug MaxMiplevel outFragColor = vec4(1.0 - vec3(float(clamp(findMSB(int(ssDiskRadius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL))/ float(MAX_MIP_LEVEL)), 1.0);
|
||||
// Debug OffsetPosition
|
||||
// float ssR;
|
||||
// vec2 unitOffset = tapLocation(int(getNumSamples() - 1), 0, ssR);
|
||||
// vec3 Q = getOffsetPosition(side, ssC, unitOffset, ssR * ssDiskRadius);
|
||||
//outFragColor = vec4(vec3(Q.x / 10.0, Q.y / 2.0, -Q.z/ 3.0), 1.0);
|
||||
// vec3 v = normalize(Q - Cp);
|
||||
//outFragColor = vec4((v + vec3(1.0))* 0.5, 1.0);
|
||||
// outFragColor = vec4((Cn + vec3(1.0))* 0.5, 1.0);
|
||||
//outFragColor = vec4(vec3(ssDiskRadius / 100.0), 1.0);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ Column {
|
|||
"Level:obscuranceLevel:1.0:false",
|
||||
"Num Taps:numSamples:32:true",
|
||||
"Taps Spiral:numSpiralTurns:10.0:false",
|
||||
"Falloff Bias:falloffBias:0.2:false",
|
||||
"Blur Radius:blurRadius:10.0:false",
|
||||
]
|
||||
ConfigSlider {
|
||||
|
|
|
@ -24,6 +24,7 @@ Column {
|
|||
"Emissive:LightingModel:enableEmissive",
|
||||
"Lightmap:LightingModel:enableLightmap",
|
||||
"Background:LightingModel:enableBackground",
|
||||
"ssao:AmbientOcclusion:enabled",
|
||||
]
|
||||
CheckBox {
|
||||
text: modelData.split(":")[0]
|
||||
|
|
Loading…
Reference in a new issue