From aed8c7fcb4a95ff00dc726119f0ecb43f6e2bc8f Mon Sep 17 00:00:00 2001 From: Pixelflinger Date: Fri, 26 Jun 2020 16:57:08 -0700 Subject: [PATCH] DoF: make all function parameter const glslang generate much less code when function parameters are marked const (it also works around a bug where highp intermediate variables are introduced -- but this will be fixed soon). Also remove non-trivial uses of ?: as it also triggers a similar problem in glslang. --- filament/src/materials/dof.mat | 56 +++++++++++++++++----------- filament/src/materials/dofDilate.mat | 4 +- filament/src/materials/dofTiles.mat | 4 +- filament/src/materials/dofUtils.fs | 26 ++++++------- 4 files changed, 51 insertions(+), 39 deletions(-) diff --git a/filament/src/materials/dof.mat b/filament/src/materials/dof.mat index 1763930c5c..a5f4577882 100644 --- a/filament/src/materials/dof.mat +++ b/filament/src/materials/dof.mat @@ -81,14 +81,14 @@ void dummy(){} layout(location = 1) out float outAlpha; -float sampleCount(float ringCount) { +float sampleCount(const float ringCount) { const float ringDensity = float(RING_DENSITY); return ((ringDensity * ringCount * (ringCount - 1.0) + 2.0) * 0.5); } -float sampleWeight(float coc, float mip) { +float sampleWeight(const float coc, const float mip) { #if KERNEL_USE_MIPMAP // When mipmaping is used this creates aliasing artifacts around geometry edges. // Applying the mip correction factor (as below) helps but doesn't solve the issue. @@ -110,7 +110,7 @@ float sampleWeight(float coc, float mip) { #endif } -float intersection(float border, float absCoc, float mip) { +float intersection(const float border, const float absCoc, const float mip) { // there is very little visible difference, so use the cheaper version on mobile #if defined(TARGET_MOBILE) return saturate((absCoc - border) + 0.5); @@ -119,7 +119,7 @@ float intersection(float border, float absCoc, float mip) { #endif } -float rcp(float x) { +float rcp(const float x) { return 1.0 / x; } @@ -147,7 +147,7 @@ void initBucket(out Bucket ring) { ring.coc = 0.0; } -void initRing(float i, float ringCount, float kernelSize, out float count, out mat2 r, out vec2 p) { +void initRing(const float i, const float ringCount, const float kernelSize, out float count, out mat2 r, out vec2 p) { const float ringDensity = float(RING_DENSITY); float radius = (kernelSize / ringCount) * i; count = max(1.0, ringDensity * i); @@ -164,7 +164,7 @@ void initRing(float i, float ringCount, float kernelSize, out float count, out m * Backgorund accumulator */ -void mergeRings(inout Bucket curr, inout Bucket prev, float count) { +void mergeRings(inout Bucket curr, inout Bucket prev, const float count) { if (curr.cw >= MEDIUMP_FLT_MIN) { // "Life of a Bokeh", SIGGRAPH 2018 -- slide 32 // How much the current ring is occluding the previous ring -- we estimate this based @@ -178,7 +178,10 @@ void mergeRings(inout Bucket curr, inout Bucket prev, float count) { float currentRingOpacity = 1.0 - saturate(prev.o * rcp(count)); // Opacity of previous ring - float previousRingWeight = (prev.cw < MEDIUMP_FLT_MIN) ? 0.0 : (1.0 - currentRingOpacity * occluded); + float previousRingWeight = 0.0; + if (prev.cw > MEDIUMP_FLT_MIN) { + previousRingWeight = 1.0 - currentRingOpacity * occluded; + } // merge current ring into previous ring prev.c = prev.c * previousRingWeight + curr.c; @@ -187,7 +190,7 @@ void mergeRings(inout Bucket curr, inout Bucket prev, float count) { } } -void accumulate(inout Bucket curr, inout Bucket prev, Sample tap, float border, float mip, const bool first) { +void accumulate(inout Bucket curr, inout Bucket prev, const Sample tap, const float border, const float mip, const bool first) { float inLayer = isBackground(tap.coc); float coc = abs(tap.coc); float intersects = intersection(border, coc, mip); @@ -219,7 +222,7 @@ void accumulate(inout Bucket curr, inout Bucket prev, Sample tap, float border, } void accumulateBackground(inout Bucket curr, inout Bucket prev, - highp vec2 pos, float border, float mip, const bool first) { + const highp vec2 pos, const float border, const float mip, const bool first) { Sample tap; tap.s = textureLod(materialParams_foreground, pos, mip); tap.coc = textureLod(materialParams_cocFgBg, pos, mip).r; @@ -227,24 +230,24 @@ void accumulateBackground(inout Bucket curr, inout Bucket prev, } void accumulateBackgroundMirror(inout Bucket curr, inout Bucket prev, - highp vec2 center, vec2 offset, float border, float mip, const bool first) { + const highp vec2 center, const vec2 offset, const float border, const float mip, const bool first) { accumulateBackground(curr, prev, center + offset, border, mip, first); accumulateBackground(curr, prev, center - offset, border, mip, first); } void accumulateBackgroundCenter(inout Bucket prev, - highp vec2 pos, float border, float mip) { + const highp vec2 pos, const float border, const float mip) { Bucket curr; initBucket(curr); accumulateBackground(curr, prev, pos, border, mip, false); mergeRings(curr, prev, 1.0); } -void accumulateRing(inout Bucket prev, float i, float ringCount, float kernelSize, - highp vec2 uvCenter, highp vec2 fullResPixelSize, float mip, const bool first) { +void accumulateRing(inout Bucket prev, const float index, const float ringCount, const float kernelSize, + const highp vec2 uvCenter, const highp vec2 fullResPixelSize, const float mip, const bool first) { // we accumulate the larger rings first - i = (ringCount - 1.0) - i; + float i = (ringCount - 1.0) - index; Bucket curr; initBucket(curr); @@ -268,7 +271,7 @@ void accumulateRing(inout Bucket prev, float i, float ringCount, float kernelSiz */ void accumulateForeground(inout vec4 foreground, inout float opacity, inout float i, - highp vec2 pos, float border, float mip) { + const highp vec2 pos, const float border, const float mip) { float coc = textureLod(materialParams_cocFgBg, pos, mip).r; vec4 s = textureLod(materialParams_foreground, pos, mip); float inLayer = isForeground(coc); @@ -280,12 +283,12 @@ void accumulateForeground(inout vec4 foreground, inout float opacity, inout floa } void accumulateForegroundCenter(inout vec4 foreground, inout float opacity, inout float i, - highp vec2 pos, float border, float mip) { + const highp vec2 pos, const float border, const float mip) { accumulateForeground(foreground, opacity, i,pos, border, mip); } void accumulateForegroundMirror(inout vec4 foreground, inout float opacity, inout float i, - highp vec2 center, vec2 offset, float border, float mip) { + const highp vec2 center, const vec2 offset, const float border, const float mip) { // The code below is equivalent to: // accumulateForeground(foreground, opacity, i, center + offset, border, mip); // accumulateForeground(foreground, opacity, i, center - offset, border, mip); @@ -306,7 +309,7 @@ void accumulateForegroundMirror(inout vec4 foreground, inout float opacity, inou i += w * 2.0; } -float getMipLevel(float ringCount, float kernelSize) { +float getMipLevel(const float ringCount, const float kernelSize) { #if KERNEL_USE_MIPMAP float s = 1.0 / (ringCount + 0.5); float mip = log2(kernelSize * s); @@ -415,9 +418,14 @@ void postProcess(inout PostProcessInputs postProcess) { p = r * p; } } - foreground *= c < MEDIUMP_FLT_MIN ? 0.0 : rcp(c); - fgOpacity *= c < MEDIUMP_FLT_MIN ? 0.0 : rcp(sampleCount(ringCountGather)); - //foreground.r += 0.1; + + if (c < MEDIUMP_FLT_MIN) { + foreground *= 0.0; + fgOpacity *= 0.0; + } else { + foreground *= rcp(c); + fgOpacity *= rcp(sampleCount(ringCountGather)); + } } @@ -448,7 +456,11 @@ void postProcess(inout PostProcessInputs postProcess) { background = prev.c; bgOpacity = cocToAlpha(prev.coc); - background *= prev.cw < MEDIUMP_FLT_MIN ? 0.0 : rcp(prev.cw); + if (prev.cw < MEDIUMP_FLT_MIN) { + background *= 0.0; + } else { + background *= rcp(prev.cw); + } //background.g += 0.1; } diff --git a/filament/src/materials/dofDilate.mat b/filament/src/materials/dofDilate.mat index aa0fdf01ce..8922a6bc01 100644 --- a/filament/src/materials/dofDilate.mat +++ b/filament/src/materials/dofDilate.mat @@ -30,11 +30,11 @@ void dummy(){} // Tiles of 16 pixels requires two dilate rounds to accomodate our max Coc of 32 pixels #define TILE_SIZE 16.0 -vec2 tap(ivec2 uv, ivec2 offset) { +vec2 tap(const ivec2 uv, const ivec2 offset) { return texelFetch(materialParams_tiles, uv + offset, 0).rg; } -vec2 dilate(inout vec2 center, vec2 tap) { +vec2 dilate(inout vec2 center, const vec2 tap) { // 2.24 (sqrt(5) is the longest distance between 2 pixels of adjacent tiles). const float maxDistance = max(-MAX_COC_RADIUS, -2.24 * TILE_SIZE); diff --git a/filament/src/materials/dofTiles.mat b/filament/src/materials/dofTiles.mat index d57cde4bbb..3a1e7f3748 100644 --- a/filament/src/materials/dofTiles.mat +++ b/filament/src/materials/dofTiles.mat @@ -25,12 +25,12 @@ fragment { void dummy(){} -float max4(vec4 f) { +float max4(const vec4 f) { vec2 t = max(f.xy, f.zw); return max(t.x, t.y); } -float min4(vec4 f) { +float min4(const vec4 f) { vec2 t = min(f.xy, f.zw); return min(t.x, t.y); } diff --git a/filament/src/materials/dofUtils.fs b/filament/src/materials/dofUtils.fs index c41d4c269d..4dbeac62d0 100644 --- a/filament/src/materials/dofUtils.fs +++ b/filament/src/materials/dofUtils.fs @@ -18,56 +18,56 @@ float random(const highp vec2 w) { return fract(m.z * fract(dot(w, m.xy))); } -float min2(vec2 v) { +float min2(const vec2 v) { return min(v.x, v.y); } -float max2(vec2 v) { +float max2(const vec2 v) { return max(v.x, v.y); } -float max4(vec4 v) { +float max4(const vec4 v) { return max2(max(v.xy, v.zw)); } -float min4(vec4 v) { +float min4(const vec4 v) { return min2(min(v.xy, v.zw)); } -float cocToAlpha(float coc) { +float cocToAlpha(const float coc) { // CoC is positive for background field. // CoC is negative for the foreground field. return saturate(abs(coc) - MAX_IN_FOCUS_COC); } // returns circle-of-confusion diameter in pixels -float getCOC(float depth, vec2 cocParams) { +float getCOC(const float depth, const vec2 cocParams) { return depth * cocParams.x + cocParams.y; } -vec4 getCOC(vec4 depth, vec2 cocParams) { +vec4 getCOC(const vec4 depth, const vec2 cocParams) { return depth * cocParams.x + cocParams.y; } -float isForeground(float coc) { +float isForeground(const float coc) { return coc < 0.0 ? 1.0 : 0.0; } -float isBackground(float coc) { +float isBackground(const float coc) { return coc > 0.0 ? 1.0 : 0.0; } -bool isForegroundTile(vec2 tiles) { +bool isForegroundTile(const vec2 tiles) { // A foreground tile is one where the smallest CoC is negative return tiles.g < 0.0; } -bool isBackgroundTile(vec2 tiles) { +bool isBackgroundTile(const vec2 tiles) { // A background tile is one where the largest CoC is positive return tiles.r > 0.0; } -bool isFastTile(vec2 tiles) { +bool isFastTile(const vec2 tiles) { // We use the distance between the min and max CoC and if the relative error is less than // 5% we assume the tile contains a constant CoC. // We could cannot use the absolute value of the min/mac CoC -- which would categorize more @@ -76,7 +76,7 @@ bool isFastTile(vec2 tiles) { return (tiles.r - tiles.g) <= abs(tiles.r) * 0.05; } -bool isTrivialTile(vec2 tiles) { +bool isTrivialTile(const vec2 tiles) { float maxCocRadius = max(abs(tiles.r), abs(tiles.g)); return maxCocRadius < MAX_IN_FOCUS_COC; }