mirror of
https://github.com/lubosz/overte.git
synced 2025-04-25 00:03:16 +02:00
Finally, a clean HBAO!
This commit is contained in:
parent
dee0a6afa2
commit
94a162893a
7 changed files with 134 additions and 105 deletions
|
@ -222,7 +222,7 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
|
|||
#else
|
||||
numSamples{ 16 },
|
||||
#endif
|
||||
resolutionLevel{ 1 },
|
||||
resolutionLevel{ 2 },
|
||||
blurRadius{ 4 },
|
||||
ditheringEnabled{ true },
|
||||
borderingEnabled{ true },
|
||||
|
@ -235,6 +235,9 @@ AmbientOcclusionEffect::AOParameters::AOParameters() {
|
|||
_radiusInfo = { 0.5f, 0.5f * 0.5f, 1.0f / (0.25f * 0.25f * 0.25f), 1.0f };
|
||||
_ditheringInfo = { 0.0f, 0.0f, 0.01f, 1.0f };
|
||||
_sampleInfo = { 11.0f, 1.0f / 11.0f, 7.0f, 1.0f };
|
||||
}
|
||||
|
||||
AmbientOcclusionEffect::BlurParameters::BlurParameters() {
|
||||
_blurInfo = { 1.0f, 3.0f, 2.0f, 0.0f };
|
||||
}
|
||||
|
||||
|
@ -269,14 +272,11 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
|||
current.y = 1.0f / (1.0f - config.falloffAngle);
|
||||
}
|
||||
|
||||
if (config.edgeSharpness != _aoParametersBuffer->getEdgeSharpness()) {
|
||||
auto& current = _aoParametersBuffer.edit()._blurInfo;
|
||||
current.x = config.edgeSharpness;
|
||||
}
|
||||
|
||||
if (config.blurDeviation != _aoParametersBuffer->getBlurDeviation()) {
|
||||
auto& current = _aoParametersBuffer.edit()._blurInfo;
|
||||
current.z = config.blurDeviation;
|
||||
if (config.edgeSharpness != _hblurParametersBuffer.get().getEdgeSharpness()) {
|
||||
auto& hblur = _hblurParametersBuffer.edit()._blurInfo;
|
||||
auto& vblur = _vblurParametersBuffer.edit()._blurInfo;
|
||||
hblur.x = config.edgeSharpness;
|
||||
vblur.x = config.edgeSharpness;
|
||||
}
|
||||
|
||||
if (config.numSpiralTurns != _aoParametersBuffer->getNumSpiralTurns()) {
|
||||
|
@ -327,9 +327,11 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
|||
shouldUpdateBlurs = true;
|
||||
}
|
||||
|
||||
if (config.blurRadius != _aoParametersBuffer.get().getBlurRadius()) {
|
||||
auto& current = _aoParametersBuffer.edit()._blurInfo;
|
||||
current.y = (float)config.blurRadius;
|
||||
if (config.blurRadius != _hblurParametersBuffer.get().getBlurRadius()) {
|
||||
auto& hblur = _hblurParametersBuffer.edit()._blurInfo;
|
||||
auto& vblur = _vblurParametersBuffer.edit()._blurInfo;
|
||||
hblur.y = (float)config.blurRadius;
|
||||
vblur.y = (float)config.blurRadius;
|
||||
}
|
||||
|
||||
if (config.ditheringEnabled != _aoParametersBuffer->isDitheringEnabled()) {
|
||||
|
@ -353,31 +355,47 @@ void AmbientOcclusionEffect::updateBlurParameters() {
|
|||
auto& vblur = _vblurParametersBuffer.edit();
|
||||
auto& hblur = _hblurParametersBuffer.edit();
|
||||
auto frameSize = _framebuffer->getSourceFrameSize();
|
||||
if (_framebuffer->isStereo()) {
|
||||
frameSize.x >>= 1;
|
||||
}
|
||||
const auto occlusionSize = divideRoundUp(frameSize, resolutionScale);
|
||||
|
||||
hblur.scaleHeight.x = 1.0f / frameSize.x;
|
||||
hblur.scaleHeight.y = float(resolutionScale) / frameSize.x;
|
||||
hblur.scaleHeight.z = frameSize.y / resolutionScale;
|
||||
// Occlusion UV limit
|
||||
hblur._blurInfo.z = occlusionSize.x / float(frameSize.x);
|
||||
hblur._blurInfo.w = occlusionSize.y / float(frameSize.y);
|
||||
|
||||
vblur.scaleHeight.x = 1.0f / frameSize.y;
|
||||
vblur.scaleHeight.y = float(resolutionScale) / frameSize.y;
|
||||
vblur.scaleHeight.z = frameSize.y;
|
||||
vblur._blurInfo.z = 1.0f;
|
||||
vblur._blurInfo.w = occlusionSize.y / float(frameSize.y);
|
||||
|
||||
// Depth axis
|
||||
hblur._blurAxis.x = 1.0f / occlusionSize.x;
|
||||
hblur._blurAxis.y = 0.0f;
|
||||
|
||||
vblur._blurAxis.x = 0.0f;
|
||||
vblur._blurAxis.y = 1.0f / occlusionSize.y;
|
||||
|
||||
// Occlusion axis
|
||||
hblur._blurAxis.z = hblur._blurAxis.x * hblur._blurInfo.z;
|
||||
hblur._blurAxis.w = 0.0f;
|
||||
|
||||
vblur._blurAxis.z = 0.0f;
|
||||
vblur._blurAxis.w = vblur._blurAxis.y * vblur._blurInfo.w;
|
||||
}
|
||||
|
||||
void AmbientOcclusionEffect::updateFramebufferSizes() {
|
||||
auto& params = _aoParametersBuffer.edit();
|
||||
const int widthScale = _framebuffer->isStereo() & 1;
|
||||
auto sourceFrameSize = _framebuffer->getSourceFrameSize();
|
||||
const int resolutionLevel = _aoParametersBuffer.get().getResolutionLevel();
|
||||
const float resolutionScale = powf(0.5f, resolutionLevel);
|
||||
// Depth is at maximum half depth
|
||||
const int depthResolutionLevel = std::min(1, resolutionLevel);
|
||||
const float depthResolutionScale = powf(2.0f, depthResolutionLevel);
|
||||
auto normalTextureSize = _framebuffer->getNormalTexture()->getDimensions();
|
||||
auto occlusionDepthFrameSize = divideRoundUp(sourceFrameSize, depthResolutionLevel);
|
||||
auto sourceFrameSideSize = _framebuffer->getSourceFrameSize();
|
||||
sourceFrameSideSize.x >>= widthScale;
|
||||
|
||||
const int resolutionLevel = _aoParametersBuffer.get().getResolutionLevel();
|
||||
// Depth is at maximum half depth
|
||||
const int depthResolutionLevel = getDepthResolutionLevel();
|
||||
const auto occlusionDepthFrameSize = divideRoundUp(sourceFrameSideSize, 1 << depthResolutionLevel);
|
||||
const auto occlusionFrameSize = divideRoundUp(sourceFrameSideSize, 1 << resolutionLevel);
|
||||
auto normalTextureSize = _framebuffer->getNormalTexture()->getDimensions();
|
||||
|
||||
sourceFrameSize.x >>= widthScale;
|
||||
normalTextureSize.x >>= widthScale;
|
||||
occlusionDepthFrameSize.x >>= widthScale;
|
||||
|
||||
params._sideSizes[0].x = normalTextureSize.x;
|
||||
params._sideSizes[0].y = normalTextureSize.y;
|
||||
|
@ -386,7 +404,7 @@ void AmbientOcclusionEffect::updateFramebufferSizes() {
|
|||
|
||||
params._sideSizes[1].x = params._sideSizes[0].x;
|
||||
params._sideSizes[1].y = params._sideSizes[0].y;
|
||||
auto occlusionSplitSize = divideRoundUp(sourceFrameSize, 1 << (resolutionLevel + SSAO_USE_QUAD_SPLIT));
|
||||
auto occlusionSplitSize = divideRoundUp(occlusionFrameSize, SSAO_SPLIT_COUNT);
|
||||
params._sideSizes[1].z = occlusionSplitSize.x;
|
||||
params._sideSizes[1].w = occlusionSplitSize.y;
|
||||
}
|
||||
|
@ -491,7 +509,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
// We need to take the rounded up resolution.
|
||||
auto occlusionViewport = divideRoundUp(sourceViewport, 1 << resolutionLevel);
|
||||
auto firstBlurViewport = sourceViewport;
|
||||
firstBlurViewport.w = divideRoundUp(firstBlurViewport.w, 1 << resolutionLevel);
|
||||
firstBlurViewport.w = occlusionViewport.w;
|
||||
|
||||
if (!_gpuTimer) {
|
||||
_gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__);
|
||||
|
@ -550,9 +568,8 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
|
||||
batch.resetViewTransform();
|
||||
|
||||
Transform model;
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.setModelTransform(model);
|
||||
batch.setModelTransform(Transform());
|
||||
|
||||
batch.pushProfileRange("Depth Mip Generation");
|
||||
// We need this with the mips levels
|
||||
|
@ -578,11 +595,12 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
postPixelOffset.y - prePixelOffset.y,
|
||||
0.0f
|
||||
);
|
||||
Transform model;
|
||||
|
||||
model.setScale(uvScale);
|
||||
model.setTranslation(uvTranslate);
|
||||
batch.setModelTransform(model);
|
||||
}
|
||||
batch.setModelTransform(model);
|
||||
|
||||
// Build face normals pass
|
||||
batch.setViewportTransform(normalViewport);
|
||||
|
@ -608,11 +626,12 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, occlusionNormalTexture);
|
||||
{
|
||||
const auto uvScale = glm::vec3(
|
||||
(splitSize.x * SSAO_SPLIT_COUNT * depthResolutionScale) / (occlusionDepthSize.x * resolutionScale),
|
||||
(splitSize.y * SSAO_SPLIT_COUNT * depthResolutionScale) / (occlusionDepthSize.y * resolutionScale),
|
||||
(splitSize.x * SSAO_SPLIT_COUNT) / float(occlusionViewport.z),
|
||||
(splitSize.y * SSAO_SPLIT_COUNT) / float(occlusionViewport.w),
|
||||
1.0f);
|
||||
const auto postPixelOffset = glm::vec2(0.5f) / glm::vec2(occlusionDepthSize);
|
||||
const auto prePixelOffset = glm::vec2(0.5f * uvScale.x, 0.5f * uvScale.y) / glm::vec2(splitSize.x, splitSize.y);
|
||||
const auto postPixelOffset = glm::vec2(0.5f) / glm::vec2(occlusionViewport.z, occlusionViewport.w);
|
||||
const auto prePixelOffset = glm::vec2(0.5f * uvScale.x, 0.5f * uvScale.y) / glm::vec2(splitSize);
|
||||
Transform model;
|
||||
|
||||
batch.setViewportTransform(splitViewport);
|
||||
|
||||
|
@ -635,13 +654,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
}
|
||||
#else
|
||||
batch.setViewportTransform(occlusionViewport);
|
||||
{
|
||||
const auto uvScale = glm::vec3(
|
||||
(occlusionViewport.z * depthResolutionScale) / (occlusionDepthSize.x * resolutionScale),
|
||||
(occlusionViewport.w * depthResolutionScale) / (occlusionDepthSize.y * resolutionScale),
|
||||
1.0f);
|
||||
model.setScale(uvScale);
|
||||
}
|
||||
model.setIdentity();
|
||||
batch.setModelTransform(model);
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[0]);
|
||||
|
@ -666,8 +679,15 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
PROFILE_RANGE_BATCH(batch, "Bilateral Blur");
|
||||
// Blur 1st pass
|
||||
batch.pushProfileRange("Horizontal");
|
||||
model.setScale(resolutionScale);
|
||||
batch.setModelTransform(model);
|
||||
{
|
||||
const auto uvScale = glm::vec3(
|
||||
occlusionViewport.z / float(sourceViewport.z),
|
||||
occlusionViewport.w / float(sourceViewport.w),
|
||||
1.0f);
|
||||
Transform model;
|
||||
model.setScale(uvScale);
|
||||
batch.setModelTransform(model);
|
||||
}
|
||||
batch.setViewportTransform(firstBlurViewport);
|
||||
batch.setFramebuffer(occlusionBlurredFBO);
|
||||
// Use full resolution depth and normal for bilateral upscaling and blur
|
||||
|
@ -680,8 +700,16 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
|||
|
||||
// Blur 2nd pass
|
||||
batch.pushProfileRange("Vertical");
|
||||
model.setScale(glm::vec3(1.0f, resolutionScale, 1.0f));
|
||||
batch.setModelTransform(model);
|
||||
{
|
||||
const auto uvScale = glm::vec3(
|
||||
1.0f,
|
||||
occlusionViewport.w / float(sourceViewport.w),
|
||||
1.0f);
|
||||
|
||||
Transform model;
|
||||
model.setScale(uvScale);
|
||||
batch.setModelTransform(model);
|
||||
}
|
||||
batch.setViewportTransform(sourceViewport);
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _vblurParametersBuffer);
|
||||
|
|
|
@ -149,14 +149,11 @@ public:
|
|||
float getPerspectiveScale() const { return _resolutionInfo.z; }
|
||||
float getObscuranceLevel() const { return _radiusInfo.w; }
|
||||
float getFalloffAngle() const { return (float)_ditheringInfo.z; }
|
||||
float getEdgeSharpness() const { return (float)_blurInfo.x; }
|
||||
float getBlurDeviation() const { return _blurInfo.z; }
|
||||
|
||||
float getNumSpiralTurns() const { return _sampleInfo.z; }
|
||||
int getNumSamples() const { return (int)_sampleInfo.x; }
|
||||
bool isFetchMipsEnabled() const { return _sampleInfo.w; }
|
||||
|
||||
int getBlurRadius() const { return (int)_blurInfo.y; }
|
||||
bool isDitheringEnabled() const { return _ditheringInfo.x; }
|
||||
bool isBorderingEnabled() const { return _ditheringInfo.w; }
|
||||
};
|
||||
|
@ -165,11 +162,14 @@ public:
|
|||
private:
|
||||
|
||||
// Class describing the uniform buffer with all the parameters common to the bilateral blur shaders
|
||||
class BlurParameters {
|
||||
class BlurParameters : public AmbientOcclusionBlurParams {
|
||||
public:
|
||||
glm::vec4 scaleHeight{ 0.0f };
|
||||
|
||||
BlurParameters() {}
|
||||
BlurParameters();
|
||||
|
||||
float getEdgeSharpness() const { return (float)_blurInfo.x; }
|
||||
int getBlurRadius() const { return (int)_blurInfo.y; }
|
||||
|
||||
};
|
||||
using BlurParametersBuffer = gpu::StructBuffer<BlurParameters>;
|
||||
|
||||
|
|
|
@ -115,14 +115,6 @@ int doFetchMips() {
|
|||
return int(params._sampleInfo.w);
|
||||
}
|
||||
|
||||
float getBlurEdgeSharpness() {
|
||||
return params._blurInfo.x;
|
||||
}
|
||||
|
||||
int getBlurRadius() {
|
||||
return int(params._blurInfo.y);
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
<@func declareSamplingDisk()@>
|
||||
|
@ -247,6 +239,11 @@ float getZEyeAtUV(vec2 texCoord, int level) {
|
|||
return -textureLod(depthPyramidTex, texCoord, level).x;
|
||||
}
|
||||
|
||||
float getZEyeAtUV(ivec4 side, vec2 texCoord, int level) {
|
||||
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side)) * 0.5, isStereo());
|
||||
return getZEyeAtUV(texCoord, level);
|
||||
}
|
||||
|
||||
vec3 getNormalEyeAtUV(vec2 texCoord, int level) {
|
||||
return normalize(textureLod(normalTex, texCoord, level).xyz*2.0 - vec3(1.0));
|
||||
}
|
||||
|
@ -417,37 +414,42 @@ float evalVisibilityHBAO(ivec4 side, vec2 fragUVPos, vec2 invSideImageSize, vec2
|
|||
<@endfunc@>
|
||||
|
||||
|
||||
<@func declareBlurPass(axis)@>
|
||||
<@func declareBlurPass()@>
|
||||
|
||||
<$declarePackOcclusionDepth()$>
|
||||
<$declareAmbientOcclusion()$>
|
||||
<$declareFetchDepthPyramidMap()$>
|
||||
<$declarePackOcclusionDepth()$>
|
||||
|
||||
// the source occlusion texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSAO_OCCLUSION) uniform sampler2D occlusionMap;
|
||||
|
||||
struct BlurParams {
|
||||
vec4 scaleHeight;
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_SSAO_BLUR_PARAMS) uniform blurParamsBuffer {
|
||||
BlurParams blurParams;
|
||||
AmbientOcclusionBlurParams blurParams;
|
||||
};
|
||||
|
||||
float getOcclusionBlurScale() {
|
||||
return blurParams.scaleHeight.x;
|
||||
vec2 getBlurOcclusionAxis() {
|
||||
return blurParams._blurAxis.zw;
|
||||
}
|
||||
|
||||
float getDepthBlurScale() {
|
||||
return blurParams.scaleHeight.y;
|
||||
vec2 getBlurDepthAxis() {
|
||||
return blurParams._blurAxis.xy;
|
||||
}
|
||||
|
||||
int getBlurImageHeight() {
|
||||
return int(blurParams.scaleHeight.z);
|
||||
vec2 getBlurOcclusionUVLimit() {
|
||||
return blurParams._blurInfo.zw;
|
||||
}
|
||||
|
||||
float fetchOcclusion(vec2 coords) {
|
||||
vec3 raw = texture(occlusionMap, coords, 0).xyz;
|
||||
float getBlurEdgeSharpness() {
|
||||
return blurParams._blurInfo.x;
|
||||
}
|
||||
|
||||
int getBlurRadius() {
|
||||
return int(blurParams._blurInfo.y);
|
||||
}
|
||||
|
||||
float fetchOcclusion(ivec4 side, vec2 texCoord) {
|
||||
texCoord.x = mix(texCoord.x, (texCoord.x + getStereoSide(side)) * 0.5, isStereo());
|
||||
vec3 raw = textureLod(occlusionMap, texCoord, 0).xyz;
|
||||
return raw.x;
|
||||
}
|
||||
|
||||
|
@ -458,19 +460,19 @@ float evalBlurCoefficient(vec2 blurScales, float radialDistance, float zDistance
|
|||
return exp2(dot(blurScales, distances*distances));
|
||||
}
|
||||
|
||||
vec2 evalTapWeightedValue(vec2 blurScales, ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) {
|
||||
ivec2 tapOffset = <$axis$> * r;
|
||||
ivec2 tapPixelCoord = destPixelCoord + ivec2(tapOffset);
|
||||
vec2 evalTapWeightedValue(vec2 blurScales, ivec4 side, int r, vec2 occlusionTexCoord, vec2 depthTexCoord, float fragDepth) {
|
||||
vec2 tapOcclusionTexCoord = getBlurOcclusionAxis() * r + occlusionTexCoord;
|
||||
vec2 occlusionTexCoordLimits = getBlurOcclusionUVLimit();
|
||||
|
||||
if ((tapPixelCoord.x < side.y || tapPixelCoord.x >= side.z + side.y) || (tapPixelCoord.y < 0 || tapPixelCoord.y >= getBlurImageHeight())) {
|
||||
if (tapOcclusionTexCoord.x < side.x || tapOcclusionTexCoord.x >= (side.x + occlusionTexCoordLimits.x)
|
||||
|| tapOcclusionTexCoord.y < 0 || tapOcclusionTexCoord.y >= occlusionTexCoordLimits.y) {
|
||||
return vec2(0.0);
|
||||
}
|
||||
|
||||
vec2 tapTexCoord = scaledTexCoord + tapOffset * getOcclusionBlurScale();
|
||||
float tapOcclusion = fetchOcclusion(tapTexCoord);
|
||||
float tapOcclusion = fetchOcclusion(side, tapOcclusionTexCoord);
|
||||
|
||||
tapTexCoord = fullTexCoord + tapOffset * getDepthBlurScale();
|
||||
float tapDepth = getZEyeAtUV(tapTexCoord, 0);
|
||||
vec2 tapDepthTexCoord = getBlurDepthAxis() * r + depthTexCoord;
|
||||
float tapDepth = getZEyeAtUV(side, tapDepthTexCoord, 0);
|
||||
|
||||
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
||||
float zDistance = tapDepth - fragDepth;
|
||||
|
@ -479,11 +481,11 @@ vec2 evalTapWeightedValue(vec2 blurScales, ivec3 side, int r, ivec2 destPixelCoo
|
|||
return vec2(tapOcclusion * weight, weight);
|
||||
}
|
||||
|
||||
vec3 getBlurredOcclusion(ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord) {
|
||||
vec3 getBlurredOcclusion(ivec2 destPixelCoord, vec2 occlusionTexCoord, vec2 depthTexCoord) {
|
||||
// Stereo side info
|
||||
ivec4 side = getStereoSideInfo(destPixelCoord.x, 0);
|
||||
|
||||
float fragDepth = getZEyeAtUV(fullTexCoord, 0);
|
||||
float fragDepth = getZEyeAtUV(side, depthTexCoord, 0);
|
||||
vec2 weightedSums = vec2(0.0);
|
||||
|
||||
// Accumulate weighted contributions along the bluring axis in the [-radius, radius] range
|
||||
|
@ -494,17 +496,17 @@ vec3 getBlurredOcclusion(ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTex
|
|||
|
||||
// negative side first
|
||||
for (int r = -blurRadius; r <= -1; ++r) {
|
||||
weightedSums += evalTapWeightedValue(blurScales, side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth);
|
||||
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, depthTexCoord, fragDepth);
|
||||
}
|
||||
|
||||
// Central pixel contribution
|
||||
float mainWeight = 1.0;
|
||||
float pixelOcclusion = fetchOcclusion(scaledTexCoord);
|
||||
float pixelOcclusion = fetchOcclusion(side, occlusionTexCoord);
|
||||
weightedSums += vec2(pixelOcclusion * mainWeight, mainWeight);
|
||||
|
||||
// then positive side
|
||||
for (int r = 1; r <= blurRadius; ++r) {
|
||||
weightedSums += evalTapWeightedValue(blurScales, side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth);
|
||||
weightedSums += evalTapWeightedValue(blurScales, side, r, occlusionTexCoord, depthTexCoord, fragDepth);
|
||||
}
|
||||
|
||||
// Final normalization
|
||||
|
|
|
@ -28,11 +28,9 @@ 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 / SSAO_SPLIT_COUNT;
|
||||
ivec2 splitImageSize = getWidthHeightRoundUp(getResolutionLevel()+SSAO_SPLIT_LOG2_COUNT);
|
||||
ivec2 modPixelCoord = destPixelCoord % ivec2(SSAO_SPLIT_COUNT);
|
||||
int occlusionMapIndex = modPixelCoord.x + modPixelCoord.y*SSAO_SPLIT_COUNT;
|
||||
vec2 sourceUV = (sourcePixelCoord + vec2(0.5)) / splitImageSize;
|
||||
ivec2 sourcePixelCoord = destPixelCoord >> SSAO_SPLIT_LOG2_COUNT;
|
||||
ivec2 modPixelCoord = destPixelCoord & (SSAO_SPLIT_COUNT-1);
|
||||
int occlusionMapIndex = modPixelCoord.x + (modPixelCoord.y << SSAO_SPLIT_LOG2_COUNT);
|
||||
|
||||
outFragColor = texture(occlusionMaps, vec3(sourceUV, occlusionMapIndex));
|
||||
outFragColor = texelFetch(occlusionMaps, ivec3(sourcePixelCoord, occlusionMapIndex), 0);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
// Hack comment
|
||||
|
||||
const ivec2 horizontal = ivec2(1,0);
|
||||
<$declareBlurPass(horizontal)$>
|
||||
<$declareBlurPass()$>
|
||||
|
||||
layout(location=0) in vec4 varTexCoord0;
|
||||
|
||||
|
|
|
@ -14,14 +14,12 @@
|
|||
|
||||
// Hack comment
|
||||
|
||||
const ivec2 vertical = ivec2(0,1);
|
||||
<$declareBlurPass(vertical)$>
|
||||
<$declareBlurPass()$>
|
||||
|
||||
layout(location=0) in vec4 varTexCoord0;
|
||||
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
float occlusion = getBlurredOcclusion(ivec2(gl_FragCoord.xy), varTexCoord0.xy, varTexCoord0.zw).x;
|
||||
outFragColor = vec4(occlusion, 0.0, 0.0, occlusion);
|
||||
outFragColor = vec4(getBlurredOcclusion(ivec2(gl_FragCoord.xy), varTexCoord0.xy, varTexCoord0.zw), 1.0);
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
// glsl / C++ compatible source as interface for ambient occlusion
|
||||
#ifdef __cplusplus
|
||||
# define SSAO_VEC4 glm::vec4
|
||||
# define SSAO_IVEC4 glm::ivec4
|
||||
# define SSAO_MAT4 glm::mat4
|
||||
#else
|
||||
# define SSAO_VEC4 vec4
|
||||
# define SSAO_IVEC4 ivec4
|
||||
# define SSAO_MAT4 mat4
|
||||
#endif
|
||||
|
||||
struct AmbientOcclusionParams {
|
||||
|
@ -38,7 +38,6 @@ struct AmbientOcclusionParams {
|
|||
SSAO_VEC4 _radiusInfo;
|
||||
SSAO_VEC4 _ditheringInfo;
|
||||
SSAO_VEC4 _sampleInfo;
|
||||
SSAO_VEC4 _blurInfo;
|
||||
SSAO_VEC4 _sideSizes[2];
|
||||
};
|
||||
|
||||
|
@ -46,6 +45,11 @@ struct AmbientOcclusionFrameParams {
|
|||
SSAO_VEC4 _angleInfo;
|
||||
};
|
||||
|
||||
struct AmbientOcclusionBlurParams {
|
||||
SSAO_VEC4 _blurInfo;
|
||||
SSAO_VEC4 _blurAxis;
|
||||
};
|
||||
|
||||
#endif // RENDER_UTILS_SHADER_CONSTANTS_H
|
||||
|
||||
// <@if 1@>
|
||||
|
|
Loading…
Reference in a new issue