workaround another PowerVR compiler bug
In some situation, functions with const parameter cause the shader compilation to fail without an error message. We remove all the `const` qualifiers on functions, assuming this shouldn't impact code generation a lot.
This commit is contained in:
@@ -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(const vec4 x, const vec4 y, float a) {
|
||||
vec4 lerp(vec4 x, vec4 y, float a) {
|
||||
return x * (1.0 - a) + y * a;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ fragment {
|
||||
#define PREVENT_FLICKERING 0 // FIXME: thin lines disapear
|
||||
|
||||
|
||||
float luma(const vec3 color) {
|
||||
float luma(vec3 color) {
|
||||
#if USE_YCoCg
|
||||
return color.x;
|
||||
#else
|
||||
@@ -103,14 +103,14 @@ float luma(const vec3 color) {
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 RGB_YCoCg(const vec3 c) {
|
||||
vec3 RGB_YCoCg(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(const vec3 c) {
|
||||
vec3 YCoCg_RGB(vec3 c) {
|
||||
float Y = c.x;
|
||||
float Co = c.y;
|
||||
float Cg = c.z;
|
||||
@@ -121,8 +121,8 @@ vec3 YCoCg_RGB(const vec3 c) {
|
||||
}
|
||||
|
||||
// clip the (c, h) segment to a box
|
||||
vec4 clipToBox(const int quality,
|
||||
const vec3 boxmin, const vec3 boxmax, const vec4 c, const vec4 h) {
|
||||
vec4 clipToBox(int quality,
|
||||
vec3 boxmin, vec3 boxmax, vec4 c, vec4 h) {
|
||||
const float epsilon = 0.0001;
|
||||
|
||||
if (quality == BOX_CLIPPING_ACCURATE) {
|
||||
@@ -144,7 +144,7 @@ vec4 clipToBox(const 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(const sampler2D tex, const highp vec2 uv, const highp vec2 texSize) {
|
||||
vec4 sampleTextureCatmullRom(sampler2D tex, highp vec2 uv, 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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
vec3 colorGrade(mediump sampler3D lut, const vec3 x) {
|
||||
vec3 colorGrade(mediump sampler3D lut, vec3 x) {
|
||||
// Alexa LogC EI 1000
|
||||
const float a = 5.555556;
|
||||
const float b = 0.047996;
|
||||
|
||||
@@ -89,7 +89,7 @@ fragment {
|
||||
|
||||
void dummy(){}
|
||||
|
||||
float starburst(const vec2 uv) {
|
||||
float starburst(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(const vec2 uv) {
|
||||
return saturate(mask + (1.0 - smoothstep(0.0, 0.3, d)));
|
||||
}
|
||||
|
||||
vec3 bloom(highp vec2 uv, const vec3 color) {
|
||||
vec3 bloom(highp vec2 uv, vec3 color) {
|
||||
vec3 result = vec3(0.0);
|
||||
|
||||
if (materialParams.bloom.x > 0.0) {
|
||||
@@ -128,7 +128,7 @@ vec3 bloom(highp vec2 uv, const vec3 color) {
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 resolveFragment(const highp vec2 uv) {
|
||||
vec4 resolveFragment(highp vec2 uv) {
|
||||
#if POST_PROCESS_OPAQUE
|
||||
return vec4(textureLod(materialParams_colorBuffer, uv, 0.0).rgb, 1.0);
|
||||
#else
|
||||
|
||||
@@ -108,16 +108,16 @@ float ringCountFast() {
|
||||
return materialParams.ringCounts[2];
|
||||
}
|
||||
|
||||
float sampleCount(const float ringCount) {
|
||||
float sampleCount(float ringCount) {
|
||||
float s = (ringCount * 2.0 - 1.0);
|
||||
return s * s;
|
||||
}
|
||||
|
||||
float computeNeededRings(const float kernelSizeInPixel) {
|
||||
float computeNeededRings(float kernelSizeInPixel) {
|
||||
return ceil(kernelSizeInPixel + 0.5);
|
||||
}
|
||||
|
||||
float getMipLevel(const float ringCount, const float kernelSizeInPixels) {
|
||||
float getMipLevel(float ringCount, 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(const float ringCount, const float kernelSizeInPixels) {
|
||||
#endif
|
||||
}
|
||||
|
||||
float sampleWeight(const float coc, const float mip) {
|
||||
float sampleWeight(float coc, 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(const float coc, const float mip) {
|
||||
return (MAX_COC_RADIUS * MAX_COC_RADIUS) / (max(coc * coc, pixelRadiusSquared));
|
||||
}
|
||||
|
||||
float intersection(const float border, const float absCoc, const float mip) {
|
||||
float intersection(float border, float absCoc, 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(const float border, const float absCoc, const float mip) {
|
||||
#endif
|
||||
}
|
||||
|
||||
highp vec2 diaphragm(const highp vec2 center, const vec2 offset) {
|
||||
highp vec2 diaphragm(highp vec2 center, 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(const float i, const float ringCount, const float kernelSize, const vec2 noise,
|
||||
void initRing(float i, float ringCount, float kernelSize, 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(const float i, const float ringCount, const float kernelSize, cons
|
||||
offset = length(p + noise);
|
||||
}
|
||||
|
||||
void mergeRings(inout Bucket curr, inout Bucket prev, const float count) {
|
||||
void mergeRings(inout Bucket curr, inout Bucket prev, 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, const float count) {
|
||||
}
|
||||
}
|
||||
|
||||
void accumulate(inout Bucket curr, inout Bucket prev, const Sample tap,
|
||||
const float radius, const float border, const float mip, const bool first) {
|
||||
void accumulate(inout Bucket curr, inout Bucket prev, Sample tap,
|
||||
float radius, float border, float mip, 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, const Sample tap,
|
||||
}
|
||||
}
|
||||
|
||||
void accumulateBackground(inout Bucket curr, inout Bucket prev, const highp vec2 pos,
|
||||
const float radius, const float border, const float mip, const bool first) {
|
||||
void accumulateBackground(inout Bucket curr, inout Bucket prev, highp vec2 pos,
|
||||
float radius, float border, float mip, 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, const highp vec2
|
||||
}
|
||||
|
||||
void accumulateBackgroundMirror(inout Bucket curr, inout Bucket prev,
|
||||
const highp vec2 center, const vec2 offset,
|
||||
const float radius, const float border, const float mip, const bool first) {
|
||||
highp vec2 center, vec2 offset,
|
||||
float radius, float border, float mip, 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,
|
||||
const highp vec2 pos, const float ringCount,
|
||||
const float kernelSize, const float noiseRadius, const float mip) {
|
||||
highp vec2 pos, float ringCount,
|
||||
float kernelSize, float noiseRadius, 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, 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) {
|
||||
void accumulateRing(inout Bucket prev, float index, float ringCount,
|
||||
float kernelSize, vec2 noise, highp vec2 uvCenter,
|
||||
highp vec2 cocToTexelScale, float mip, 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(const float coc) {
|
||||
float foregroundFadding(float coc) {
|
||||
return saturate(abs(coc) - (MAX_IN_FOCUS_COC - 1.0));
|
||||
}
|
||||
|
||||
void accumulateForeground(inout Layer layer[2], const vec2 tiles,
|
||||
const highp vec2 pos, const float border, const float mip) {
|
||||
void accumulateForeground(inout Layer layer[2], vec2 tiles,
|
||||
highp vec2 pos, float border, 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], const vec2 tiles,
|
||||
layer[1].weight += inBackWeight;
|
||||
}
|
||||
|
||||
void accumulateForegroundCenter(inout Layer layer[2], const vec2 tiles,
|
||||
const highp vec2 pos, const float border, const float mip) {
|
||||
void accumulateForegroundCenter(inout Layer layer[2], vec2 tiles,
|
||||
highp vec2 pos, float border, float mip) {
|
||||
accumulateForeground(layer, tiles, pos, border, mip);
|
||||
}
|
||||
|
||||
void accumulateForegroundMirror(inout Layer layer[2], const vec2 tiles,
|
||||
const highp vec2 center, const vec2 offset, const float border, const float mip) {
|
||||
void accumulateForegroundMirror(inout Layer layer[2], vec2 tiles,
|
||||
highp vec2 center, vec2 offset, float border, 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], const vec2 tiles,
|
||||
*/
|
||||
|
||||
void fastTile(inout vec4 color, inout float alpha,
|
||||
const highp vec2 uv, const vec2 tiles, const NoiseState noiseState) {
|
||||
highp vec2 uv, vec2 tiles, 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,
|
||||
const highp vec2 uv, const vec2 tiles, const NoiseState noiseState) {
|
||||
highp vec2 uv, vec2 tiles, 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,
|
||||
const highp vec2 uv, const vec2 tiles, const NoiseState noiseState) {
|
||||
highp vec2 uv, vec2 tiles, NoiseState noiseState) {
|
||||
highp vec2 cocToTexelScale = materialParams.cocToTexelScale;
|
||||
float cocToPixelScale = materialParams.cocToPixelScale;
|
||||
|
||||
|
||||
@@ -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(const vec2 uv, const vec2 offset) {
|
||||
vec2 tap(vec2 uv, vec2 offset) {
|
||||
return textureLod(materialParams_tiles, uv + offset, 0.0).rg;
|
||||
}
|
||||
|
||||
vec2 dilate(inout vec2 center, const vec2 tap) {
|
||||
vec2 dilate(inout vec2 center, 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);
|
||||
|
||||
@@ -32,12 +32,12 @@ fragment {
|
||||
|
||||
void dummy(){}
|
||||
|
||||
float max4(const vec4 f) {
|
||||
float max4(vec4 f) {
|
||||
vec2 t = max(f.xy, f.zw);
|
||||
return max(t.x, t.y);
|
||||
}
|
||||
|
||||
float min4(const vec4 f) {
|
||||
float min4(vec4 f) {
|
||||
vec2 t = min(f.xy, f.zw);
|
||||
return min(t.x, t.y);
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ fragment {
|
||||
|
||||
void dummy(){}
|
||||
|
||||
float max4(const vec4 f) {
|
||||
float max4(vec4 f) {
|
||||
vec2 t = max(f.xy, f.zw);
|
||||
return max(t.x, t.y);
|
||||
}
|
||||
|
||||
float min4(const vec4 f) {
|
||||
float min4(vec4 f) {
|
||||
vec2 t = min(f.xy, f.zw);
|
||||
return min(t.x, t.y);
|
||||
}
|
||||
|
||||
@@ -17,68 +17,68 @@
|
||||
// Currently our dilate pass is set-up for 32 max.
|
||||
#define MAX_COC_RADIUS 32.0
|
||||
|
||||
float min2(const vec2 v) {
|
||||
float min2(vec2 v) {
|
||||
return min(v.x, v.y);
|
||||
}
|
||||
|
||||
float max2(const vec2 v) {
|
||||
float max2(vec2 v) {
|
||||
return max(v.x, v.y);
|
||||
}
|
||||
|
||||
float max4(const vec4 v) {
|
||||
float max4(vec4 v) {
|
||||
return max2(max(v.xy, v.zw));
|
||||
}
|
||||
|
||||
float min4(const vec4 v) {
|
||||
float min4(vec4 v) {
|
||||
return min2(min(v.xy, v.zw));
|
||||
}
|
||||
|
||||
float rcp(const float x) {
|
||||
float rcp(float x) {
|
||||
return 1.0 / x;
|
||||
}
|
||||
|
||||
float rcpOrZero(const float x) {
|
||||
float rcpOrZero(float x) {
|
||||
return x > MEDIUMP_FLT_MIN ? (1.0 / x) : 0.0;
|
||||
}
|
||||
|
||||
highp float rcpOrZeroHighp(const highp float x) {
|
||||
highp float rcpOrZeroHighp(highp float x) {
|
||||
return x > MEDIUMP_FLT_MIN ? (1.0 / x) : 0.0;
|
||||
}
|
||||
|
||||
float cocToAlpha(const float coc) {
|
||||
float cocToAlpha(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(const float depth, const vec2 cocParams) {
|
||||
float getCOC(float depth, vec2 cocParams) {
|
||||
return depth * cocParams.x + cocParams.y;
|
||||
}
|
||||
|
||||
vec4 getCOC(const vec4 depth, const vec2 cocParams) {
|
||||
vec4 getCOC(vec4 depth, vec2 cocParams) {
|
||||
return depth * cocParams.x + cocParams.y;
|
||||
}
|
||||
|
||||
float isForeground(const float coc) {
|
||||
float isForeground(float coc) {
|
||||
return coc < 0.0 ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
float isBackground(const float coc) {
|
||||
float isBackground(float coc) {
|
||||
return coc > 0.0 ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
bool isForegroundTile(const vec2 tiles) {
|
||||
bool isForegroundTile(vec2 tiles) {
|
||||
// A foreground tile is one where the smallest CoC is negative
|
||||
return tiles.r < 0.0;
|
||||
}
|
||||
|
||||
bool isBackgroundTile(const vec2 tiles) {
|
||||
bool isBackgroundTile(vec2 tiles) {
|
||||
// A background tile is one where the largest CoC is positive
|
||||
return tiles.g > 0.0;
|
||||
}
|
||||
|
||||
bool isFastTile(const vec2 tiles) {
|
||||
bool isFastTile(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(const vec2 tiles) {
|
||||
return (tiles.g - tiles.r) <= abs(tiles.g) * 0.05;
|
||||
}
|
||||
|
||||
bool isTrivialTile(const vec2 tiles) {
|
||||
bool isTrivialTile(vec2 tiles) {
|
||||
float maxCocRadius = max(abs(tiles.r), abs(tiles.g));
|
||||
return maxCocRadius < MAX_IN_FOCUS_COC;
|
||||
}
|
||||
|
||||
float downsampleCoC(const vec4 c) {
|
||||
float downsampleCoC(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(const vec4 c, const float outCoc, const float scale) {
|
||||
vec4 downsampleCocWeights(vec4 c, float outCoc, 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
|
||||
|
||||
@@ -78,15 +78,15 @@ fragment {
|
||||
|
||||
void dummy(){ }
|
||||
|
||||
float smoothstep01(const float t) {
|
||||
float smoothstep01(float t) {
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
float ring(float x, const float c, const float r) {
|
||||
float ring(float x, float c, float r) {
|
||||
return 1.0 - smoothstep01(min(abs(x - c) / r, 1.0));
|
||||
}
|
||||
|
||||
vec3 sampleColor(const vec2 uv) {
|
||||
vec3 sampleColor(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(const vec2 uv) {
|
||||
);
|
||||
}
|
||||
|
||||
vec3 ghosts(const vec2 vertex_uv) {
|
||||
vec3 ghosts(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(const vec2 vertex_uv) {
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 halo(const vec2 uv) {
|
||||
vec3 halo(vec2 uv) {
|
||||
float haloRadius = materialParams.haloRadius;
|
||||
float haloThickness = materialParams.haloThickness;
|
||||
float threshold = materialParams.threshold.y;
|
||||
|
||||
@@ -72,7 +72,7 @@ fragment {
|
||||
#if defined(FILAMENT_HAS_FEATURE_TEXTURE_GATHER)
|
||||
#define gather textureGather
|
||||
#else
|
||||
vec4 gather(const mediump sampler2D color, highp vec2 p, const int comp) {
|
||||
vec4 gather(mediump sampler2D color, highp vec2 p, int comp) {
|
||||
highp ivec2 i = ivec2(p * materialParams.textureSize - 0.5);
|
||||
vec4 d;
|
||||
d[0] = texelFetchOffset(color, i, 0, ivec2(0, 1))[comp];
|
||||
|
||||
@@ -75,7 +75,7 @@ fragment {
|
||||
#if defined(FILAMENT_HAS_FEATURE_TEXTURE_GATHER)
|
||||
#define gather textureGather
|
||||
#else
|
||||
vec4 gather(const mediump sampler2D color, highp vec2 p, const int comp) {
|
||||
vec4 gather(mediump sampler2D color, highp vec2 p, int comp) {
|
||||
highp ivec2 i = ivec2(p * materialParams.textureSize - 0.5);
|
||||
vec4 d;
|
||||
d[0] = texelFetchOffset(color, i, 0, ivec2(0, 1))[comp];
|
||||
|
||||
@@ -76,7 +76,7 @@ fragment {
|
||||
#if defined(FILAMENT_HAS_FEATURE_TEXTURE_GATHER)
|
||||
#define gather textureGather
|
||||
#else
|
||||
vec4 gather(const mediump sampler2D color, highp vec2 p, const int comp) {
|
||||
vec4 gather(mediump sampler2D color, highp vec2 p, int comp) {
|
||||
highp ivec2 i = ivec2(p * materialParams.textureSize - 0.5);
|
||||
vec4 d;
|
||||
d[0] = texelFetchOffset(color, i, 0, ivec2(0, 1))[comp];
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
float vmax(const float v) {
|
||||
float vmax(float v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
highp vec4 sourceTexLod(const highp vec2 p, float m, float l) {
|
||||
highp vec4 sourceTexLod(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(const highp vec2 p, float m, float l) {
|
||||
}
|
||||
}
|
||||
|
||||
void tap(inout highp vec4 sum, const float weight, const highp vec2 position) {
|
||||
void tap(inout highp vec4 sum, float weight, highp vec2 position) {
|
||||
highp vec4 s = sourceTexLod(position, materialParams.level, materialParams.layer);
|
||||
sum += s * weight;
|
||||
}
|
||||
|
||||
void tapReinhard(inout highp vec4 sum, inout float totalWeight, const float weight, const highp vec2 position) {
|
||||
void tapReinhard(inout highp vec4 sum, inout float totalWeight, float weight, highp vec2 position) {
|
||||
highp vec4 s = sourceTexLod(position, materialParams.level, materialParams.layer);
|
||||
float w = weight / (1.0 + vmax(s));
|
||||
totalWeight += w;
|
||||
|
||||
@@ -48,7 +48,7 @@ fragment {
|
||||
return max(0.0, 1.0 - diff * diff);
|
||||
}
|
||||
|
||||
void tap(const highp sampler2DArray saoTexture,
|
||||
void tap(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;
|
||||
|
||||
@@ -60,14 +60,14 @@ fragment {
|
||||
return max(0.0, 1.0 - diff * diff);
|
||||
}
|
||||
|
||||
void tapAO(const highp sampler2DArray saoTexture, highp vec2 uv,
|
||||
void tapAO(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(const highp sampler2DArray saoTexture, highp vec2 uv,
|
||||
void tapBN(highp sampler2DArray saoTexture, highp vec2 uv,
|
||||
out vec3 bentNormal) {
|
||||
vec3 data = textureLod(saoTexture, vec3(uv, 1.0), 0.0).xyz;
|
||||
bentNormal = unpackBentNormal(data);
|
||||
|
||||
@@ -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, const float noise) {
|
||||
vec3 tapLocation(float i, 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(const float noise) {
|
||||
highp vec2 startPosition(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, const float noise) {
|
||||
vec3 tapLocationFast(float i, vec2 p, 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,
|
||||
const highp vec2 uv, const highp vec3 origin, const vec3 normal,
|
||||
const vec2 tapPosition, const float noise) {
|
||||
highp vec2 uv, highp vec3 origin, vec3 normal,
|
||||
vec2 tapPosition, float noise) {
|
||||
|
||||
vec3 tap = tapLocationFast(i, tapPosition, noise);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ struct ConeTraceSetup {
|
||||
uint sampleCount;
|
||||
};
|
||||
|
||||
highp float getWFromProjectionMatrix(const highp mat4 p, const vec3 v) {
|
||||
highp float getWFromProjectionMatrix(highp mat4 p, 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(const highp mat4 p, const vec3 v) {
|
||||
//return p[2][3] * v.z + p[3][3];
|
||||
}
|
||||
|
||||
highp float getViewSpaceZFromW(const highp mat4 p, const float w) {
|
||||
highp float getViewSpaceZFromW(highp mat4 p, 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, const highp sampler2D depthTexture) {
|
||||
float coneTraceOcclusion(in ConeTraceSetup setup, 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, const highp sampler2D depthTex
|
||||
}
|
||||
|
||||
float ssctDominantLightShadowing(highp vec2 uv, highp vec3 origin, vec3 normal,
|
||||
const highp sampler2D depthTexture, const highp vec2 fragCoord,
|
||||
highp sampler2D depthTexture, highp vec2 fragCoord,
|
||||
vec2 rayCount, ConeTraceSetup cone) {
|
||||
|
||||
float occlusion = 0.0;
|
||||
|
||||
@@ -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(const highp sampler2D depthTexture, const highp vec2 uv, float lod) {
|
||||
highp float sampleDepth(highp sampler2D depthTexture, highp vec2 uv, float lod) {
|
||||
return textureLod(depthTexture, uvToRenderTargetUV(uv), lod).r;
|
||||
}
|
||||
|
||||
highp float sampleDepthLinear(const highp sampler2D depthTexture,
|
||||
const highp vec2 uv, float lod) {
|
||||
highp float sampleDepthLinear(highp sampler2D depthTexture,
|
||||
highp vec2 uv, float lod) {
|
||||
return linearizeDepth(sampleDepth(depthTexture, uv, lod));
|
||||
}
|
||||
|
||||
|
||||
@@ -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(const highp vec3 position) {
|
||||
highp vec3 computeViewSpaceNormalLowQ(highp vec3 position) {
|
||||
return faceNormal(dFdx(position), dFdy(position));
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ highp vec3 computeViewSpaceNormalLowQ(const highp vec3 position) {
|
||||
// positionParams : invProjection[0][0] * 2, invProjection[1][1] * 2
|
||||
//
|
||||
highp vec3 computeViewSpaceNormalMediumQ(
|
||||
const highp sampler2D depthTexture, const highp vec2 uv,
|
||||
const highp vec3 position,
|
||||
highp sampler2D depthTexture, highp vec2 uv,
|
||||
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(
|
||||
const highp sampler2D depthTexture, const highp vec2 uv,
|
||||
const highp float depth, const highp vec3 position,
|
||||
highp sampler2D depthTexture, highp vec2 uv,
|
||||
highp float depth, 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(
|
||||
const highp sampler2D depthTexture, const highp vec2 uv,
|
||||
const highp float depth, const highp vec3 position,
|
||||
highp sampler2D depthTexture, highp vec2 uv,
|
||||
highp float depth, highp vec3 position,
|
||||
highp vec2 texel, highp vec2 positionParams) {
|
||||
// todo: maybe make this a quality parameter
|
||||
#if FILAMENT_QUALITY == FILAMENT_QUALITY_HIGH
|
||||
|
||||
@@ -74,25 +74,29 @@ private:
|
||||
};
|
||||
|
||||
TEST_F(CompilerTest, Simple) {
|
||||
auto vertex = R"(
|
||||
auto shader = R"(
|
||||
#version 300 es
|
||||
void main()
|
||||
{
|
||||
})"sv;
|
||||
|
||||
const char* const vs = vertex.data();
|
||||
GLint const vl = (GLint)vertex.size();
|
||||
const char* const src = shader.data();
|
||||
GLint const len = (GLint)shader.size();
|
||||
|
||||
GLuint const vid = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint const id = glCreateShader(GL_VERTEX_SHADER);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glShaderSource(vid, 1, &vs, &vl);
|
||||
glShaderSource(id, 1, &src, &len);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glCompileShader(vid);
|
||||
glCompileShader(id);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glDeleteShader(vid);
|
||||
GLint result = 0;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
EXPECT_EQ(result, GL_TRUE);
|
||||
|
||||
glDeleteShader(id);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
}
|
||||
|
||||
@@ -100,7 +104,7 @@ TEST_F(CompilerTest, CrashPVRUniFlexCompileToHw) {
|
||||
|
||||
// Some PowerVR driver crash with this shader
|
||||
|
||||
auto vertex = R"(
|
||||
auto shader = R"(
|
||||
#version 300 es
|
||||
|
||||
layout(location = 0) in vec4 mesh_position;
|
||||
@@ -114,19 +118,60 @@ void main() {
|
||||
gl_Position.z = dot(gl_Position.zw, frameUniforms.i);
|
||||
})"sv;
|
||||
|
||||
const char* const vs = vertex.data();
|
||||
GLint const vl = (GLint)vertex.size();
|
||||
const char* const src = shader.data();
|
||||
GLint const len = (GLint)shader.size();
|
||||
|
||||
GLuint const vid = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint const id = glCreateShader(GL_VERTEX_SHADER);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glShaderSource(vid, 1, &vs, &vl);
|
||||
glShaderSource(id, 1, &src, &len);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glCompileShader(vid);
|
||||
glCompileShader(id);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glDeleteShader(vid);
|
||||
GLint result = 0;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
EXPECT_EQ(result, GL_TRUE);
|
||||
|
||||
glDeleteShader(id);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
}
|
||||
|
||||
TEST_F(CompilerTest, ConstParameters) {
|
||||
|
||||
// Some PowerVR driver fail to compile this shader
|
||||
|
||||
auto shader = R"(
|
||||
#version 300 es
|
||||
|
||||
highp mat3 m;
|
||||
void buggy(const mediump vec3 n) {
|
||||
m*n;
|
||||
}
|
||||
|
||||
void main() {
|
||||
})"sv;
|
||||
|
||||
const char* const src = shader.data();
|
||||
GLint const len = (GLint)shader.size();
|
||||
|
||||
GLuint const id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glShaderSource(id, 1, &src, &len);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glCompileShader(id);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
GLint result = 0;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
EXPECT_EQ(result, GL_TRUE);
|
||||
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
|
||||
glDeleteShader(id);
|
||||
EXPECT_EQ(glGetError(), GL_NO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ vec3 unpackBentNormal(vec3 bn) {
|
||||
return bn * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
float specularAO(float NoV, float visibility, float roughness, const in SSAOInterpolationCache cache) {
|
||||
float specularAO(float NoV, float visibility, float roughness, 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, const in SSAOInte
|
||||
* The albedo term is meant to be the diffuse color or f0 for the diffuse and
|
||||
* specular terms respectively.
|
||||
*/
|
||||
vec3 gtaoMultiBounce(float visibility, const vec3 albedo) {
|
||||
vec3 gtaoMultiBounce(float visibility, 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, const vec3 albedo) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void multiBounceAO(float visibility, const vec3 albedo, inout vec3 color) {
|
||||
void multiBounceAO(float visibility, vec3 albedo, inout vec3 color) {
|
||||
#if MULTI_BOUNCE_AMBIENT_OCCLUSION == 1
|
||||
color *= gtaoMultiBounce(visibility, albedo);
|
||||
#endif
|
||||
}
|
||||
|
||||
void multiBounceSpecularAO(float visibility, const vec3 albedo, inout vec3 color) {
|
||||
void multiBounceSpecularAO(float visibility, vec3 albedo, inout vec3 color) {
|
||||
#if MULTI_BOUNCE_AMBIENT_OCCLUSION == 1 && SPECULAR_AMBIENT_OCCLUSION != SPECULAR_AO_OFF
|
||||
color *= gtaoMultiBounce(visibility, albedo);
|
||||
#endif
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
// Specular BRDF implementations
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
float D_GGX(float roughness, float NoH, const vec3 h) {
|
||||
float D_GGX(float roughness, float NoH, 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(const vec3 f0, float f90, float VoH) {
|
||||
vec3 F_Schlick(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(const vec3 f0, float VoH) {
|
||||
vec3 F_Schlick(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, const vec3 h) {
|
||||
float distribution(float roughness, float NoH, 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(const vec3 f0, float LoH) {
|
||||
vec3 fresnel(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, const vec3 h) {
|
||||
float distributionClearCoat(float roughness, float NoH, vec3 h) {
|
||||
#if BRDF_CLEAR_COAT_D == SPECULAR_D_GGX
|
||||
return D_GGX(roughness, NoH, h);
|
||||
#endif
|
||||
|
||||
@@ -22,13 +22,3 @@
|
||||
|
||||
#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
|
||||
|
||||
@@ -65,7 +65,7 @@ highp float getUserTimeMod(float m) {
|
||||
*
|
||||
* @public-api
|
||||
*/
|
||||
highp vec2 uvToRenderTargetUV(const highp vec2 uv) {
|
||||
highp vec2 uvToRenderTargetUV(highp vec2 uv) {
|
||||
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
return vec2(uv.x, 1.0 - uv.y);
|
||||
#else
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* @public-api
|
||||
*/
|
||||
float luminance(const vec3 linear) {
|
||||
float luminance(vec3 linear) {
|
||||
return dot(linear, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ float luminance(const 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(const highp float intensity, const highp float exposure) {
|
||||
float computePreExposedIntensity(highp float intensity, 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(const vec3 x) {
|
||||
vec3 Inverse_Tonemap_Filmic(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(const highp vec2 resolution) {
|
||||
highp vec2 getFragCoord(highp vec2 resolution) {
|
||||
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
return vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y);
|
||||
#else
|
||||
|
||||
@@ -82,7 +82,7 @@ float computeMicroShadowing(float NoL, float visibility) {
|
||||
* direction to match reference renderings when the roughness increases
|
||||
*/
|
||||
|
||||
vec3 getReflectedVector(const PixelParams pixel, const vec3 v, const vec3 n) {
|
||||
vec3 getReflectedVector(PixelParams pixel, vec3 v, 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(const PixelParams pixel, const vec3 v, const vec3 n) {
|
||||
return r;
|
||||
}
|
||||
|
||||
void getAnisotropyPixelParams(const MaterialInputs material, inout PixelParams pixel) {
|
||||
void getAnisotropyPixelParams(MaterialInputs material, inout PixelParams pixel) {
|
||||
#if defined(MATERIAL_HAS_ANISOTROPY)
|
||||
vec3 direction = material.anisotropyDirection;
|
||||
pixel.anisotropy = material.anisotropy;
|
||||
|
||||
@@ -14,11 +14,11 @@ float clampNoV(float NoV) {
|
||||
return max(NoV, MIN_N_DOT_V);
|
||||
}
|
||||
|
||||
vec3 computeDiffuseColor(const vec4 baseColor, float metallic) {
|
||||
vec3 computeDiffuseColor(vec4 baseColor, float metallic) {
|
||||
return baseColor.rgb * (1.0 - metallic);
|
||||
}
|
||||
|
||||
vec3 computeF0(const vec4 baseColor, float metallic, float reflectance) {
|
||||
vec3 computeF0(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(const vec3 specularColor) {
|
||||
float computeMetallicFromSpecularColor(vec3 specularColor) {
|
||||
return max3(specularColor);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ float f0ToIor(float f0) {
|
||||
return (1.0 + r) / (1.0 - r);
|
||||
}
|
||||
|
||||
vec3 f0ClearCoatToSurface(const vec3 f0) {
|
||||
vec3 f0ClearCoatToSurface(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
|
||||
|
||||
@@ -53,19 +53,19 @@ float sq(float x) {
|
||||
*
|
||||
* @public-api
|
||||
*/
|
||||
float max3(const vec3 v) {
|
||||
float max3(vec3 v) {
|
||||
return max(v.x, max(v.y, v.z));
|
||||
}
|
||||
|
||||
float vmax(const vec2 v) {
|
||||
float vmax(vec2 v) {
|
||||
return max(v.x, v.y);
|
||||
}
|
||||
|
||||
float vmax(const vec3 v) {
|
||||
float vmax(vec3 v) {
|
||||
return max(v.x, max(v.y, v.z));
|
||||
}
|
||||
|
||||
float vmax(const vec4 v) {
|
||||
float vmax(vec4 v) {
|
||||
return max(max(v.x, v.y), max(v.y, v.z));
|
||||
}
|
||||
|
||||
@@ -74,19 +74,19 @@ float vmax(const vec4 v) {
|
||||
*
|
||||
* @public-api
|
||||
*/
|
||||
float min3(const vec3 v) {
|
||||
float min3(vec3 v) {
|
||||
return min(v.x, min(v.y, v.z));
|
||||
}
|
||||
|
||||
float vmin(const vec2 v) {
|
||||
float vmin(vec2 v) {
|
||||
return min(v.x, v.y);
|
||||
}
|
||||
|
||||
float vmin(const vec3 v) {
|
||||
float vmin(vec3 v) {
|
||||
return min(v.x, min(v.y, v.z));
|
||||
}
|
||||
|
||||
float vmin(const vec4 v) {
|
||||
float vmin(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(const highp mat4 m, const highp vec3 v) {
|
||||
highp vec4 mulMat4x4Float3(highp mat4 m, 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(const highp mat4 m, const highp vec3 v) {
|
||||
*
|
||||
* @public-api
|
||||
*/
|
||||
highp vec3 mulMat3x3Float3(const highp mat4 m, const highp vec3 v) {
|
||||
highp vec3 mulMat3x3Float3(highp mat4 m, 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(const highp vec4 q, out highp vec3 n) {
|
||||
void toTangentFrame(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(const highp vec4 q, out highp vec3 n) {
|
||||
* Extracts the normal and tangent vectors of the tangent frame encoded in the
|
||||
* specified quaternion.
|
||||
*/
|
||||
void toTangentFrame(const highp vec4 q, out highp vec3 n, out highp vec3 t) {
|
||||
void toTangentFrame(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(const highp mat3 m) {
|
||||
highp mat3 cofactor(highp mat3 m) {
|
||||
highp float a = m[0][0];
|
||||
highp float b = m[1][0];
|
||||
highp float c = m[2][0];
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
* Normal bias is not used for VSM.
|
||||
*/
|
||||
|
||||
highp vec4 computeLightSpacePosition(highp vec3 p, const highp vec3 n,
|
||||
const highp vec3 dir, const float b, highp_mat4 lightFromWorldMatrix) {
|
||||
highp vec4 computeLightSpacePosition(highp vec3 p, highp vec3 n,
|
||||
highp vec3 dir, float b, highp mat4 lightFromWorldMatrix) {
|
||||
|
||||
#if !defined(VARIANT_HAS_VSM)
|
||||
highp float cosTheta = saturate(dot(n, dir));
|
||||
|
||||
@@ -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(const highp float depth);
|
||||
highp vec2 computeDepthMomentsVSM(highp float depth);
|
||||
|
||||
void main() {
|
||||
filament_lodBias = frameUniforms.lodBias;
|
||||
@@ -74,7 +74,7 @@ void main() {
|
||||
#endif
|
||||
}
|
||||
|
||||
highp vec2 computeDepthMomentsVSM(const highp float depth) {
|
||||
highp vec2 computeDepthMomentsVSM(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
|
||||
|
||||
@@ -30,7 +30,7 @@ float triangleNoise(highp vec2 n) {
|
||||
// Dithering
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
vec4 Dither_InterleavedGradientNoise(vec4 rgba, const highp float temporalNoise01) {
|
||||
vec4 Dither_InterleavedGradientNoise(vec4 rgba, 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, const highp float temporalNoise0
|
||||
return rgba + vec4(noise / 255.0);
|
||||
}
|
||||
|
||||
vec4 Dither_TriangleNoise(vec4 rgba, const highp float temporalNoise01) {
|
||||
vec4 Dither_TriangleNoise(vec4 rgba, 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, const highp float temporalNoise01) {
|
||||
return rgba + vec4(noise / 255.0);
|
||||
}
|
||||
|
||||
vec4 Dither_Vlachos(vec4 rgba, const highp float temporalNoise01) {
|
||||
vec4 Dither_Vlachos(vec4 rgba, 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, const highp float temporalNoise01) {
|
||||
return vec4(rgba.rgb + (noiseRGB / 255.0), rgba.a);
|
||||
}
|
||||
|
||||
vec4 Dither_TriangleNoiseRGB(vec4 rgba, const highp float temporalNoise01) {
|
||||
vec4 Dither_TriangleNoiseRGB(vec4 rgba, 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, const 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, const highp float temporalNoise01) {
|
||||
vec4 dither(vec4 rgba, highp float temporalNoise01) {
|
||||
#if DITHERING_OPERATOR == DITHERING_NONE
|
||||
return rgba;
|
||||
#elif DITHERING_OPERATOR == DITHERING_INTERLEAVED_NOISE
|
||||
|
||||
@@ -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, const uvec4 ids, const vec4 weights) {
|
||||
void skinNormal(inout vec3 n, uvec4 ids, 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, const uvec4 ids, const vec4 weights) {
|
||||
void skinPosition(inout vec3 p, uvec4 ids, vec4 weights) {
|
||||
p = mulBoneVertex(p, ids.x) * weights.x
|
||||
+ mulBoneVertex(p, ids.y) * weights.y
|
||||
+ mulBoneVertex(p, ids.z) * weights.z
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define SUN_AS_AREA_LIGHT
|
||||
#endif
|
||||
|
||||
vec3 sampleSunAreaLight(const vec3 lightDirection) {
|
||||
vec3 sampleSunAreaLight(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(const MaterialInputs material,
|
||||
const PixelParams pixel, inout vec3 color) {
|
||||
void evaluateDirectionalLight(MaterialInputs material,
|
||||
PixelParams pixel, inout vec3 color) {
|
||||
|
||||
Light light = getDirectionalLight();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// IBL utilities
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
vec3 decodeDataForIBL(const vec4 data) {
|
||||
vec3 decodeDataForIBL(vec4 data) {
|
||||
return data.rgb;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ vec3 prefilteredDFG(float perceptualRoughness, float NoV) {
|
||||
// IBL irradiance implementations
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
vec3 Irradiance_SphericalHarmonics(const vec3 n) {
|
||||
vec3 Irradiance_SphericalHarmonics(vec3 n) {
|
||||
return max(
|
||||
frameUniforms.iblSH[0]
|
||||
#if SPHERICAL_HARMONICS_BANDS >= 2
|
||||
@@ -61,7 +61,7 @@ vec3 Irradiance_SphericalHarmonics(const vec3 n) {
|
||||
, 0.0);
|
||||
}
|
||||
|
||||
vec3 Irradiance_RoughnessOne(const vec3 n) {
|
||||
vec3 Irradiance_RoughnessOne(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(const vec3 n) {
|
||||
// IBL irradiance dispatch
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
vec3 diffuseIrradiance(const vec3 n) {
|
||||
vec3 diffuseIrradiance(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(const vec3 r, float perceptualRoughness) {
|
||||
vec3 prefilteredRadiance(vec3 r, float perceptualRoughness) {
|
||||
float lod = perceptualRoughnessToLod(perceptualRoughness);
|
||||
return decodeDataForIBL(textureLod(light_iblSpecular, r, lod));
|
||||
}
|
||||
|
||||
vec3 prefilteredRadiance(const vec3 r, float roughness, float offset) {
|
||||
vec3 prefilteredRadiance(vec3 r, float roughness, float offset) {
|
||||
float lod = frameUniforms.iblRoughnessOneLevel * roughness;
|
||||
return decodeDataForIBL(textureLod(light_iblSpecular, r, lod + offset));
|
||||
}
|
||||
|
||||
vec3 getSpecularDominantDirection(const vec3 n, const vec3 r, float roughness) {
|
||||
vec3 getSpecularDominantDirection(vec3 n, vec3 r, float roughness) {
|
||||
return mix(r, n, roughness * roughness);
|
||||
}
|
||||
|
||||
vec3 specularDFG(const PixelParams pixel) {
|
||||
vec3 specularDFG(PixelParams pixel) {
|
||||
#if defined(SHADING_MODEL_CLOTH)
|
||||
return pixel.f0 * pixel.dfg.z;
|
||||
#else
|
||||
@@ -140,7 +140,7 @@ vec3 specularDFG(const PixelParams pixel) {
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 getReflectedVector(const PixelParams pixel, const vec3 n) {
|
||||
vec3 getReflectedVector(PixelParams pixel, 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(const PixelParams pixel, const vec3 n, const vec3 v, const float NoV) {
|
||||
vec3 isEvaluateSpecularIBL(PixelParams pixel, vec3 n, vec3 v, 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(const PixelParams pixel, const vec3 n, const vec3 v,
|
||||
return indirectSpecular;
|
||||
}
|
||||
|
||||
vec3 isEvaluateDiffuseIBL(const PixelParams pixel, vec3 n, vec3 v) {
|
||||
vec3 isEvaluateDiffuseIBL(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(const PixelParams pixel, vec3 n, vec3 v) {
|
||||
return indirectDiffuse * invNumSamples; // we bake 1/PI here, which cancels out
|
||||
}
|
||||
|
||||
void isEvaluateClearCoatIBL(const PixelParams pixel, float specularAO, inout vec3 Fd, inout vec3 Fr) {
|
||||
void isEvaluateClearCoatIBL(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(const PixelParams pixel, float specularAO, inout vec
|
||||
// IBL evaluation
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void evaluateClothIndirectDiffuseBRDF(const PixelParams pixel, inout float diffuse) {
|
||||
void evaluateClothIndirectDiffuseBRDF(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(const PixelParams pixel, inout float diffu
|
||||
#endif
|
||||
}
|
||||
|
||||
void evaluateSheenIBL(const PixelParams pixel, float diffuseAO,
|
||||
const in SSAOInterpolationCache cache, inout vec3 Fd, inout vec3 Fr) {
|
||||
void evaluateSheenIBL(PixelParams pixel, float diffuseAO,
|
||||
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(const PixelParams pixel, float diffuseAO,
|
||||
#endif
|
||||
}
|
||||
|
||||
void evaluateClearCoatIBL(const PixelParams pixel, float diffuseAO,
|
||||
const in SSAOInterpolationCache cache, inout vec3 Fd, inout vec3 Fr) {
|
||||
void evaluateClearCoatIBL(PixelParams pixel, float diffuseAO,
|
||||
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(const PixelParams pixel, float diffuseAO,
|
||||
#endif
|
||||
}
|
||||
|
||||
void evaluateSubsurfaceIBL(const PixelParams pixel, const vec3 diffuseIrradiance,
|
||||
void evaluateSubsurfaceIBL(PixelParams pixel, 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(const PixelParams pixel,
|
||||
const vec3 n, vec3 r, out Refraction ray) {
|
||||
void refractionSolidSphere(PixelParams pixel,
|
||||
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(const PixelParams pixel,
|
||||
ray.direction = refract(r, n1, pixel.etaRI);
|
||||
}
|
||||
|
||||
void refractionSolidBox(const PixelParams pixel,
|
||||
const vec3 n, vec3 r, out Refraction ray) {
|
||||
void refractionSolidBox(PixelParams pixel,
|
||||
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(const PixelParams pixel,
|
||||
#endif
|
||||
}
|
||||
|
||||
void refractionThinSphere(const PixelParams pixel,
|
||||
const vec3 n, vec3 r, out Refraction ray) {
|
||||
void refractionThinSphere(PixelParams pixel,
|
||||
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,9 +485,7 @@ void refractionThinSphere(const PixelParams pixel,
|
||||
ray.d = d;
|
||||
}
|
||||
|
||||
vec3 evaluateRefraction(
|
||||
const PixelParams pixel,
|
||||
const vec3 n0, vec3 E) {
|
||||
vec3 evaluateRefraction(PixelParams pixel, vec3 n0, vec3 E) {
|
||||
|
||||
Refraction ray;
|
||||
|
||||
@@ -556,7 +554,7 @@ vec3 evaluateRefraction(
|
||||
}
|
||||
#endif
|
||||
|
||||
void evaluateIBL(const MaterialInputs material, const PixelParams pixel, inout vec3 color) {
|
||||
void evaluateIBL(MaterialInputs material, PixelParams pixel, inout vec3 color) {
|
||||
// specular layer
|
||||
vec3 Fr = vec3(0.0);
|
||||
|
||||
|
||||
@@ -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(const highp vec3 fragCoords) {
|
||||
uvec3 getFroxelCoords(highp vec3 fragCoords) {
|
||||
uvec3 froxelCoord;
|
||||
|
||||
froxelCoord.xy = uvec2(fragCoords.xy * frameUniforms.froxelCountXY);
|
||||
@@ -48,7 +48,7 @@ uvec3 getFroxelCoords(const 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(const highp vec3 fragCoords) {
|
||||
uint getFroxelIndex(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(const uint froxelIndex) {
|
||||
FroxelParams getFroxelParams(uint froxelIndex) {
|
||||
uint w = froxelIndex >> 2u;
|
||||
uint c = froxelIndex & 0x3u;
|
||||
highp uvec4 d = froxelsUniforms.records[w];
|
||||
@@ -81,7 +81,7 @@ FroxelParams getFroxelParams(const 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(const uint index) {
|
||||
uint getLightIndex(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(const highp vec3 posToLight, float falloff) {
|
||||
float getDistanceAttenuation(highp vec3 posToLight, float falloff) {
|
||||
float distanceSquare = dot(posToLight, posToLight);
|
||||
float attenuation = getSquareFalloffAttenuation(distanceSquare, falloff);
|
||||
// light far attenuation
|
||||
@@ -109,7 +109,7 @@ float getDistanceAttenuation(const highp vec3 posToLight, float falloff) {
|
||||
return attenuation / max(distanceSquare, 1e-4);
|
||||
}
|
||||
|
||||
float getAngleAttenuation(const highp vec3 lightDir, const highp vec3 l, const highp vec2 scaleOffset) {
|
||||
float getAngleAttenuation(highp vec3 lightDir, highp vec3 l, 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(const highp vec3 lightDir, const highp vec3 l, const h
|
||||
* lightsUniforms uniform buffer.
|
||||
*/
|
||||
|
||||
Light getLight(const uint lightIndex) {
|
||||
Light getLight(uint lightIndex) {
|
||||
// retrieve the light data from the UBO
|
||||
|
||||
highp mat4 data = lightsUniforms.lights[lightIndex];
|
||||
@@ -176,8 +176,8 @@ Light getLight(const uint lightIndex) {
|
||||
* The result of the lighting computations is accumulated in the color
|
||||
* parameter, as linear HDR RGB.
|
||||
*/
|
||||
void evaluatePunctualLights(const MaterialInputs material,
|
||||
const PixelParams pixel, inout vec3 color) {
|
||||
void evaluatePunctualLights(MaterialInputs material,
|
||||
PixelParams pixel, inout vec3 color) {
|
||||
|
||||
// Fetch the light information stored in the froxel that contains the
|
||||
// current fragment
|
||||
|
||||
@@ -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(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,
|
||||
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,
|
||||
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(const highp vec3 vsOrigin, const highp vec3 vsDirection
|
||||
|
||||
// -- end "BSD 2-clause license" -------------------------------------------------------------------
|
||||
|
||||
highp mat4 scaleMatrix(const highp float x, const highp float y) {
|
||||
highp mat4 scaleMatrix(highp float x, highp float y) {
|
||||
mat4 m = mat4(1.0);
|
||||
m[0].x = x;
|
||||
m[1].y = y;
|
||||
@@ -200,7 +200,7 @@ highp mat4 scaleMatrix(const highp float x, const highp float y) {
|
||||
*
|
||||
* If there is no hit, the return value is vec4(0).
|
||||
*/
|
||||
vec4 evaluateScreenSpaceReflections(const highp vec3 wsRayDirection) {
|
||||
vec4 evaluateScreenSpaceReflections(highp vec3 wsRayDirection) {
|
||||
vec4 Fr = vec4(0.0);
|
||||
highp vec3 wsRayStart = shading_position + frameUniforms.ssrBias * wsRayDirection;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ layout(location = 0) out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
#if defined(MATERIAL_HAS_POST_LIGHTING_COLOR)
|
||||
void blendPostLightingColor(const MaterialInputs material, inout vec4 color) {
|
||||
void blendPostLightingColor(MaterialInputs material, inout vec4 color) {
|
||||
#if defined(POST_LIGHTING_BLEND_MODE_OPAQUE)
|
||||
color = material.postLightingColor;
|
||||
#elif defined(POST_LIGHTING_BLEND_MODE_TRANSPARENT)
|
||||
|
||||
@@ -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(const MaterialVertexInputs material) {
|
||||
vec4 getWorldPosition(MaterialVertexInputs material) {
|
||||
return material.worldPosition;
|
||||
}
|
||||
|
||||
#ifdef VERTEX_DOMAIN_DEVICE
|
||||
#ifdef MATERIAL_HAS_CLIP_SPACE_TRANSFORM
|
||||
mat4 getMaterialClipSpaceTransform(const MaterialVertexInputs material) {
|
||||
mat4 getMaterialClipSpaceTransform(MaterialVertexInputs material) {
|
||||
return material.clipSpaceTransform;
|
||||
}
|
||||
#endif // MATERIAL_HAS_CLIP_SPACE_TRANSFORM
|
||||
|
||||
@@ -38,7 +38,7 @@ void applyAlphaMask(inout vec4 baseColor) {}
|
||||
#endif
|
||||
|
||||
#if defined(GEOMETRIC_SPECULAR_AA)
|
||||
float normalFiltering(float perceptualRoughness, const vec3 worldNormal) {
|
||||
float normalFiltering(float perceptualRoughness, 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, const vec3 worldNormal) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void getCommonPixelParams(const MaterialInputs material, inout PixelParams pixel) {
|
||||
void getCommonPixelParams(MaterialInputs material, inout PixelParams pixel) {
|
||||
vec4 baseColor = material.baseColor;
|
||||
applyAlphaMask(baseColor);
|
||||
|
||||
@@ -137,7 +137,7 @@ void getCommonPixelParams(const MaterialInputs material, inout PixelParams pixel
|
||||
#endif
|
||||
}
|
||||
|
||||
void getSheenPixelParams(const MaterialInputs material, inout PixelParams pixel) {
|
||||
void getSheenPixelParams(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(const MaterialInputs material, inout PixelParams pixel)
|
||||
#endif
|
||||
}
|
||||
|
||||
void getClearCoatPixelParams(const MaterialInputs material, inout PixelParams pixel) {
|
||||
void getClearCoatPixelParams(MaterialInputs material, inout PixelParams pixel) {
|
||||
#if defined(MATERIAL_HAS_CLEAR_COAT)
|
||||
pixel.clearCoat = material.clearCoat;
|
||||
|
||||
@@ -181,7 +181,7 @@ void getClearCoatPixelParams(const MaterialInputs material, inout PixelParams pi
|
||||
#endif
|
||||
}
|
||||
|
||||
void getRoughnessPixelParams(const MaterialInputs material, inout PixelParams pixel) {
|
||||
void getRoughnessPixelParams(MaterialInputs material, inout PixelParams pixel) {
|
||||
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
|
||||
float perceptualRoughness = computeRoughnessFromGlossiness(material.glossiness);
|
||||
#else
|
||||
@@ -209,7 +209,7 @@ void getRoughnessPixelParams(const MaterialInputs material, inout PixelParams pi
|
||||
pixel.roughness = perceptualRoughnessToRoughness(pixel.perceptualRoughness);
|
||||
}
|
||||
|
||||
void getSubsurfacePixelParams(const MaterialInputs material, inout PixelParams pixel) {
|
||||
void getSubsurfacePixelParams(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(const MaterialInputs material, out PixelParams pixel) {
|
||||
void getPixelParams(MaterialInputs material, out PixelParams pixel) {
|
||||
getCommonPixelParams(material, pixel);
|
||||
getSheenPixelParams(material, pixel);
|
||||
getClearCoatPixelParams(material, pixel);
|
||||
@@ -265,7 +265,7 @@ void getPixelParams(const MaterialInputs material, out PixelParams pixel) {
|
||||
*
|
||||
* Returns a pre-exposed HDR RGBA color in linear space.
|
||||
*/
|
||||
vec4 evaluateLights(const MaterialInputs material) {
|
||||
vec4 evaluateLights(MaterialInputs material) {
|
||||
PixelParams pixel;
|
||||
getPixelParams(material, pixel);
|
||||
|
||||
@@ -295,7 +295,7 @@ vec4 evaluateLights(const MaterialInputs material) {
|
||||
return vec4(color, computeDiffuseAlpha(material.baseColor.a));
|
||||
}
|
||||
|
||||
void addEmissive(const MaterialInputs material, inout vec4 color) {
|
||||
void addEmissive(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(const MaterialInputs material, inout vec4 color) {
|
||||
*
|
||||
* Returns a pre-exposed HDR RGBA color in linear space.
|
||||
*/
|
||||
vec4 evaluateMaterial(const MaterialInputs material) {
|
||||
vec4 evaluateMaterial(MaterialInputs material) {
|
||||
vec4 color = evaluateLights(material);
|
||||
addEmissive(material, color);
|
||||
return color;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
vec3 customSurfaceShading(const MaterialInputs materialInputs,
|
||||
const PixelParams pixel, const Light light, float visibility) {
|
||||
vec3 customSurfaceShading(MaterialInputs materialInputs,
|
||||
PixelParams pixel, Light light, float visibility) {
|
||||
|
||||
LightData lightData;
|
||||
lightData.colorIntensity = light.colorIntensity;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* computation of these events is not physically based but can add necessary
|
||||
* details to a material.
|
||||
*/
|
||||
vec3 surfaceShading(const PixelParams pixel, const Light light, float occlusion) {
|
||||
vec3 surfaceShading(PixelParams pixel, Light light, float occlusion) {
|
||||
vec3 h = normalize(shading_view + light.l);
|
||||
float NoL = light.NoL;
|
||||
float NoH = saturate(dot(shading_normal, h));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#if defined(MATERIAL_HAS_SHEEN_COLOR)
|
||||
vec3 sheenLobe(const PixelParams pixel, float NoV, float NoL, float NoH) {
|
||||
vec3 sheenLobe(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(const PixelParams pixel, float NoV, float NoL, float NoH) {
|
||||
#endif
|
||||
|
||||
#if defined(MATERIAL_HAS_CLEAR_COAT)
|
||||
float clearCoatLobe(const PixelParams pixel, const vec3 h, float NoH, float LoH, out float Fcc) {
|
||||
float clearCoatLobe(PixelParams pixel, 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(const PixelParams pixel, const vec3 h, float NoH, float LoH,
|
||||
#endif
|
||||
|
||||
#if defined(MATERIAL_HAS_ANISOTROPY)
|
||||
vec3 anisotropicLobe(const PixelParams pixel, const Light light, const vec3 h,
|
||||
vec3 anisotropicLobe(PixelParams pixel, Light light, vec3 h,
|
||||
float NoV, float NoL, float NoH, float LoH) {
|
||||
|
||||
vec3 l = light.l;
|
||||
@@ -58,7 +58,7 @@ vec3 anisotropicLobe(const PixelParams pixel, const Light light, const vec3 h,
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 isotropicLobe(const PixelParams pixel, const Light light, const vec3 h,
|
||||
vec3 isotropicLobe(PixelParams pixel, Light light, vec3 h,
|
||||
float NoV, float NoL, float NoH, float LoH) {
|
||||
|
||||
float D = distribution(pixel.roughness, NoH, h);
|
||||
@@ -68,7 +68,7 @@ vec3 isotropicLobe(const PixelParams pixel, const Light light, const vec3 h,
|
||||
return (D * V) * F;
|
||||
}
|
||||
|
||||
vec3 specularLobe(const PixelParams pixel, const Light light, const vec3 h,
|
||||
vec3 specularLobe(PixelParams pixel, Light light, 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(const PixelParams pixel, const Light light, const vec3 h,
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 diffuseLobe(const PixelParams pixel, float NoV, float NoL, float LoH) {
|
||||
vec3 diffuseLobe(PixelParams pixel, float NoV, float NoL, float LoH) {
|
||||
return pixel.diffuseColor * diffuse(pixel.roughness, NoV, NoL, LoH);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ vec3 diffuseLobe(const 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(const PixelParams pixel, const Light light, float occlusion) {
|
||||
vec3 surfaceShading(PixelParams pixel, Light light, float occlusion) {
|
||||
vec3 h = normalize(shading_view + light.l);
|
||||
|
||||
float NoV = shading_NoV;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* scattering. The BTDF itself is not physically based and does not represent a
|
||||
* correct interpretation of transmission events.
|
||||
*/
|
||||
vec3 surfaceShading(const PixelParams pixel, const Light light, float occlusion) {
|
||||
vec3 surfaceShading(PixelParams pixel, Light light, float occlusion) {
|
||||
vec3 h = normalize(shading_view + light.l);
|
||||
|
||||
float NoL = light.NoL;
|
||||
|
||||
@@ -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(const MaterialInputs material) {
|
||||
void prepareMaterial(MaterialInputs material) {
|
||||
#if defined(HAS_ATTRIBUTE_TANGENTS)
|
||||
#if defined(MATERIAL_HAS_NORMAL)
|
||||
shading_normal = normalize(shading_tangentToWorld * material.normal);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* screen-space reflection shading
|
||||
*/
|
||||
vec4 evaluateMaterial(const MaterialInputs material) {
|
||||
vec4 evaluateMaterial(MaterialInputs material) {
|
||||
|
||||
#if defined(MATERIAL_HAS_REFLECTIONS)
|
||||
PixelParams pixel;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
void addEmissive(const MaterialInputs material, inout vec4 color) {
|
||||
void addEmissive(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(const MaterialInputs material) {
|
||||
vec4 evaluateMaterial(MaterialInputs material) {
|
||||
vec4 color = material.baseColor;
|
||||
|
||||
#if defined(BLEND_MODE_MASKED)
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
// PCF Shadow Sampling
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
float sampleDepth(const mediump sampler2DArrayShadow map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, highp vec2 uv, float depth) {
|
||||
float sampleDepth(mediump sampler2DArrayShadow map,
|
||||
highp vec4 scissorNormalized,
|
||||
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(const mediump sampler2DArrayShadow map,
|
||||
|
||||
#if SHADOW_SAMPLING_METHOD == SHADOW_SAMPLING_PCF_HARD
|
||||
// use hardware assisted PCF
|
||||
float ShadowSample_PCF_Hard(const mediump sampler2DArrayShadow map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
float ShadowSample_PCF_Hard(mediump sampler2DArrayShadow map,
|
||||
highp vec4 scissorNormalized,
|
||||
uint layer, 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(const mediump sampler2DArrayShadow map,
|
||||
|
||||
#if SHADOW_SAMPLING_METHOD == SHADOW_SAMPLING_PCF_LOW
|
||||
// use hardware assisted PCF + 3x3 gaussian filter
|
||||
float ShadowSample_PCF_Low(const mediump sampler2DArrayShadow map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
float ShadowSample_PCF_Low(mediump sampler2DArrayShadow map,
|
||||
highp vec4 scissorNormalized,
|
||||
uint layer, 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(const mediump sampler2DArrayShadow map,
|
||||
#endif
|
||||
|
||||
// use manual PCF
|
||||
float ShadowSample_PCF(const mediump sampler2DArray map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
float ShadowSample_PCF(mediump sampler2DArray map,
|
||||
highp vec4 scissorNormalized,
|
||||
uint layer, 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(const highp vec3 position) {
|
||||
highp vec2 computeReceiverPlaneDepthBias(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(const bool DIRECTIONAL, const int index, const highp float zLight) {
|
||||
float getPenumbraLs(bool DIRECTIONAL, int index, highp float zLight) {
|
||||
float penumbra;
|
||||
// This conditional is resolved at compile time
|
||||
if (DIRECTIONAL) {
|
||||
@@ -179,7 +179,7 @@ float getPenumbraLs(const bool DIRECTIONAL, const int index, const highp float z
|
||||
return penumbra;
|
||||
}
|
||||
|
||||
float getPenumbraRatio(const bool DIRECTIONAL, const int index,
|
||||
float getPenumbraRatio(bool DIRECTIONAL, 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(const bool DIRECTIONAL, const int index,
|
||||
}
|
||||
|
||||
void blockerSearchAndFilter(out float occludedCount, out float z_occSum,
|
||||
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) {
|
||||
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) {
|
||||
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(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 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 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(const 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(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) {
|
||||
float ShadowSample_DPCF(bool DIRECTIONAL,
|
||||
mediump sampler2DArray map,
|
||||
highp vec4 scissorNormalized,
|
||||
uint layer, int index,
|
||||
highp vec4 shadowPosition, 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(const bool DIRECTIONAL,
|
||||
return 1.0 - percentageOccluded;
|
||||
}
|
||||
|
||||
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) {
|
||||
float ShadowSample_PCSS(bool DIRECTIONAL,
|
||||
mediump sampler2DArray map,
|
||||
highp vec4 scissorNormalized,
|
||||
uint layer, int index,
|
||||
highp vec4 shadowPosition, 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(const float min, const float max, const float v) {
|
||||
float linstep(float min, float max, float v) {
|
||||
// we could use smoothstep() too
|
||||
return clamp((v - min) / (max - min), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float reduceLightBleed(const float pMax, const float amount) {
|
||||
float reduceLightBleed(float pMax, float amount) {
|
||||
// Remove the [0, amount] tail and linearly rescale (amount, 1].
|
||||
return linstep(amount, 1.0, pMax);
|
||||
}
|
||||
|
||||
float chebyshevUpperBound(const highp vec2 moments, const highp float mean,
|
||||
const highp float minVariance, const float lightBleedReduction) {
|
||||
float chebyshevUpperBound(highp vec2 moments, highp float mean,
|
||||
highp float minVariance, float lightBleedReduction) {
|
||||
// Donnelly and Lauritzen 2006, "Variance Shadow Maps"
|
||||
|
||||
highp float variance = moments.y - (moments.x * moments.x);
|
||||
@@ -460,15 +460,15 @@ float chebyshevUpperBound(const highp vec2 moments, const highp float mean,
|
||||
return mean <= moments.x ? 1.0 : pMax;
|
||||
}
|
||||
|
||||
float evaluateShadowVSM(const highp vec2 moments, const highp float depth) {
|
||||
float evaluateShadowVSM(highp vec2 moments, highp float depth) {
|
||||
highp float depthScale = frameUniforms.vsmDepthScale * depth;
|
||||
highp float minVariance = depthScale * depthScale;
|
||||
return chebyshevUpperBound(moments, depth, minVariance, frameUniforms.vsmLightBleedReduction);
|
||||
}
|
||||
|
||||
float ShadowSample_VSM(const bool ELVSM, const highp sampler2DArray shadowMap,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
float ShadowSample_VSM(bool ELVSM, highp sampler2DArray shadowMap,
|
||||
in highp vec4 scissorNormalized,
|
||||
in uint layer, 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(const bool ELVSM, const highp sampler2DArray shadowMap,
|
||||
|
||||
// get texture coordinate for directional and spot shadow maps
|
||||
#if defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
highp vec4 getShadowPosition(const int cascade) {
|
||||
highp vec4 getShadowPosition(int cascade) {
|
||||
return getCascadeLightSpacePosition(cascade);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_DYNAMIC_LIGHTING)
|
||||
highp vec4 getShadowPosition(const int index, const highp vec3 dir, const highp float zLight) {
|
||||
highp vec4 getShadowPosition(int index, highp vec3 dir, highp float zLight) {
|
||||
return getSpotLightSpacePosition(index, dir, zLight);
|
||||
}
|
||||
#endif
|
||||
|
||||
int getPointLightFace(const highp vec3 r) {
|
||||
int getPointLightFace(highp vec3 r) {
|
||||
highp vec4 tc;
|
||||
highp float rx = abs(r.x);
|
||||
highp float ry = abs(r.y);
|
||||
@@ -534,9 +534,9 @@ int getPointLightFace(const highp vec3 r) {
|
||||
}
|
||||
|
||||
// PCF sampling
|
||||
float shadow(const bool DIRECTIONAL,
|
||||
const mediump sampler2DArrayShadow shadowMap,
|
||||
const int index, highp vec4 shadowPosition, highp float zLight) {
|
||||
float shadow(bool DIRECTIONAL,
|
||||
in mediump sampler2DArrayShadow shadowMap,
|
||||
in 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(const bool DIRECTIONAL,
|
||||
}
|
||||
|
||||
// Shadow requiring a sampler2D sampler (VSM, DPCF and PCSS)
|
||||
float shadow(const bool DIRECTIONAL,
|
||||
const highp sampler2DArray shadowMap,
|
||||
const int index, highp vec4 shadowPosition, highp float zLight) {
|
||||
float shadow(bool DIRECTIONAL,
|
||||
in highp sampler2DArray shadowMap,
|
||||
in 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
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// uv: viewport coordinates
|
||||
// vignette: pre-computed parameters midPoint, radius, aspect and feather
|
||||
// vignetteColor: color of the vignette effect
|
||||
vec3 vignette(const vec3 color, const highp vec2 uv, const vec4 vignette, const vec4 vignetteColor) {
|
||||
vec3 vignette(vec3 color, highp vec2 uv, vec4 vignette, vec4 vignetteColor) {
|
||||
float midPoint = vignette.x;
|
||||
float radius = vignette.y;
|
||||
float aspect = vignette.z;
|
||||
|
||||
Reference in New Issue
Block a user