Revert "workaround another PowerVR compiler bug "

This reverts commit 58f96be2c4.

This caused material files to increase in size significantly. It turns
out that glslang has to generate a copy for each parameter that is
passed to a function as a non-const parameter.


This revert will break IMG devices again, but that should be the case
only on debug builds. Release builds lose the const qualifier by 
virtue of going through spirv. We'll try to address this some other 
way later.
This commit is contained in:
Mathias Agopian
2023-08-25 10:15:01 -07:00
committed by Powei Feng
parent e63dc17f54
commit cd7973bdcf
48 changed files with 280 additions and 268 deletions

View File

@@ -20,7 +20,7 @@
// This substitute for the built-in "mix" function exists to work around #732,
// seen with Vulkan on the Pixel 3 + Android P.
vec4 lerp(vec4 x, vec4 y, float a) {
vec4 lerp(const vec4 x, const vec4 y, float a) {
return x * (1.0 - a) + y * a;
}

View File

@@ -95,7 +95,7 @@ fragment {
#define PREVENT_FLICKERING 0 // FIXME: thin lines disapear
float luma(vec3 color) {
float luma(const vec3 color) {
#if USE_YCoCg
return color.x;
#else
@@ -103,14 +103,14 @@ float luma(vec3 color) {
#endif
}
vec3 RGB_YCoCg(vec3 c) {
vec3 RGB_YCoCg(const vec3 c) {
float Y = dot(c.rgb, vec3( 1, 2, 1) * 0.25);
float Co = dot(c.rgb, vec3( 2, 0, -2) * 0.25);
float Cg = dot(c.rgb, vec3(-1, 2, -1) * 0.25);
return vec3(Y, Co, Cg);
}
vec3 YCoCg_RGB(vec3 c) {
vec3 YCoCg_RGB(const vec3 c) {
float Y = c.x;
float Co = c.y;
float Cg = c.z;
@@ -121,8 +121,8 @@ vec3 YCoCg_RGB(vec3 c) {
}
// clip the (c, h) segment to a box
vec4 clipToBox(int quality,
vec3 boxmin, vec3 boxmax, vec4 c, vec4 h) {
vec4 clipToBox(const int quality,
const vec3 boxmin, const vec3 boxmax, const vec4 c, const vec4 h) {
const float epsilon = 0.0001;
if (quality == BOX_CLIPPING_ACCURATE) {
@@ -144,7 +144,7 @@ vec4 clipToBox(int quality,
// http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details
// Optimized to 5 taps by removing the corner samples
// And modified for mediump support
vec4 sampleTextureCatmullRom(sampler2D tex, highp vec2 uv, highp vec2 texSize) {
vec4 sampleTextureCatmullRom(const sampler2D tex, const highp vec2 uv, const highp vec2 texSize) {
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
// location [1, 1] in the grid, where [0, 0] is the top left corner.

View File

@@ -1,4 +1,4 @@
vec3 colorGrade(mediump sampler3D lut, vec3 x) {
vec3 colorGrade(mediump sampler3D lut, const vec3 x) {
// Alexa LogC EI 1000
const float a = 5.555556;
const float b = 0.047996;

View File

@@ -89,7 +89,7 @@ fragment {
void dummy(){}
float starburst(vec2 uv) {
float starburst(const vec2 uv) {
// get an offset that continuously moves with the camera
vec3 forward = getViewFromWorldMatrix()[2].xyz;
float offset = forward.x + forward.y + forward.z;
@@ -104,7 +104,7 @@ float starburst(vec2 uv) {
return saturate(mask + (1.0 - smoothstep(0.0, 0.3, d)));
}
vec3 bloom(highp vec2 uv, vec3 color) {
vec3 bloom(highp vec2 uv, const vec3 color) {
vec3 result = vec3(0.0);
if (materialParams.bloom.x > 0.0) {
@@ -128,7 +128,7 @@ vec3 bloom(highp vec2 uv, vec3 color) {
return result;
}
vec4 resolveFragment(highp vec2 uv) {
vec4 resolveFragment(const highp vec2 uv) {
#if POST_PROCESS_OPAQUE
return vec4(textureLod(materialParams_colorBuffer, uv, 0.0).rgb, 1.0);
#else

View File

@@ -108,16 +108,16 @@ float ringCountFast() {
return materialParams.ringCounts[2];
}
float sampleCount(float ringCount) {
float sampleCount(const float ringCount) {
float s = (ringCount * 2.0 - 1.0);
return s * s;
}
float computeNeededRings(float kernelSizeInPixel) {
float computeNeededRings(const float kernelSizeInPixel) {
return ceil(kernelSizeInPixel + 0.5);
}
float getMipLevel(float ringCount, float kernelSizeInPixels) {
float getMipLevel(const float ringCount, const float kernelSizeInPixels) {
#if KERNEL_USE_MIPMAP
// note: the 0.5 is to convert from highres to our downslampled texture
float ringDistanceInTexels = kernelSizeInPixels * rcp(ringCount - 0.5);
@@ -140,7 +140,7 @@ float getMipLevel(float ringCount, float kernelSizeInPixels) {
#endif
}
float sampleWeight(float coc, float mip) {
float sampleWeight(const float coc, const float mip) {
// The contribution of sample is inversely proportional to *its* area
// (the larger area, the fainter it is).
// In theory this factor should be 1 / pi * radius^2, however 1/pi is a constant, and
@@ -159,7 +159,7 @@ float sampleWeight(float coc, float mip) {
return (MAX_COC_RADIUS * MAX_COC_RADIUS) / (max(coc * coc, pixelRadiusSquared));
}
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 FILAMENT_QUALITY < FILAMENT_QUALITY_HIGH
return saturate((absCoc - border) + 0.5);
@@ -168,7 +168,7 @@ float intersection(float border, float absCoc, float mip) {
#endif
}
highp vec2 diaphragm(highp vec2 center, vec2 offset) {
highp vec2 diaphragm(const highp vec2 center, const vec2 offset) {
#if DOF_DIAPHRAGM == DOF_DIAPHRAGM_CIRCLE
return center + offset;
#elif DOF_DIAPHRAGM == DOF_DIAPHRAGM_STRAIGHT_BLADES
@@ -217,7 +217,7 @@ void initBucket(out Bucket ring) {
ring.coc = 0.0;
}
void initRing(float i, float ringCount, float kernelSize, vec2 noise,
void initRing(const float i, const float ringCount, const float kernelSize, const vec2 noise,
out float offset, out float count, out mat2 r, out vec2 p) {
float radius = (kernelSize / (ringCount - 0.5)) * i;
@@ -240,7 +240,7 @@ void initRing(float i, float ringCount, float kernelSize, vec2 noise,
offset = length(p + noise);
}
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
@@ -265,8 +265,8 @@ void mergeRings(inout Bucket curr, inout Bucket prev, float count) {
}
}
void accumulate(inout Bucket curr, inout Bucket prev, Sample tap,
float radius, float border, float mip, bool first) {
void accumulate(inout Bucket curr, inout Bucket prev, const Sample tap,
const float radius, const float border, const float mip, const bool first) {
float inLayer = tap.inLayer;
float coc = abs(tap.coc);
float w = inLayer * intersection(radius, coc, mip) * sampleWeight(coc, mip);
@@ -299,8 +299,8 @@ void accumulate(inout Bucket curr, inout Bucket prev, Sample tap,
}
}
void accumulateBackground(inout Bucket curr, inout Bucket prev, highp vec2 pos,
float radius, float border, float mip, bool first) {
void accumulateBackground(inout Bucket curr, inout Bucket prev, const highp vec2 pos,
const float radius, const float border, const float mip, const bool first) {
Sample tap;
tap.s = textureLod(materialParams_color, pos, mip);
tap.coc = textureLod(materialParams_coc, pos, mip).r;
@@ -309,15 +309,15 @@ void accumulateBackground(inout Bucket curr, inout Bucket prev, highp vec2 pos,
}
void accumulateBackgroundMirror(inout Bucket curr, inout Bucket prev,
highp vec2 center, vec2 offset,
float radius, float border, float mip, bool first) {
const highp vec2 center, const vec2 offset,
const float radius, const float border, const float mip, const bool first) {
accumulateBackground(curr, prev, diaphragm(center, offset), radius, border, mip, first);
accumulateBackground(curr, prev, diaphragm(center, -offset), radius, border, mip, first);
}
void accumulateBackgroundCenter(inout Bucket prev,
highp vec2 pos, float ringCount,
float kernelSize, float noiseRadius, float mip) {
const highp vec2 pos, const float ringCount,
const float kernelSize, const float noiseRadius, const float mip) {
Bucket curr;
initBucket(curr);
float border = (kernelSize / (ringCount - 0.5)) * 0.5;
@@ -327,9 +327,9 @@ void accumulateBackgroundCenter(inout Bucket prev,
mergeRings(curr, prev, 1.0);
}
void accumulateRing(inout Bucket prev, float index, float ringCount,
float kernelSize, vec2 noise, highp vec2 uvCenter,
highp vec2 cocToTexelScale, float mip, bool first) {
void accumulateRing(inout Bucket prev, const float index, const float ringCount,
const float kernelSize, const vec2 noise, const highp vec2 uvCenter,
const highp vec2 cocToTexelScale, const float mip, const bool first) {
// we accumulate the larger rings first
float i = (ringCount - 1.0) - index;
@@ -378,12 +378,12 @@ float computeLayer(float coc, vec2 tiles) {
return saturate((coc - tiles.r - frontLayerCocSize) * invTransitionSize);
}
float foregroundFadding(float coc) {
float foregroundFadding(const float coc) {
return saturate(abs(coc) - (MAX_IN_FOCUS_COC - 1.0));
}
void accumulateForeground(inout Layer layer[2], vec2 tiles,
highp vec2 pos, float border, float mip) {
void accumulateForeground(inout Layer layer[2], const vec2 tiles,
const highp vec2 pos, const float border, const float mip) {
float coc = textureLod(materialParams_coc, pos, mip).r;
vec4 s = textureLod(materialParams_color, pos, mip);
@@ -399,13 +399,13 @@ void accumulateForeground(inout Layer layer[2], vec2 tiles,
layer[1].weight += inBackWeight;
}
void accumulateForegroundCenter(inout Layer layer[2], vec2 tiles,
highp vec2 pos, float border, float mip) {
void accumulateForegroundCenter(inout Layer layer[2], const vec2 tiles,
const highp vec2 pos, const float border, const float mip) {
accumulateForeground(layer, tiles, pos, border, mip);
}
void accumulateForegroundMirror(inout Layer layer[2], vec2 tiles,
highp vec2 center, vec2 offset, float border, float mip) {
void accumulateForegroundMirror(inout Layer layer[2], const vec2 tiles,
const highp vec2 center, const vec2 offset, const float border, const float mip) {
// The code below is equivalent to:
// accumulateForeground(layer, tiles, diaphragm(center, offset), border, mip);
// accumulateForeground(layer, tiles, diaphragm(center, -offset), border, mip);
@@ -440,7 +440,7 @@ void accumulateForegroundMirror(inout Layer layer[2], vec2 tiles,
*/
void fastTile(inout vec4 color, inout float alpha,
highp vec2 uv, vec2 tiles, NoiseState noiseState) {
const highp vec2 uv, const vec2 tiles, const NoiseState noiseState) {
highp vec2 cocToTexelScale = materialParams.cocToTexelScale;
float cocToPixelScale = materialParams.cocToPixelScale;
@@ -481,7 +481,7 @@ void fastTile(inout vec4 color, inout float alpha,
}
void foregroundTile(inout vec4 foreground, inout float fgOpacity,
highp vec2 uv, vec2 tiles, NoiseState noiseState) {
const highp vec2 uv, const vec2 tiles, const NoiseState noiseState) {
highp vec2 cocToTexelScale = materialParams.cocToTexelScale;
float cocToPixelScale = materialParams.cocToPixelScale;
@@ -536,7 +536,7 @@ void foregroundTile(inout vec4 foreground, inout float fgOpacity,
}
void backgroundTile(inout vec4 background, inout float bgOpacity,
highp vec2 uv, vec2 tiles, NoiseState noiseState) {
const highp vec2 uv, const vec2 tiles, const NoiseState noiseState) {
highp vec2 cocToTexelScale = materialParams.cocToTexelScale;
float cocToPixelScale = materialParams.cocToPixelScale;

View File

@@ -30,11 +30,11 @@ void dummy(){}
// Size of a tile in full-resolution pixels -- must match tileSize in PostProcessManager.cpp
#define TILE_SIZE 16.0
vec2 tap(vec2 uv, vec2 offset) {
vec2 tap(const vec2 uv, const vec2 offset) {
return textureLod(materialParams_tiles, uv + offset, 0.0).rg;
}
vec2 dilate(inout vec2 center, vec2 tap) {
vec2 dilate(inout vec2 center, const vec2 tap) {
// Tiles that can affect us need to transfer their CoC to us (for the foreground it's
// min(ourCoc, theirCoc) because CoC are negative (the min is the larger radius).
center.r = min(center.r, tap.r);

View File

@@ -32,12 +32,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);
}

View File

@@ -32,12 +32,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);
}

View File

@@ -17,68 +17,68 @@
// Currently our dilate pass is set-up for 32 max.
#define MAX_COC_RADIUS 32.0
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 rcp(float x) {
float rcp(const float x) {
return 1.0 / x;
}
float rcpOrZero(float x) {
float rcpOrZero(const float x) {
return x > MEDIUMP_FLT_MIN ? (1.0 / x) : 0.0;
}
highp float rcpOrZeroHighp(highp float x) {
highp float rcpOrZeroHighp(const highp float x) {
return x > MEDIUMP_FLT_MIN ? (1.0 / x) : 0.0;
}
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.r < 0.0;
}
bool isBackgroundTile(vec2 tiles) {
bool isBackgroundTile(const vec2 tiles) {
// A background tile is one where the largest CoC is positive
return tiles.g > 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
@@ -87,19 +87,19 @@ bool isFastTile(vec2 tiles) {
return (tiles.g - tiles.r) <= abs(tiles.g) * 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;
}
float downsampleCoC(vec4 c) {
float downsampleCoC(const vec4 c) {
// We need to compute a suitable CoC to represent the 4 pixels that are downsampled.
// We pick the min because this always selects the most foreground sample if there is one,
// because the foreground can leak on the background, but not the reverse.
return min4(c);
}
vec4 downsampleCocWeights(vec4 c, float outCoc, float scale) {
vec4 downsampleCocWeights(const vec4 c, const float outCoc, const float scale) {
// The bilateral weight is normally computed as saturate(1 - |outCoc - c|) which selects
// the sample with the outCoc weight (and does a little bit of cross-fade if other samples
// are close). However, this can also cause some aliasing with dithered objects, so by

View File

@@ -78,15 +78,15 @@ fragment {
void dummy(){ }
float smoothstep01(float t) {
float smoothstep01(const float t) {
return t * t * (3.0 - 2.0 * t);
}
float ring(float x, float c, float r) {
float ring(float x, const float c, const float r) {
return 1.0 - smoothstep01(min(abs(x - c) / r, 1.0));
}
vec3 sampleColor(vec2 uv) {
vec3 sampleColor(const vec2 uv) {
// because we work on reduced resolution, we assume mediump uv is enough.
float level = materialParams.level;
float chromaticAberration = materialParams.chromaticAberration;
@@ -99,7 +99,7 @@ vec3 sampleColor(vec2 uv) {
);
}
vec3 ghosts(vec2 vertex_uv) {
vec3 ghosts(const vec2 vertex_uv) {
// because we work on reduced resolution, we assume mediump uv is enough.
float ghostSpacing = materialParams.ghostSpacing;
float ghostCount = materialParams.ghostCount;
@@ -116,7 +116,7 @@ vec3 ghosts(vec2 vertex_uv) {
return color;
}
vec3 halo(vec2 uv) {
vec3 halo(const vec2 uv) {
float haloRadius = materialParams.haloRadius;
float haloThickness = materialParams.haloThickness;
float threshold = materialParams.threshold.y;

View File

@@ -72,7 +72,7 @@ fragment {
#if defined(FILAMENT_HAS_FEATURE_TEXTURE_GATHER)
#define gather textureGather
#else
vec4 gather(mediump sampler2D color, highp vec2 p, int comp) {
vec4 gather(const mediump sampler2D color, highp vec2 p, const int comp) {
highp ivec2 i = ivec2(p * materialParams.textureSize - 0.5);
vec4 d;
d[0] = texelFetchOffset(color, i, 0, ivec2(0, 1))[comp];

View File

@@ -75,7 +75,7 @@ fragment {
#if defined(FILAMENT_HAS_FEATURE_TEXTURE_GATHER)
#define gather textureGather
#else
vec4 gather(mediump sampler2D color, highp vec2 p, int comp) {
vec4 gather(const mediump sampler2D color, highp vec2 p, const int comp) {
highp ivec2 i = ivec2(p * materialParams.textureSize - 0.5);
vec4 d;
d[0] = texelFetchOffset(color, i, 0, ivec2(0, 1))[comp];

View File

@@ -76,7 +76,7 @@ fragment {
#if defined(FILAMENT_HAS_FEATURE_TEXTURE_GATHER)
#define gather textureGather
#else
vec4 gather(mediump sampler2D color, highp vec2 p, int comp) {
vec4 gather(const mediump sampler2D color, highp vec2 p, const int comp) {
highp ivec2 i = ivec2(p * materialParams.textureSize - 0.5);
vec4 d;
d[0] = texelFetchOffset(color, i, 0, ivec2(0, 1))[comp];

View File

@@ -1,8 +1,8 @@
float vmax(float v) {
float vmax(const float v) {
return v;
}
highp vec4 sourceTexLod(highp vec2 p, float m, float l) {
highp vec4 sourceTexLod(const highp vec2 p, float m, float l) {
// This condition is optimized away at compile-time.
if (materialConstants_arraySampler) {
return textureLod(materialParams_sourceArray, vec3(p, l), m);
@@ -11,12 +11,12 @@ highp vec4 sourceTexLod(highp vec2 p, float m, float l) {
}
}
void tap(inout highp vec4 sum, float weight, highp vec2 position) {
void tap(inout highp vec4 sum, const float weight, const highp vec2 position) {
highp vec4 s = sourceTexLod(position, materialParams.level, materialParams.layer);
sum += s * weight;
}
void tapReinhard(inout highp vec4 sum, inout float totalWeight, float weight, highp vec2 position) {
void tapReinhard(inout highp vec4 sum, inout float totalWeight, const float weight, const highp vec2 position) {
highp vec4 s = sourceTexLod(position, materialParams.level, materialParams.layer);
float w = weight / (1.0 + vmax(s));
totalWeight += w;

View File

@@ -48,7 +48,7 @@ fragment {
return max(0.0, 1.0 - diff * diff);
}
void tap(highp sampler2DArray saoTexture,
void tap(const highp sampler2DArray saoTexture,
inout float sum, inout float totalWeight, float weight, float depth, vec2 position) {
// ambient occlusion sample
vec3 data = textureLod(saoTexture, vec3(position, 0.0), 0.0).rgb;

View File

@@ -60,14 +60,14 @@ fragment {
return max(0.0, 1.0 - diff * diff);
}
void tapAO(highp sampler2DArray saoTexture, highp vec2 uv,
void tapAO(const highp sampler2DArray saoTexture, highp vec2 uv,
out float ao, out highp float sampleDepth) {
vec3 data = textureLod(saoTexture, vec3(uv, 0.0), 0.0).rgb;
ao = data.r;
sampleDepth = unpack(data.gb);
}
void tapBN(highp sampler2DArray saoTexture, highp vec2 uv,
void tapBN(const highp sampler2DArray saoTexture, highp vec2 uv,
out vec3 bentNormal) {
vec3 data = textureLod(saoTexture, vec3(uv, 1.0), 0.0).xyz;
bentNormal = unpackBentNormal(data);

View File

@@ -34,14 +34,14 @@ const float kLog2LodRate = 3.0;
// "The Alchemy Screen-Space Ambient Obscurance Algorithm" by Morgan McGuire
// "Scalable Ambient Obscurance" by Morgan McGuire, Michael Mara and David Luebke
vec3 tapLocation(float i, float noise) {
vec3 tapLocation(float i, const float noise) {
float offset = ((2.0 * PI) * 2.4) * noise;
float angle = ((i * materialParams.sampleCount.y) * materialParams.spiralTurns) * (2.0 * PI) + offset;
float radius = (i + noise + 0.5) * materialParams.sampleCount.y;
return vec3(cos(angle), sin(angle), radius * radius);
}
highp vec2 startPosition(float noise) {
highp vec2 startPosition(const float noise) {
float angle = ((2.0 * PI) * 2.4) * noise;
return vec2(cos(angle), sin(angle));
}
@@ -51,15 +51,15 @@ highp mat2 tapAngleStep() {
return mat2(t.x, t.y, -t.y, t.x);
}
vec3 tapLocationFast(float i, vec2 p, float noise) {
vec3 tapLocationFast(float i, vec2 p, const float noise) {
float radius = (i + noise + 0.5) * materialParams.sampleCount.y;
return vec3(p, radius * radius);
}
void computeAmbientOcclusionSAO(inout float occlusion, inout vec3 bentNormal,
float i, float ssDiskRadius,
highp vec2 uv, highp vec3 origin, vec3 normal,
vec2 tapPosition, float noise) {
const highp vec2 uv, const highp vec3 origin, const vec3 normal,
const vec2 tapPosition, const float noise) {
vec3 tap = tapLocationFast(i, tapPosition, noise);

View File

@@ -52,7 +52,7 @@ struct ConeTraceSetup {
uint sampleCount;
};
highp float getWFromProjectionMatrix(highp mat4 p, vec3 v) {
highp float getWFromProjectionMatrix(const highp mat4 p, const vec3 v) {
// this essentially returns (p * vec4(v, 1.0)).w, but we make some assumptions
// this assumes a perspective projection
return -v.z;
@@ -60,14 +60,14 @@ highp float getWFromProjectionMatrix(highp mat4 p, vec3 v) {
//return p[2][3] * v.z + p[3][3];
}
highp float getViewSpaceZFromW(highp mat4 p, float w) {
highp float getViewSpaceZFromW(const highp mat4 p, const float w) {
// this assumes a perspective projection
return -w;
// this assumes a perspective or ortho projection
//return (w - p[3][3]) / p[2][3];
}
float coneTraceOcclusion(in ConeTraceSetup setup, highp sampler2D depthTexture) {
float coneTraceOcclusion(in ConeTraceSetup setup, const highp sampler2D depthTexture) {
// skip fragments that are back-facing trace direction
// (avoid overshadowing of translucent surfaces)
float NoL = dot(setup.vsNormal, setup.vsConeDirection);
@@ -138,7 +138,7 @@ float coneTraceOcclusion(in ConeTraceSetup setup, highp sampler2D depthTexture)
}
float ssctDominantLightShadowing(highp vec2 uv, highp vec3 origin, vec3 normal,
highp sampler2D depthTexture, highp vec2 fragCoord,
const highp sampler2D depthTexture, const highp vec2 fragCoord,
vec2 rayCount, ConeTraceSetup cone) {
float occlusion = 0.0;

View File

@@ -28,12 +28,12 @@ highp float linearizeDepth(highp float depth) {
return (depth * p[2].z + p[3].z) / max(depth * p[2].w + p[3].w, preventDiv0);
}
highp float sampleDepth(highp sampler2D depthTexture, highp vec2 uv, float lod) {
highp float sampleDepth(const highp sampler2D depthTexture, const highp vec2 uv, float lod) {
return textureLod(depthTexture, uvToRenderTargetUV(uv), lod).r;
}
highp float sampleDepthLinear(highp sampler2D depthTexture,
highp vec2 uv, float lod) {
highp float sampleDepthLinear(const highp sampler2D depthTexture,
const highp vec2 uv, float lod) {
return linearizeDepth(sampleDepth(depthTexture, uv, lod));
}

View File

@@ -36,7 +36,7 @@ highp vec3 faceNormal(highp vec3 dpdx, highp vec3 dpdy) {
// this creates arifacts around geometry edges.
// Note: when using the spirv optimizer, this results in much slower execution time because
// this whole expression is inlined in the AO loop below.
highp vec3 computeViewSpaceNormalLowQ(highp vec3 position) {
highp vec3 computeViewSpaceNormalLowQ(const highp vec3 position) {
return faceNormal(dFdx(position), dFdy(position));
}
@@ -52,8 +52,8 @@ highp vec3 computeViewSpaceNormalLowQ(highp vec3 position) {
// positionParams : invProjection[0][0] * 2, invProjection[1][1] * 2
//
highp vec3 computeViewSpaceNormalMediumQ(
highp sampler2D depthTexture, highp vec2 uv,
highp vec3 position,
const highp sampler2D depthTexture, const highp vec2 uv,
const highp vec3 position,
highp vec2 texel, highp vec2 positionParams) {
precision highp float;
@@ -81,8 +81,8 @@ highp vec3 computeViewSpaceNormalMediumQ(
// positionParams : invProjection[0][0] * 2, invProjection[1][1] * 2
//
highp vec3 computeViewSpaceNormalHighQ(
highp sampler2D depthTexture, highp vec2 uv,
highp float depth, highp vec3 position,
const highp sampler2D depthTexture, const highp vec2 uv,
const highp float depth, const highp vec3 position,
highp vec2 texel, highp vec2 positionParams) {
precision highp float;
@@ -125,8 +125,8 @@ highp vec3 computeViewSpaceNormalHighQ(
// positionParams : invProjection[0][0] * 2, invProjection[1][1] * 2
//
highp vec3 computeViewSpaceNormal(
highp sampler2D depthTexture, highp vec2 uv,
highp float depth, highp vec3 position,
const highp sampler2D depthTexture, const highp vec2 uv,
const highp float depth, const highp vec3 position,
highp vec2 texel, highp vec2 positionParams) {
// todo: maybe make this a quality parameter
#if FILAMENT_QUALITY == FILAMENT_QUALITY_HIGH

View File

@@ -139,7 +139,7 @@ vec3 unpackBentNormal(vec3 bn) {
return bn * 2.0 - 1.0;
}
float specularAO(float NoV, float visibility, float roughness, SSAOInterpolationCache cache) {
float specularAO(float NoV, float visibility, float roughness, const in SSAOInterpolationCache cache) {
float specularAO = 1.0;
// SSAO is not applied when blending is enabled
@@ -200,7 +200,7 @@ float specularAO(float NoV, float visibility, float roughness, SSAOInterpolation
* The albedo term is meant to be the diffuse color or f0 for the diffuse and
* specular terms respectively.
*/
vec3 gtaoMultiBounce(float visibility, vec3 albedo) {
vec3 gtaoMultiBounce(float visibility, const vec3 albedo) {
// Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"
vec3 a = 2.0404 * albedo - 0.3324;
vec3 b = -4.7951 * albedo + 0.6417;
@@ -210,13 +210,13 @@ vec3 gtaoMultiBounce(float visibility, vec3 albedo) {
}
#endif
void multiBounceAO(float visibility, vec3 albedo, inout vec3 color) {
void multiBounceAO(float visibility, const vec3 albedo, inout vec3 color) {
#if MULTI_BOUNCE_AMBIENT_OCCLUSION == 1
color *= gtaoMultiBounce(visibility, albedo);
#endif
}
void multiBounceSpecularAO(float visibility, vec3 albedo, inout vec3 color) {
void multiBounceSpecularAO(float visibility, const vec3 albedo, inout vec3 color) {
#if MULTI_BOUNCE_AMBIENT_OCCLUSION == 1 && SPECULAR_AMBIENT_OCCLUSION != SPECULAR_AO_OFF
color *= gtaoMultiBounce(visibility, albedo);
#endif

View File

@@ -51,7 +51,7 @@
// Specular BRDF implementations
//------------------------------------------------------------------------------
float D_GGX(float roughness, float NoH, vec3 h) {
float D_GGX(float roughness, float NoH, const vec3 h) {
// Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
// In mediump, there are two problems computing 1.0 - NoH^2
@@ -138,12 +138,12 @@ float V_Neubelt(float NoV, float NoL) {
return saturateMediump(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));
}
vec3 F_Schlick(vec3 f0, float f90, float VoH) {
vec3 F_Schlick(const vec3 f0, float f90, float VoH) {
// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
return f0 + (f90 - f0) * pow5(1.0 - VoH);
}
vec3 F_Schlick(vec3 f0, float VoH) {
vec3 F_Schlick(const vec3 f0, float VoH) {
float f = pow(1.0 - VoH, 5.0);
return f + f0 * (1.0 - f);
}
@@ -156,7 +156,7 @@ float F_Schlick(float f0, float f90, float VoH) {
// Specular BRDF dispatch
//------------------------------------------------------------------------------
float distribution(float roughness, float NoH, vec3 h) {
float distribution(float roughness, float NoH, const vec3 h) {
#if BRDF_SPECULAR_D == SPECULAR_D_GGX
return D_GGX(roughness, NoH, h);
#endif
@@ -170,7 +170,7 @@ float visibility(float roughness, float NoV, float NoL) {
#endif
}
vec3 fresnel(vec3 f0, float LoH) {
vec3 fresnel(const vec3 f0, float LoH) {
#if BRDF_SPECULAR_F == SPECULAR_F_SCHLICK
#if FILAMENT_QUALITY == FILAMENT_QUALITY_LOW
return F_Schlick(f0, LoH); // f90 = 1.0
@@ -196,7 +196,7 @@ float visibilityAnisotropic(float roughness, float at, float ab,
#endif
}
float distributionClearCoat(float roughness, float NoH, vec3 h) {
float distributionClearCoat(float roughness, float NoH, const vec3 h) {
#if BRDF_CLEAR_COAT_D == SPECULAR_D_GGX
return D_GGX(roughness, NoH, h);
#endif

View File

@@ -22,3 +22,13 @@
#define float3x3 mat3
#define float4x4 mat4
// To workaround an adreno crash (#5294), we need ensure that a method with
// parameter 'const mat4' does not call another method also with a 'const mat4'
// parameter (i.e. mulMat4x4Float3). So we remove the const modifier for
// materials compiled for vulkan+mobile.
#if defined(TARGET_VULKAN_ENVIRONMENT) && defined(TARGET_MOBILE)
#define highp_mat4 highp mat4
#else
#define highp_mat4 const highp mat4
#endif

View File

@@ -70,7 +70,7 @@ highp float getUserTimeMod(float m) {
*
* @public-api
*/
highp vec2 uvToRenderTargetUV(highp vec2 uv) {
highp vec2 uvToRenderTargetUV(const highp vec2 uv) {
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
return vec2(uv.x, 1.0 - uv.y);
#else

View File

@@ -8,7 +8,7 @@
*
* @public-api
*/
float luminance(vec3 linear) {
float luminance(const vec3 linear) {
return dot(linear, vec3(0.2126, 0.7152, 0.0722));
}
@@ -16,7 +16,7 @@ float luminance(vec3 linear) {
* Computes the pre-exposed intensity using the specified intensity and exposure.
* This function exists to force highp precision on the two parameters
*/
float computePreExposedIntensity(highp float intensity, highp float exposure) {
float computePreExposedIntensity(const highp float intensity, const highp float exposure) {
return intensity * exposure;
}
@@ -47,7 +47,7 @@ vec3 ycbcrToRgb(float luminance, vec2 cbcr) {
/*
* The input must be in the [0, 1] range.
*/
vec3 Inverse_Tonemap_Filmic(vec3 x) {
vec3 Inverse_Tonemap_Filmic(const vec3 x) {
return (0.03 - 0.59 * x - sqrt(0.0009 + 1.3702 * x - 1.0127 * x * x)) / (-5.02 + 4.86 * x);
}
@@ -94,7 +94,7 @@ vec3 decodeRGBM(vec4 c) {
// returns the frag coord in the GL convention with (0, 0) at the bottom-left
// resolution : width, height
highp vec2 getFragCoord(highp vec2 resolution) {
highp vec2 getFragCoord(const highp vec2 resolution) {
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
return vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y);
#else

View File

@@ -82,7 +82,7 @@ float computeMicroShadowing(float NoL, float visibility) {
* direction to match reference renderings when the roughness increases
*/
vec3 getReflectedVector(PixelParams pixel, vec3 v, vec3 n) {
vec3 getReflectedVector(const PixelParams pixel, const vec3 v, const vec3 n) {
#if defined(MATERIAL_HAS_ANISOTROPY)
vec3 anisotropyDirection = pixel.anisotropy >= 0.0 ? pixel.anisotropicB : pixel.anisotropicT;
vec3 anisotropicTangent = cross(anisotropyDirection, v);
@@ -97,7 +97,7 @@ vec3 getReflectedVector(PixelParams pixel, vec3 v, vec3 n) {
return r;
}
void getAnisotropyPixelParams(MaterialInputs material, inout PixelParams pixel) {
void getAnisotropyPixelParams(const MaterialInputs material, inout PixelParams pixel) {
#if defined(MATERIAL_HAS_ANISOTROPY)
vec3 direction = material.anisotropyDirection;
pixel.anisotropy = material.anisotropy;

View File

@@ -14,11 +14,11 @@ float clampNoV(float NoV) {
return max(NoV, MIN_N_DOT_V);
}
vec3 computeDiffuseColor(vec4 baseColor, float metallic) {
vec3 computeDiffuseColor(const vec4 baseColor, float metallic) {
return baseColor.rgb * (1.0 - metallic);
}
vec3 computeF0(vec4 baseColor, float metallic, float reflectance) {
vec3 computeF0(const vec4 baseColor, float metallic, float reflectance) {
return baseColor.rgb * metallic + (reflectance * (1.0 - metallic));
}
@@ -26,7 +26,7 @@ float computeDielectricF0(float reflectance) {
return 0.16 * reflectance * reflectance;
}
float computeMetallicFromSpecularColor(vec3 specularColor) {
float computeMetallicFromSpecularColor(const vec3 specularColor) {
return max3(specularColor);
}
@@ -51,7 +51,7 @@ float f0ToIor(float f0) {
return (1.0 + r) / (1.0 - r);
}
vec3 f0ClearCoatToSurface(vec3 f0) {
vec3 f0ClearCoatToSurface(const vec3 f0) {
// Approximation of iorTof0(f0ToIor(f0), 1.5)
// This assumes that the clear coat layer has an IOR of 1.5
#if FILAMENT_QUALITY == FILAMENT_QUALITY_LOW

View File

@@ -53,19 +53,19 @@ float sq(float x) {
*
* @public-api
*/
float max3(vec3 v) {
float max3(const vec3 v) {
return max(v.x, max(v.y, v.z));
}
float vmax(vec2 v) {
float vmax(const vec2 v) {
return max(v.x, v.y);
}
float vmax(vec3 v) {
float vmax(const vec3 v) {
return max(v.x, max(v.y, v.z));
}
float vmax(vec4 v) {
float vmax(const vec4 v) {
return max(max(v.x, v.y), max(v.y, v.z));
}
@@ -74,19 +74,19 @@ float vmax(vec4 v) {
*
* @public-api
*/
float min3(vec3 v) {
float min3(const vec3 v) {
return min(v.x, min(v.y, v.z));
}
float vmin(vec2 v) {
float vmin(const vec2 v) {
return min(v.x, v.y);
}
float vmin(vec3 v) {
float vmin(const vec3 v) {
return min(v.x, min(v.y, v.z));
}
float vmin(vec4 v) {
float vmin(const vec4 v) {
return min(min(v.x, v.y), min(v.y, v.z));
}
@@ -126,7 +126,7 @@ float acosFastPositive(float x) {
*
* @public-api
*/
highp vec4 mulMat4x4Float3(highp mat4 m, highp vec3 v) {
highp vec4 mulMat4x4Float3(const highp mat4 m, const highp vec3 v) {
return v.x * m[0] + (v.y * m[1] + (v.z * m[2] + m[3]));
}
@@ -136,14 +136,14 @@ highp vec4 mulMat4x4Float3(highp mat4 m, highp vec3 v) {
*
* @public-api
*/
highp vec3 mulMat3x3Float3(highp mat4 m, highp vec3 v) {
highp vec3 mulMat3x3Float3(const highp mat4 m, const highp vec3 v) {
return v.x * m[0].xyz + (v.y * m[1].xyz + (v.z * m[2].xyz));
}
/**
* Extracts the normal vector of the tangent frame encoded in the specified quaternion.
*/
void toTangentFrame(highp vec4 q, out highp vec3 n) {
void toTangentFrame(const highp vec4 q, out highp vec3 n) {
n = vec3( 0.0, 0.0, 1.0) +
vec3( 2.0, -2.0, -2.0) * q.x * q.zwx +
vec3( 2.0, 2.0, -2.0) * q.y * q.wzy;
@@ -153,14 +153,14 @@ void toTangentFrame(highp vec4 q, out highp vec3 n) {
* Extracts the normal and tangent vectors of the tangent frame encoded in the
* specified quaternion.
*/
void toTangentFrame(highp vec4 q, out highp vec3 n, out highp vec3 t) {
void toTangentFrame(const highp vec4 q, out highp vec3 n, out highp vec3 t) {
toTangentFrame(q, n);
t = vec3( 1.0, 0.0, 0.0) +
vec3(-2.0, 2.0, -2.0) * q.y * q.yxw +
vec3(-2.0, 2.0, 2.0) * q.z * q.zwx;
}
highp mat3 cofactor(highp mat3 m) {
highp mat3 cofactor(const highp mat3 m) {
highp float a = m[0][0];
highp float b = m[1][0];
highp float c = m[2][0];

View File

@@ -11,8 +11,8 @@
* Normal bias is not used for VSM.
*/
highp vec4 computeLightSpacePosition(highp vec3 p, highp vec3 n,
highp vec3 dir, float b, highp mat4 lightFromWorldMatrix) {
highp vec4 computeLightSpacePosition(highp vec3 p, const highp vec3 n,
const highp vec3 dir, const float b, highp_mat4 lightFromWorldMatrix) {
#if !defined(VARIANT_HAS_VSM)
highp float cosTheta = saturate(dot(n, dir));

View File

@@ -20,7 +20,7 @@ layout(location = 0) out highp vec2 outPicking;
// note: VARIANT_HAS_VSM and VARIANT_HAS_PICKING are mutually exclusive
//------------------------------------------------------------------------------
highp vec2 computeDepthMomentsVSM(highp float depth);
highp vec2 computeDepthMomentsVSM(const highp float depth);
void main() {
filament_lodBias = frameUniforms.lodBias;
@@ -74,7 +74,7 @@ void main() {
#endif
}
highp vec2 computeDepthMomentsVSM(highp float depth) {
highp vec2 computeDepthMomentsVSM(const highp float depth) {
// computes the moments
// See GPU Gems 3
// https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-8-summed-area-variance-shadow-maps

View File

@@ -30,7 +30,7 @@ float triangleNoise(highp vec2 n) {
// Dithering
//------------------------------------------------------------------------------
vec4 Dither_InterleavedGradientNoise(vec4 rgba, highp float temporalNoise01) {
vec4 Dither_InterleavedGradientNoise(vec4 rgba, const highp float temporalNoise01) {
// Jimenez 2014, "Next Generation Post-Processing in Call of Duty"
highp vec2 uv = gl_FragCoord.xy + temporalNoise01;
@@ -43,7 +43,7 @@ vec4 Dither_InterleavedGradientNoise(vec4 rgba, highp float temporalNoise01) {
return rgba + vec4(noise / 255.0);
}
vec4 Dither_TriangleNoise(vec4 rgba, highp float temporalNoise01) {
vec4 Dither_TriangleNoise(vec4 rgba, const highp float temporalNoise01) {
// Gjøl 2016, "Banding in Games: A Noisy Rant"
highp vec2 fragCoord = gl_FragCoord.xy;
// FIXME: resolution.zw is the viewport dimension but we should be using the buffer's
@@ -58,7 +58,7 @@ vec4 Dither_TriangleNoise(vec4 rgba, highp float temporalNoise01) {
return rgba + vec4(noise / 255.0);
}
vec4 Dither_Vlachos(vec4 rgba, highp float temporalNoise01) {
vec4 Dither_Vlachos(vec4 rgba, const highp float temporalNoise01) {
// Vlachos 2016, "Advanced VR Rendering"
highp vec2 fragCoord = gl_FragCoord.xy;
float noise = dot(vec2(171.0, 231.0), fragCoord + temporalNoise01);
@@ -70,7 +70,7 @@ vec4 Dither_Vlachos(vec4 rgba, highp float temporalNoise01) {
return vec4(rgba.rgb + (noiseRGB / 255.0), rgba.a);
}
vec4 Dither_TriangleNoiseRGB(vec4 rgba, highp float temporalNoise01) {
vec4 Dither_TriangleNoiseRGB(vec4 rgba, const highp float temporalNoise01) {
// Gjøl 2016, "Banding in Games: A Noisy Rant"
highp vec2 fragCoord = gl_FragCoord.xy;
// FIXME: resolution.zw is the viewport dimension but we should be using the buffer's
@@ -97,7 +97,7 @@ vec4 Dither_TriangleNoiseRGB(vec4 rgba, highp float temporalNoise01) {
* This dithering function assumes we are dithering to an 8-bit target.
* This function dithers the alpha channel assuming premultiplied output
*/
vec4 dither(vec4 rgba, highp float temporalNoise01) {
vec4 dither(vec4 rgba, const highp float temporalNoise01) {
#if DITHERING_OPERATOR == DITHERING_NONE
return rgba;
#elif DITHERING_OPERATOR == DITHERING_INTERLEAVED_NOISE

View File

@@ -62,14 +62,14 @@ vec3 mulBoneVertex(vec3 v, uint i) {
return v.x * m[0].xyz + (v.y * m[1].xyz + (v.z * m[2].xyz + m[3].xyz));
}
void skinNormal(inout vec3 n, uvec4 ids, vec4 weights) {
void skinNormal(inout vec3 n, const uvec4 ids, const vec4 weights) {
n = mulBoneNormal(n, ids.x) * weights.x
+ mulBoneNormal(n, ids.y) * weights.y
+ mulBoneNormal(n, ids.z) * weights.z
+ mulBoneNormal(n, ids.w) * weights.w;
}
void skinPosition(inout vec3 p, uvec4 ids, vec4 weights) {
void skinPosition(inout vec3 p, const uvec4 ids, const vec4 weights) {
p = mulBoneVertex(p, ids.x) * weights.x
+ mulBoneVertex(p, ids.y) * weights.y
+ mulBoneVertex(p, ids.z) * weights.z

View File

@@ -6,7 +6,7 @@
#define SUN_AS_AREA_LIGHT
#endif
vec3 sampleSunAreaLight(vec3 lightDirection) {
vec3 sampleSunAreaLight(const vec3 lightDirection) {
#if defined(SUN_AS_AREA_LIGHT)
if (frameUniforms.sun.w >= 0.0) {
// simulate sun as disc area light
@@ -31,8 +31,8 @@ Light getDirectionalLight() {
return light;
}
void evaluateDirectionalLight(MaterialInputs material,
PixelParams pixel, inout vec3 color) {
void evaluateDirectionalLight(const MaterialInputs material,
const PixelParams pixel, inout vec3 color) {
Light light = getDirectionalLight();

View File

@@ -17,7 +17,7 @@
// IBL utilities
//------------------------------------------------------------------------------
vec3 decodeDataForIBL(vec4 data) {
vec3 decodeDataForIBL(const vec4 data) {
return data.rgb;
}
@@ -43,7 +43,7 @@ vec3 prefilteredDFG(float perceptualRoughness, float NoV) {
// IBL irradiance implementations
//------------------------------------------------------------------------------
vec3 Irradiance_SphericalHarmonics(vec3 n) {
vec3 Irradiance_SphericalHarmonics(const vec3 n) {
return max(
frameUniforms.iblSH[0]
#if SPHERICAL_HARMONICS_BANDS >= 2
@@ -61,7 +61,7 @@ vec3 Irradiance_SphericalHarmonics(vec3 n) {
, 0.0);
}
vec3 Irradiance_RoughnessOne(vec3 n) {
vec3 Irradiance_RoughnessOne(const vec3 n) {
// note: lod used is always integer, hopefully the hardware skips tri-linear filtering
return decodeDataForIBL(textureLod(light_iblSpecular, n, frameUniforms.iblRoughnessOneLevel));
}
@@ -70,7 +70,7 @@ vec3 Irradiance_RoughnessOne(vec3 n) {
// IBL irradiance dispatch
//------------------------------------------------------------------------------
vec3 diffuseIrradiance(vec3 n) {
vec3 diffuseIrradiance(const vec3 n) {
// On Metal devices with an A8X chipset, this light_iblSpecular texture sample must be pulled
// outside the frameUniforms.iblSH check. This is to avoid a Metal pipeline compilation error
// with the message: "Could not statically determine the target of a texture".
@@ -118,21 +118,21 @@ float perceptualRoughnessToLod(float perceptualRoughness) {
return frameUniforms.iblRoughnessOneLevel * perceptualRoughness * (2.0 - perceptualRoughness);
}
vec3 prefilteredRadiance(vec3 r, float perceptualRoughness) {
vec3 prefilteredRadiance(const vec3 r, float perceptualRoughness) {
float lod = perceptualRoughnessToLod(perceptualRoughness);
return decodeDataForIBL(textureLod(light_iblSpecular, r, lod));
}
vec3 prefilteredRadiance(vec3 r, float roughness, float offset) {
vec3 prefilteredRadiance(const vec3 r, float roughness, float offset) {
float lod = frameUniforms.iblRoughnessOneLevel * roughness;
return decodeDataForIBL(textureLod(light_iblSpecular, r, lod + offset));
}
vec3 getSpecularDominantDirection(vec3 n, vec3 r, float roughness) {
vec3 getSpecularDominantDirection(const vec3 n, const vec3 r, float roughness) {
return mix(r, n, roughness * roughness);
}
vec3 specularDFG(PixelParams pixel) {
vec3 specularDFG(const PixelParams pixel) {
#if defined(SHADING_MODEL_CLOTH)
return pixel.f0 * pixel.dfg.z;
#else
@@ -140,7 +140,7 @@ vec3 specularDFG(PixelParams pixel) {
#endif
}
vec3 getReflectedVector(PixelParams pixel, vec3 n) {
vec3 getReflectedVector(const PixelParams pixel, const vec3 n) {
#if defined(MATERIAL_HAS_ANISOTROPY)
vec3 r = getReflectedVector(pixel, shading_view, n);
#else
@@ -223,7 +223,7 @@ float prefilteredImportanceSampling(float ipdf, float omegaP) {
return mipLevel;
}
vec3 isEvaluateSpecularIBL(PixelParams pixel, vec3 n, vec3 v, float NoV) {
vec3 isEvaluateSpecularIBL(const PixelParams pixel, const vec3 n, const vec3 v, const float NoV) {
const int numSamples = IBL_INTEGRATION_IMPORTANCE_SAMPLING_COUNT;
const float invNumSamples = 1.0 / float(numSamples);
const vec3 up = vec3(0.0, 0.0, 1.0);
@@ -282,7 +282,7 @@ vec3 isEvaluateSpecularIBL(PixelParams pixel, vec3 n, vec3 v, float NoV) {
return indirectSpecular;
}
vec3 isEvaluateDiffuseIBL(PixelParams pixel, vec3 n, vec3 v) {
vec3 isEvaluateDiffuseIBL(const PixelParams pixel, vec3 n, vec3 v) {
const int numSamples = IBL_INTEGRATION_IMPORTANCE_SAMPLING_COUNT;
const float invNumSamples = 1.0 / float(numSamples);
const vec3 up = vec3(0.0, 0.0, 1.0);
@@ -332,7 +332,7 @@ vec3 isEvaluateDiffuseIBL(PixelParams pixel, vec3 n, vec3 v) {
return indirectDiffuse * invNumSamples; // we bake 1/PI here, which cancels out
}
void isEvaluateClearCoatIBL(PixelParams pixel, float specularAO, inout vec3 Fd, inout vec3 Fr) {
void isEvaluateClearCoatIBL(const PixelParams pixel, float specularAO, inout vec3 Fd, inout vec3 Fr) {
#if defined(MATERIAL_HAS_CLEAR_COAT)
#if defined(MATERIAL_HAS_NORMAL) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// We want to use the geometric normal for the clear coat layer
@@ -366,7 +366,7 @@ void isEvaluateClearCoatIBL(PixelParams pixel, float specularAO, inout vec3 Fd,
// IBL evaluation
//------------------------------------------------------------------------------
void evaluateClothIndirectDiffuseBRDF(PixelParams pixel, inout float diffuse) {
void evaluateClothIndirectDiffuseBRDF(const PixelParams pixel, inout float diffuse) {
#if defined(SHADING_MODEL_CLOTH)
#if defined(MATERIAL_HAS_SUBSURFACE_COLOR)
// Simulate subsurface scattering with a wrap diffuse term
@@ -375,8 +375,8 @@ void evaluateClothIndirectDiffuseBRDF(PixelParams pixel, inout float diffuse) {
#endif
}
void evaluateSheenIBL(PixelParams pixel, float diffuseAO,
SSAOInterpolationCache cache, inout vec3 Fd, inout vec3 Fr) {
void evaluateSheenIBL(const PixelParams pixel, float diffuseAO,
const in SSAOInterpolationCache cache, inout vec3 Fd, inout vec3 Fr) {
#if !defined(SHADING_MODEL_CLOTH) && !defined(SHADING_MODEL_SUBSURFACE)
#if defined(MATERIAL_HAS_SHEEN_COLOR)
// Albedo scaling of the base layer before we layer sheen on top
@@ -391,8 +391,8 @@ void evaluateSheenIBL(PixelParams pixel, float diffuseAO,
#endif
}
void evaluateClearCoatIBL(PixelParams pixel, float diffuseAO,
SSAOInterpolationCache cache, inout vec3 Fd, inout vec3 Fr) {
void evaluateClearCoatIBL(const PixelParams pixel, float diffuseAO,
const in SSAOInterpolationCache cache, inout vec3 Fd, inout vec3 Fr) {
#if IBL_INTEGRATION == IBL_INTEGRATION_IMPORTANCE_SAMPLING
float specularAO = specularAO(shading_NoV, diffuseAO, pixel.clearCoatRoughness, cache);
isEvaluateClearCoatIBL(pixel, specularAO, Fd, Fr);
@@ -422,7 +422,7 @@ void evaluateClearCoatIBL(PixelParams pixel, float diffuseAO,
#endif
}
void evaluateSubsurfaceIBL(PixelParams pixel, vec3 diffuseIrradiance,
void evaluateSubsurfaceIBL(const PixelParams pixel, const vec3 diffuseIrradiance,
inout vec3 Fd, inout vec3 Fr) {
#if defined(SHADING_MODEL_SUBSURFACE)
vec3 viewIndependent = diffuseIrradiance;
@@ -442,8 +442,8 @@ struct Refraction {
float d;
};
void refractionSolidSphere(PixelParams pixel,
vec3 n, vec3 r, out Refraction ray) {
void refractionSolidSphere(const PixelParams pixel,
const vec3 n, vec3 r, out Refraction ray) {
r = refract(r, n, pixel.etaIR);
float NoR = dot(n, r);
float d = pixel.thickness * -NoR;
@@ -453,8 +453,8 @@ void refractionSolidSphere(PixelParams pixel,
ray.direction = refract(r, n1, pixel.etaRI);
}
void refractionSolidBox(PixelParams pixel,
vec3 n, vec3 r, out Refraction ray) {
void refractionSolidBox(const PixelParams pixel,
const vec3 n, vec3 r, out Refraction ray) {
vec3 rr = refract(r, n, pixel.etaIR);
float NoR = dot(n, rr);
float d = pixel.thickness / max(-NoR, 0.001);
@@ -468,8 +468,8 @@ void refractionSolidBox(PixelParams pixel,
#endif
}
void refractionThinSphere(PixelParams pixel,
vec3 n, vec3 r, out Refraction ray) {
void refractionThinSphere(const PixelParams pixel,
const vec3 n, vec3 r, out Refraction ray) {
float d = 0.0;
#if defined(MATERIAL_HAS_MICRO_THICKNESS)
// note: we need the refracted ray to calculate the distance traveled
@@ -485,7 +485,9 @@ void refractionThinSphere(PixelParams pixel,
ray.d = d;
}
vec3 evaluateRefraction(PixelParams pixel, vec3 n0, vec3 E) {
vec3 evaluateRefraction(
const PixelParams pixel,
const vec3 n0, vec3 E) {
Refraction ray;
@@ -554,7 +556,7 @@ vec3 evaluateRefraction(PixelParams pixel, vec3 n0, vec3 E) {
}
#endif
void evaluateIBL(MaterialInputs material, PixelParams pixel, inout vec3 color) {
void evaluateIBL(const MaterialInputs material, const PixelParams pixel, inout vec3 color) {
// specular layer
vec3 Fr = vec3(0.0);

View File

@@ -20,7 +20,7 @@ struct FroxelParams {
* Returns the coordinates of the froxel at the specified fragment coordinates.
* The coordinates are a 3D position in the froxel grid.
*/
uvec3 getFroxelCoords(highp vec3 fragCoords) {
uvec3 getFroxelCoords(const highp vec3 fragCoords) {
uvec3 froxelCoord;
froxelCoord.xy = uvec2(fragCoords.xy * frameUniforms.froxelCountXY);
@@ -48,7 +48,7 @@ uvec3 getFroxelCoords(highp vec3 fragCoords) {
* The froxel index is computed from the 3D coordinates of the froxel in the
* froxel grid and later used to fetch from the froxel buffer.
*/
uint getFroxelIndex(highp vec3 fragCoords) {
uint getFroxelIndex(const highp vec3 fragCoords) {
uvec3 froxelCoord = getFroxelCoords(fragCoords);
return froxelCoord.x * frameUniforms.fParams.x +
froxelCoord.y * frameUniforms.fParams.y +
@@ -66,7 +66,7 @@ ivec2 getFroxelTexCoord(uint froxelIndex) {
* Returns the froxel data for the given froxel index. The data is fetched
* from FroxelsUniforms UBO.
*/
FroxelParams getFroxelParams(uint froxelIndex) {
FroxelParams getFroxelParams(const uint froxelIndex) {
uint w = froxelIndex >> 2u;
uint c = froxelIndex & 0x3u;
highp uvec4 d = froxelsUniforms.records[w];
@@ -81,7 +81,7 @@ FroxelParams getFroxelParams(uint froxelIndex) {
* Return the light index from the record index
* A light record is a single uint index into the lights data buffer (lightsUniforms UBO).
*/
uint getLightIndex(uint index) {
uint getLightIndex(const uint index) {
uint v = index >> 4u;
uint c = (index >> 2u) & 0x3u;
uint s = (index & 0x3u) * 8u;
@@ -98,7 +98,7 @@ float getSquareFalloffAttenuation(float distanceSquare, float falloff) {
return smoothFactor * smoothFactor;
}
float getDistanceAttenuation(highp vec3 posToLight, float falloff) {
float getDistanceAttenuation(const highp vec3 posToLight, float falloff) {
float distanceSquare = dot(posToLight, posToLight);
float attenuation = getSquareFalloffAttenuation(distanceSquare, falloff);
// light far attenuation
@@ -109,7 +109,7 @@ float getDistanceAttenuation(highp vec3 posToLight, float falloff) {
return attenuation / max(distanceSquare, 1e-4);
}
float getAngleAttenuation(highp vec3 lightDir, highp vec3 l, highp vec2 scaleOffset) {
float getAngleAttenuation(const highp vec3 lightDir, const highp vec3 l, const highp vec2 scaleOffset) {
float cd = dot(lightDir, l);
float attenuation = saturate(cd * scaleOffset.x + scaleOffset.y);
return attenuation * attenuation;
@@ -124,7 +124,7 @@ float getAngleAttenuation(highp vec3 lightDir, highp vec3 l, highp vec2 scaleOff
* lightsUniforms uniform buffer.
*/
Light getLight(uint lightIndex) {
Light getLight(const uint lightIndex) {
// retrieve the light data from the UBO
highp mat4 data = lightsUniforms.lights[lightIndex];
@@ -176,8 +176,8 @@ Light getLight(uint lightIndex) {
* The result of the lighting computations is accumulated in the color
* parameter, as linear HDR RGB.
*/
void evaluatePunctualLights(MaterialInputs material,
PixelParams pixel, inout vec3 color) {
void evaluatePunctualLights(const MaterialInputs material,
const PixelParams pixel, inout vec3 color) {
// Fetch the light information stored in the froxel that contains the
// current fragment

View File

@@ -57,10 +57,10 @@ highp float distanceSquared(highp vec2 a, highp vec2 b) {
// Note: McGuire and Mara use the "cs" prefix to stand for "camera space", equivalent to Filament's
// "view space". "cs" has been replaced with "vs" to avoid confusion.
bool traceScreenSpaceRay(highp vec3 vsOrigin, highp vec3 vsDirection,
highp mat4 uvFromViewMatrix, highp sampler2D vsZBuffer,
float vsZThickness, highp float nearPlaneZ, float stride,
float jitterFraction, highp float maxSteps, float maxRayTraceDistance,
bool traceScreenSpaceRay(const highp vec3 vsOrigin, const highp vec3 vsDirection,
highp_mat4 uvFromViewMatrix, const highp sampler2D vsZBuffer,
const float vsZThickness, const highp float nearPlaneZ, const float stride,
const float jitterFraction, const highp float maxSteps, const float maxRayTraceDistance,
out highp vec2 hitPixel, out highp vec3 vsHitPoint) {
// Clip ray to a near plane in 3D (doesn't have to be *the* near plane, although that would be a
// good idea)
@@ -181,7 +181,7 @@ bool traceScreenSpaceRay(highp vec3 vsOrigin, highp vec3 vsDirection,
// -- end "BSD 2-clause license" -------------------------------------------------------------------
highp mat4 scaleMatrix(highp float x, highp float y) {
highp mat4 scaleMatrix(const highp float x, const highp float y) {
mat4 m = mat4(1.0);
m[0].x = x;
m[1].y = y;
@@ -200,7 +200,7 @@ highp mat4 scaleMatrix(highp float x, highp float y) {
*
* If there is no hit, the return value is vec4(0).
*/
vec4 evaluateScreenSpaceReflections(highp vec3 wsRayDirection) {
vec4 evaluateScreenSpaceReflections(const highp vec3 wsRayDirection) {
vec4 Fr = vec4(0.0);
highp vec3 wsRayStart = shading_position + frameUniforms.ssrBias * wsRayDirection;

View File

@@ -5,7 +5,7 @@ layout(location = 0) out vec4 fragColor;
#endif
#if defined(MATERIAL_HAS_POST_LIGHTING_COLOR)
void blendPostLightingColor(MaterialInputs material, inout vec4 color) {
void blendPostLightingColor(const MaterialInputs material, inout vec4 color) {
#if defined(POST_LIGHTING_BLEND_MODE_OPAQUE)
color = material.postLightingColor;
#elif defined(POST_LIGHTING_BLEND_MODE_TRANSPARENT)

View File

@@ -33,13 +33,13 @@ struct MaterialVertexInputs {
// Workaround for a driver bug on ARM Bifrost GPUs. Assigning a structure member
// (directly or inside an expression) to an invariant causes a driver crash.
vec4 getWorldPosition(MaterialVertexInputs material) {
vec4 getWorldPosition(const MaterialVertexInputs material) {
return material.worldPosition;
}
#ifdef VERTEX_DOMAIN_DEVICE
#ifdef MATERIAL_HAS_CLIP_SPACE_TRANSFORM
mat4 getMaterialClipSpaceTransform(MaterialVertexInputs material) {
mat4 getMaterialClipSpaceTransform(const MaterialVertexInputs material) {
return material.clipSpaceTransform;
}
#endif // MATERIAL_HAS_CLIP_SPACE_TRANSFORM

View File

@@ -38,7 +38,7 @@ void applyAlphaMask(inout vec4 baseColor) {}
#endif
#if defined(GEOMETRIC_SPECULAR_AA)
float normalFiltering(float perceptualRoughness, vec3 worldNormal) {
float normalFiltering(float perceptualRoughness, const vec3 worldNormal) {
// Kaplanyan 2016, "Stable specular highlights"
// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
@@ -63,7 +63,7 @@ float normalFiltering(float perceptualRoughness, vec3 worldNormal) {
}
#endif
void getCommonPixelParams(MaterialInputs material, inout PixelParams pixel) {
void getCommonPixelParams(const MaterialInputs material, inout PixelParams pixel) {
vec4 baseColor = material.baseColor;
applyAlphaMask(baseColor);
@@ -137,7 +137,7 @@ void getCommonPixelParams(MaterialInputs material, inout PixelParams pixel) {
#endif
}
void getSheenPixelParams(MaterialInputs material, inout PixelParams pixel) {
void getSheenPixelParams(const MaterialInputs material, inout PixelParams pixel) {
#if defined(MATERIAL_HAS_SHEEN_COLOR) && !defined(SHADING_MODEL_CLOTH) && !defined(SHADING_MODEL_SUBSURFACE)
pixel.sheenColor = material.sheenColor;
@@ -154,7 +154,7 @@ void getSheenPixelParams(MaterialInputs material, inout PixelParams pixel) {
#endif
}
void getClearCoatPixelParams(MaterialInputs material, inout PixelParams pixel) {
void getClearCoatPixelParams(const MaterialInputs material, inout PixelParams pixel) {
#if defined(MATERIAL_HAS_CLEAR_COAT)
pixel.clearCoat = material.clearCoat;
@@ -181,7 +181,7 @@ void getClearCoatPixelParams(MaterialInputs material, inout PixelParams pixel) {
#endif
}
void getRoughnessPixelParams(MaterialInputs material, inout PixelParams pixel) {
void getRoughnessPixelParams(const MaterialInputs material, inout PixelParams pixel) {
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
float perceptualRoughness = computeRoughnessFromGlossiness(material.glossiness);
#else
@@ -209,7 +209,7 @@ void getRoughnessPixelParams(MaterialInputs material, inout PixelParams pixel) {
pixel.roughness = perceptualRoughnessToRoughness(pixel.perceptualRoughness);
}
void getSubsurfacePixelParams(MaterialInputs material, inout PixelParams pixel) {
void getSubsurfacePixelParams(const MaterialInputs material, inout PixelParams pixel) {
#if defined(SHADING_MODEL_SUBSURFACE)
pixel.subsurfacePower = material.subsurfacePower;
pixel.subsurfaceColor = material.subsurfaceColor;
@@ -245,7 +245,7 @@ void getEnergyCompensationPixelParams(inout PixelParams pixel) {
* This function is also responsible for discarding the fragment when alpha
* testing fails.
*/
void getPixelParams(MaterialInputs material, out PixelParams pixel) {
void getPixelParams(const MaterialInputs material, out PixelParams pixel) {
getCommonPixelParams(material, pixel);
getSheenPixelParams(material, pixel);
getClearCoatPixelParams(material, pixel);
@@ -265,7 +265,7 @@ void getPixelParams(MaterialInputs material, out PixelParams pixel) {
*
* Returns a pre-exposed HDR RGBA color in linear space.
*/
vec4 evaluateLights(MaterialInputs material) {
vec4 evaluateLights(const MaterialInputs material) {
PixelParams pixel;
getPixelParams(material, pixel);
@@ -295,7 +295,7 @@ vec4 evaluateLights(MaterialInputs material) {
return vec4(color, computeDiffuseAlpha(material.baseColor.a));
}
void addEmissive(MaterialInputs material, inout vec4 color) {
void addEmissive(const MaterialInputs material, inout vec4 color) {
#if defined(MATERIAL_HAS_EMISSIVE)
highp vec4 emissive = material.emissive;
highp float attenuation = mix(1.0, getExposure(), emissive.w);
@@ -309,7 +309,7 @@ void addEmissive(MaterialInputs material, inout vec4 color) {
*
* Returns a pre-exposed HDR RGBA color in linear space.
*/
vec4 evaluateMaterial(MaterialInputs material) {
vec4 evaluateMaterial(const MaterialInputs material) {
vec4 color = evaluateLights(material);
addEmissive(material, color);
return color;

View File

@@ -1,5 +1,5 @@
vec3 customSurfaceShading(MaterialInputs materialInputs,
PixelParams pixel, Light light, float visibility) {
vec3 customSurfaceShading(const MaterialInputs materialInputs,
const PixelParams pixel, const Light light, float visibility) {
LightData lightData;
lightData.colorIntensity = light.colorIntensity;

View File

@@ -9,7 +9,7 @@
* computation of these events is not physically based but can add necessary
* details to a material.
*/
vec3 surfaceShading(PixelParams pixel, Light light, float occlusion) {
vec3 surfaceShading(const PixelParams pixel, const Light light, float occlusion) {
vec3 h = normalize(shading_view + light.l);
float NoL = light.NoL;
float NoH = saturate(dot(shading_normal, h));

View File

@@ -1,5 +1,5 @@
#if defined(MATERIAL_HAS_SHEEN_COLOR)
vec3 sheenLobe(PixelParams pixel, float NoV, float NoL, float NoH) {
vec3 sheenLobe(const PixelParams pixel, float NoV, float NoL, float NoH) {
float D = distributionCloth(pixel.sheenRoughness, NoH);
float V = visibilityCloth(NoV, NoL);
@@ -8,7 +8,7 @@ vec3 sheenLobe(PixelParams pixel, float NoV, float NoL, float NoH) {
#endif
#if defined(MATERIAL_HAS_CLEAR_COAT)
float clearCoatLobe(PixelParams pixel, vec3 h, float NoH, float LoH, out float Fcc) {
float clearCoatLobe(const PixelParams pixel, const vec3 h, float NoH, float LoH, out float Fcc) {
#if defined(MATERIAL_HAS_NORMAL) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
// If the material has a normal map, we want to use the geometric normal
// instead to avoid applying the normal map details to the clear coat layer
@@ -28,7 +28,7 @@ float clearCoatLobe(PixelParams pixel, vec3 h, float NoH, float LoH, out float F
#endif
#if defined(MATERIAL_HAS_ANISOTROPY)
vec3 anisotropicLobe(PixelParams pixel, Light light, vec3 h,
vec3 anisotropicLobe(const PixelParams pixel, const Light light, const vec3 h,
float NoV, float NoL, float NoH, float LoH) {
vec3 l = light.l;
@@ -58,7 +58,7 @@ vec3 anisotropicLobe(PixelParams pixel, Light light, vec3 h,
}
#endif
vec3 isotropicLobe(PixelParams pixel, Light light, vec3 h,
vec3 isotropicLobe(const PixelParams pixel, const Light light, const vec3 h,
float NoV, float NoL, float NoH, float LoH) {
float D = distribution(pixel.roughness, NoH, h);
@@ -68,7 +68,7 @@ vec3 isotropicLobe(PixelParams pixel, Light light, vec3 h,
return (D * V) * F;
}
vec3 specularLobe(PixelParams pixel, Light light, vec3 h,
vec3 specularLobe(const PixelParams pixel, const Light light, const vec3 h,
float NoV, float NoL, float NoH, float LoH) {
#if defined(MATERIAL_HAS_ANISOTROPY)
return anisotropicLobe(pixel, light, h, NoV, NoL, NoH, LoH);
@@ -77,7 +77,7 @@ vec3 specularLobe(PixelParams pixel, Light light, vec3 h,
#endif
}
vec3 diffuseLobe(PixelParams pixel, float NoV, float NoL, float LoH) {
vec3 diffuseLobe(const PixelParams pixel, float NoV, float NoL, float LoH) {
return pixel.diffuseColor * diffuse(pixel.roughness, NoV, NoL, LoH);
}
@@ -98,7 +98,7 @@ vec3 diffuseLobe(PixelParams pixel, float NoV, float NoL, float LoH) {
* on the Cook-Torrance microfacet model, it uses cheaper terms than the surface
* BRDF's specular lobe (see brdf.fs).
*/
vec3 surfaceShading(PixelParams pixel, Light light, float occlusion) {
vec3 surfaceShading(const PixelParams pixel, const Light light, float occlusion) {
vec3 h = normalize(shading_view + light.l);
float NoV = shading_NoV;

View File

@@ -5,7 +5,7 @@
* scattering. The BTDF itself is not physically based and does not represent a
* correct interpretation of transmission events.
*/
vec3 surfaceShading(PixelParams pixel, Light light, float occlusion) {
vec3 surfaceShading(const PixelParams pixel, const Light light, float occlusion) {
vec3 h = normalize(shading_view + light.l);
float NoL = light.NoL;

View File

@@ -56,7 +56,7 @@ void computeShadingParams() {
* This function must be invoked by the user's material code (guaranteed by
* the material compiler) after setting a value for MaterialInputs.normal.
*/
void prepareMaterial(MaterialInputs material) {
void prepareMaterial(const MaterialInputs material) {
#if defined(HAS_ATTRIBUTE_TANGENTS)
#if defined(MATERIAL_HAS_NORMAL)
shading_normal = normalize(shading_tangentToWorld * material.normal);

View File

@@ -1,7 +1,7 @@
/*
* screen-space reflection shading
*/
vec4 evaluateMaterial(MaterialInputs material) {
vec4 evaluateMaterial(const MaterialInputs material) {
#if defined(MATERIAL_HAS_REFLECTIONS)
PixelParams pixel;

View File

@@ -1,4 +1,4 @@
void addEmissive(MaterialInputs material, inout vec4 color) {
void addEmissive(const MaterialInputs material, inout vec4 color) {
#if defined(MATERIAL_HAS_EMISSIVE)
highp vec4 emissive = material.emissive;
highp float attenuation = mix(1.0, getExposure(), emissive.w);
@@ -27,7 +27,7 @@ float computeMaskedAlpha(float a) {
* This is mostly useful in AR to cast shadows on unlit transparent shadow
* receiving planes.
*/
vec4 evaluateMaterial(MaterialInputs material) {
vec4 evaluateMaterial(const MaterialInputs material) {
vec4 color = material.baseColor;
#if defined(BLEND_MODE_MASKED)

View File

@@ -17,9 +17,9 @@
// PCF Shadow Sampling
//------------------------------------------------------------------------------
float sampleDepth(mediump sampler2DArrayShadow map,
highp vec4 scissorNormalized,
uint layer, highp vec2 uv, float depth) {
float sampleDepth(const mediump sampler2DArrayShadow map,
const highp vec4 scissorNormalized,
const uint layer, highp vec2 uv, float depth) {
// clamp needed for directional lights and/or large kernels
uv = clamp(uv, scissorNormalized.xy, scissorNormalized.zw);
@@ -31,9 +31,9 @@ float sampleDepth(mediump sampler2DArrayShadow map,
#if SHADOW_SAMPLING_METHOD == SHADOW_SAMPLING_PCF_HARD
// use hardware assisted PCF
float ShadowSample_PCF_Hard(mediump sampler2DArrayShadow map,
highp vec4 scissorNormalized,
uint layer, highp vec4 shadowPosition) {
float ShadowSample_PCF_Hard(const mediump sampler2DArrayShadow map,
const highp vec4 scissorNormalized,
const uint layer, const highp vec4 shadowPosition) {
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
return sampleDepth(map, scissorNormalized, layer, position.xy, position.z);
@@ -42,9 +42,9 @@ float ShadowSample_PCF_Hard(mediump sampler2DArrayShadow map,
#if SHADOW_SAMPLING_METHOD == SHADOW_SAMPLING_PCF_LOW
// use hardware assisted PCF + 3x3 gaussian filter
float ShadowSample_PCF_Low(mediump sampler2DArrayShadow map,
highp vec4 scissorNormalized,
uint layer, highp vec4 shadowPosition) {
float ShadowSample_PCF_Low(const mediump sampler2DArrayShadow map,
const highp vec4 scissorNormalized,
const uint layer, const highp vec4 shadowPosition) {
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
highp vec2 size = vec2(textureSize(map, 0));
@@ -80,9 +80,9 @@ float ShadowSample_PCF_Low(mediump sampler2DArrayShadow map,
#endif
// use manual PCF
float ShadowSample_PCF(mediump sampler2DArray map,
highp vec4 scissorNormalized,
uint layer, highp vec4 shadowPosition) {
float ShadowSample_PCF(const mediump sampler2DArray map,
const highp vec4 scissorNormalized,
const uint layer, const highp vec4 shadowPosition) {
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
highp vec2 size = vec2(textureSize(map, 0));
@@ -147,7 +147,7 @@ float hardenedKernel(float x) {
return 0.5 * x + 0.5;
}
highp vec2 computeReceiverPlaneDepthBias(highp vec3 position) {
highp vec2 computeReceiverPlaneDepthBias(const highp vec3 position) {
// see: GDC '06: Shadow Mapping: GPU-based Tips and Techniques
// Chain rule to compute dz/du and dz/dv
// |dz/du| |du/dx du/dy|^-T |dz/dx|
@@ -167,7 +167,7 @@ mat2 getRandomRotationMatrix(highp vec2 fragCoord) {
return R;
}
float getPenumbraLs(bool DIRECTIONAL, int index, highp float zLight) {
float getPenumbraLs(const bool DIRECTIONAL, const int index, const highp float zLight) {
float penumbra;
// This conditional is resolved at compile time
if (DIRECTIONAL) {
@@ -179,7 +179,7 @@ float getPenumbraLs(bool DIRECTIONAL, int index, highp float zLight) {
return penumbra;
}
float getPenumbraRatio(bool DIRECTIONAL, int index,
float getPenumbraRatio(const bool DIRECTIONAL, const int index,
float z_receiver, float z_blocker) {
// z_receiver/z_blocker are not linear depths (i.e. they're not distances)
// Penumbra ratio for PCSS is given by: pr = (d_receiver - d_blocker) / d_blocker
@@ -202,10 +202,10 @@ float getPenumbraRatio(bool DIRECTIONAL, int index,
}
void blockerSearchAndFilter(out float occludedCount, out float z_occSum,
mediump sampler2DArray map, highp vec4 scissorNormalized, highp vec2 uv,
float z_rec, uint layer,
highp vec2 filterRadii, mat2 R, highp vec2 dz_duv,
uint tapCount) {
const mediump sampler2DArray map, const highp vec4 scissorNormalized, const highp vec2 uv,
const float z_rec, const uint layer,
const highp vec2 filterRadii, const mat2 R, const highp vec2 dz_duv,
const uint tapCount) {
occludedCount = 0.0;
z_occSum = 0.0;
for (uint i = 0u; i < tapCount; i++) {
@@ -230,12 +230,12 @@ void blockerSearchAndFilter(out float occludedCount, out float z_occSum,
}
}
float filterPCSS(mediump sampler2DArray map,
highp vec4 scissorNormalized,
highp vec2 size,
highp vec2 uv, float z_rec, uint layer,
highp vec2 filterRadii, mat2 R, highp vec2 dz_duv,
uint tapCount) {
float filterPCSS(const mediump sampler2DArray map,
const highp vec4 scissorNormalized,
const highp vec2 size,
const highp vec2 uv, const float z_rec, const uint layer,
const highp vec2 filterRadii, const mat2 R, const highp vec2 dz_duv,
const uint tapCount) {
float occludedCount = 0.0; // must be highp to workaround a spirv-tools issue
for (uint i = 0u; i < tapCount; i++) {
@@ -270,11 +270,11 @@ float filterPCSS(mediump sampler2DArray map,
* DPCF, PCF with contact hardenning simulation.
* see "Shadow of Cold War", A scalable approach to shadowing -- by Kevin Myers
*/
float ShadowSample_DPCF(bool DIRECTIONAL,
mediump sampler2DArray map,
highp vec4 scissorNormalized,
uint layer, int index,
highp vec4 shadowPosition, highp float zLight) {
float ShadowSample_DPCF(const bool DIRECTIONAL,
const mediump sampler2DArray map,
const highp vec4 scissorNormalized,
const uint layer, const int index,
const highp vec4 shadowPosition, const highp float zLight) {
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
highp vec2 texelSize = vec2(1.0) / vec2(textureSize(map, 0));
@@ -317,11 +317,11 @@ float ShadowSample_DPCF(bool DIRECTIONAL,
return 1.0 - percentageOccluded;
}
float ShadowSample_PCSS(bool DIRECTIONAL,
mediump sampler2DArray map,
highp vec4 scissorNormalized,
uint layer, int index,
highp vec4 shadowPosition, highp float zLight) {
float ShadowSample_PCSS(const bool DIRECTIONAL,
const mediump sampler2DArray map,
const highp vec4 scissorNormalized,
const uint layer, const int index,
const highp vec4 shadowPosition, const highp float zLight) {
highp vec2 size = vec2(textureSize(map, 0));
highp vec2 texelSize = vec2(1.0) / size;
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
@@ -435,18 +435,18 @@ float screenSpaceContactShadow(vec3 lightDirection) {
// VSM
//------------------------------------------------------------------------------
float linstep(float min, float max, float v) {
float linstep(const float min, const float max, const float v) {
// we could use smoothstep() too
return clamp((v - min) / (max - min), 0.0, 1.0);
}
float reduceLightBleed(float pMax, float amount) {
float reduceLightBleed(const float pMax, const float amount) {
// Remove the [0, amount] tail and linearly rescale (amount, 1].
return linstep(amount, 1.0, pMax);
}
float chebyshevUpperBound(highp vec2 moments, highp float mean,
highp float minVariance, float lightBleedReduction) {
float chebyshevUpperBound(const highp vec2 moments, const highp float mean,
const highp float minVariance, const float lightBleedReduction) {
// Donnelly and Lauritzen 2006, "Variance Shadow Maps"
highp float variance = moments.y - (moments.x * moments.x);
@@ -460,15 +460,15 @@ float chebyshevUpperBound(highp vec2 moments, highp float mean,
return mean <= moments.x ? 1.0 : pMax;
}
float evaluateShadowVSM(highp vec2 moments, highp float depth) {
float evaluateShadowVSM(const highp vec2 moments, const highp float depth) {
highp float depthScale = frameUniforms.vsmDepthScale * depth;
highp float minVariance = depthScale * depthScale;
return chebyshevUpperBound(moments, depth, minVariance, frameUniforms.vsmLightBleedReduction);
}
float ShadowSample_VSM(bool ELVSM, highp sampler2DArray shadowMap,
in highp vec4 scissorNormalized,
in uint layer, highp vec4 shadowPosition) {
float ShadowSample_VSM(const bool ELVSM, const highp sampler2DArray shadowMap,
const highp vec4 scissorNormalized,
const uint layer, const highp vec4 shadowPosition) {
// note: shadowPosition.z is in linear light-space normalized to [0, 1]
// see: ShadowMap::computeVsmLightSpaceMatrix() in ShadowMap.cpp
@@ -507,18 +507,18 @@ float ShadowSample_VSM(bool ELVSM, highp sampler2DArray shadowMap,
// get texture coordinate for directional and spot shadow maps
#if defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
highp vec4 getShadowPosition(int cascade) {
highp vec4 getShadowPosition(const int cascade) {
return getCascadeLightSpacePosition(cascade);
}
#endif
#if defined(VARIANT_HAS_DYNAMIC_LIGHTING)
highp vec4 getShadowPosition(int index, highp vec3 dir, highp float zLight) {
highp vec4 getShadowPosition(const int index, const highp vec3 dir, const highp float zLight) {
return getSpotLightSpacePosition(index, dir, zLight);
}
#endif
int getPointLightFace(highp vec3 r) {
int getPointLightFace(const highp vec3 r) {
highp vec4 tc;
highp float rx = abs(r.x);
highp float ry = abs(r.y);
@@ -534,9 +534,9 @@ int getPointLightFace(highp vec3 r) {
}
// PCF sampling
float shadow(bool DIRECTIONAL,
in mediump sampler2DArrayShadow shadowMap,
in int index, highp vec4 shadowPosition, highp float zLight) {
float shadow(const bool DIRECTIONAL,
const mediump sampler2DArrayShadow shadowMap,
const int index, highp vec4 shadowPosition, highp float zLight) {
highp vec4 scissorNormalized = shadowUniforms.shadows[index].scissorNormalized;
uint layer = shadowUniforms.shadows[index].layer;
#if SHADOW_SAMPLING_METHOD == SHADOW_SAMPLING_PCF_HARD
@@ -547,9 +547,9 @@ float shadow(bool DIRECTIONAL,
}
// Shadow requiring a sampler2D sampler (VSM, DPCF and PCSS)
float shadow(bool DIRECTIONAL,
in highp sampler2DArray shadowMap,
in int index, highp vec4 shadowPosition, highp float zLight) {
float shadow(const bool DIRECTIONAL,
const highp sampler2DArray shadowMap,
const int index, highp vec4 shadowPosition, highp float zLight) {
highp vec4 scissorNormalized = shadowUniforms.shadows[index].scissorNormalized;
uint layer = shadowUniforms.shadows[index].layer;
// This conditional is resolved at compile time

View File

@@ -7,7 +7,7 @@
// uv: viewport coordinates
// vignette: pre-computed parameters midPoint, radius, aspect and feather
// vignetteColor: color of the vignette effect
vec3 vignette(vec3 color, highp vec2 uv, vec4 vignette, vec4 vignetteColor) {
vec3 vignette(const vec3 color, const highp vec2 uv, const vec4 vignette, const vec4 vignetteColor) {
float midPoint = vignette.x;
float radius = vignette.y;
float aspect = vignette.z;