improve SSrefr highlights at low roughness

We untonemap/tonemap the first level of blur to reduce the very high
frequencies due to HDR highlights in the image, this produce a softer
image at higher roughness. This can programmatically be turned off,
but that setting is not exposed.
This commit is contained in:
Mathias Agopian
2020-02-12 18:26:44 -08:00
committed by Mathias Agopian
parent 2a1cbe67c6
commit 3de1e197aa
4 changed files with 39 additions and 13 deletions

View File

@@ -729,9 +729,10 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::bilateralBlurPass(FrameGraph
FrameGraphId<FrameGraphTexture> PostProcessManager::generateGaussianMipmap(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, size_t roughnessLodCount,
size_t kernelWidth, float sigmaRatio) noexcept {
bool reinhard, size_t kernelWidth, float sigmaRatio) noexcept {
for (size_t i = 1; i < roughnessLodCount; i++) {
input = gaussianBlurPass(fg, input, i - 1, input, i, kernelWidth, sigmaRatio);
input = gaussianBlurPass(fg, input, i - 1, input, i, reinhard, kernelWidth, sigmaRatio);
reinhard = false; // only do the reinhard filtering on the first level
}
return input;
}
@@ -739,7 +740,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::generateGaussianMipmap(Frame
FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, uint8_t srcLevel,
FrameGraphId<FrameGraphTexture> output, uint8_t dstLevel,
size_t kernelWidth, float sigmaRatio) noexcept {
bool reinhard, size_t kernelWidth, float sigmaRatio) noexcept {
const float sigma = (kernelWidth + 1) / sigmaRatio;
@@ -849,6 +850,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph&
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
mi->setParameter("level", (float)srcLevel);
mi->setParameter("reinhard", reinhard ? uint32_t(1) : uint32_t(0));
mi->setParameter("resolution", float4{
tempDesc.width, tempDesc.height,
1.0f / tempDesc.width, 1.0f / tempDesc.height });

View File

@@ -69,13 +69,13 @@ public:
View::AmbientOcclusionOptions const& options) noexcept;
FrameGraphId<FrameGraphTexture> generateGaussianMipmap(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, size_t roughnessLodCount,
FrameGraphId<FrameGraphTexture> input, size_t roughnessLodCount, bool reinhard,
size_t kernelWidth, float sigmaRatio = 6.0f) noexcept;
FrameGraphId<FrameGraphTexture> gaussianBlurPass(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, uint8_t srcLevel,
FrameGraphId<FrameGraphTexture> output, uint8_t dstLevel,
size_t kernelWidth, float sigma = 6.0f) noexcept;
bool reinhard, size_t kernelWidth, float sigma = 6.0f) noexcept;
backend::Handle<backend::HwTexture> getNoSSAOTexture() const {
return mNoSSAOTexture;

View File

@@ -513,7 +513,7 @@ FrameGraphId<FrameGraphTexture> FRenderer::refractionPass(FrameGraph& fg,
.format = TextureFormat::R11F_G11F_B10F,
});
input = ppm.generateGaussianMipmap(fg, input, roughnessLodCount, kernelSize);
input = ppm.generateGaussianMipmap(fg, input, roughnessLodCount, true, kernelSize);
struct PrepareSSRData {
FrameGraphId<FrameGraphTexture> ssr;

View File

@@ -23,6 +23,10 @@ material {
type : int,
name : count
},
{
type : int,
name : reinhard
},
{
type : float2[32],
name : kernel
@@ -51,19 +55,39 @@ fragment {
sum += s * weight;
}
void tapReinhard(inout vec3 sum, inout float totalWeight, float weight, highp vec2 position) {
vec3 s = textureLod(materialParams_source, position, materialParams.level).rgb;
float w = weight / (1.0 + max3(s));
totalWeight += w;
sum += s * w;
}
void postProcess(inout PostProcessInputs postProcess) {
highp vec2 uv = variable_vertex.xy;
// we handle the center pixel separately
vec3 sum = vec3(0);
tap(sum, materialParams.kernel[0].x, uv);
vec2 offset = materialParams.axis;
for (int i = 1; i < materialParams.count; i++, offset += materialParams.axis * 2.0) {
float k = materialParams.kernel[i].x;
vec2 o = offset + materialParams.axis * materialParams.kernel[i].y;
tap(sum, k, uv + o);
tap(sum, k, uv - o);
if (materialParams.reinhard != 0) {
float totalWeight = 0.0;
tapReinhard(sum, totalWeight, materialParams.kernel[0].x, uv);
vec2 offset = materialParams.axis;
for (int i = 1; i < materialParams.count; i++, offset += materialParams.axis * 2.0) {
float k = materialParams.kernel[i].x;
vec2 o = offset + materialParams.axis * materialParams.kernel[i].y;
tapReinhard(sum, totalWeight, k, uv + o);
tapReinhard(sum, totalWeight, k, uv - o);
}
sum *= 1.0 / totalWeight;
} else {
tap(sum, materialParams.kernel[0].x, uv);
vec2 offset = materialParams.axis;
for (int i = 1; i < materialParams.count; i++, offset += materialParams.axis * 2.0) {
float k = materialParams.kernel[i].x;
vec2 o = offset + materialParams.axis * materialParams.kernel[i].y;
tap(sum, k, uv + o);
tap(sum, k, uv - o);
}
}
postProcess.color.rgb = sum;