More changes

This commit is contained in:
sam 2016-08-06 11:54:54 -07:00
parent e96fd92f32
commit e92e69d963
8 changed files with 68 additions and 115 deletions

View file

@ -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);
});
}

View file

@ -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

View file

@ -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)));

View file

@ -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()$>

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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 {

View file

@ -24,6 +24,7 @@ Column {
"Emissive:LightingModel:enableEmissive",
"Lightmap:LightingModel:enableLightmap",
"Background:LightingModel:enableBackground",
"ssao:AmbientOcclusion:enabled",
]
CheckBox {
text: modelData.split(":")[0]