the math needs to be maintained in highp, including during the blur pass. we add the ability to specify a "precision" qualifier to the "output" of a post-process material. we also remove the mediump clamping we used to do on mobile, it shouldn't be done automatically behind the scenes, it's up to the shaders to do it if it makes sense.
96 lines
3.0 KiB
GLSL
96 lines
3.0 KiB
GLSL
#if defined(VARIANT_HAS_VSM)
|
|
layout(location = 0) out highp vec4 fragColor;
|
|
#elif defined(VARIANT_HAS_PICKING)
|
|
# if __VERSION__ == 100
|
|
highp vec4 outPicking;
|
|
# else
|
|
# if MATERIAL_FEATURE_LEVEL == 0
|
|
layout(location = 0) out highp vec4 outPicking;
|
|
# else
|
|
layout(location = 0) out highp vec2 outPicking;
|
|
# endif
|
|
# endif
|
|
#else
|
|
// not color output
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Depth
|
|
//
|
|
// note: VARIANT_HAS_VSM and VARIANT_HAS_PICKING are mutually exclusive
|
|
//------------------------------------------------------------------------------
|
|
|
|
highp vec2 computeDepthMomentsVSM(const highp float depth);
|
|
|
|
void main() {
|
|
filament_lodBias = frameUniforms.lodBias;
|
|
|
|
initObjectUniforms(object_uniforms);
|
|
|
|
#if defined(BLEND_MODE_MASKED) || ((defined(BLEND_MODE_TRANSPARENT) || defined(BLEND_MODE_FADE)) && defined(MATERIAL_HAS_TRANSPARENT_SHADOW))
|
|
MaterialInputs inputs;
|
|
initMaterial(inputs);
|
|
material(inputs);
|
|
|
|
float alpha = inputs.baseColor.a;
|
|
#if defined(BLEND_MODE_MASKED)
|
|
if (alpha < getMaskThreshold()) {
|
|
discard;
|
|
}
|
|
#endif
|
|
|
|
#if defined(MATERIAL_HAS_TRANSPARENT_SHADOW)
|
|
// Interleaved gradient noise, see dithering.fs
|
|
float noise = interleavedGradientNoise(gl_FragCoord.xy);
|
|
if (noise >= alpha) {
|
|
discard;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(VARIANT_HAS_VSM)
|
|
// interpolated depth is stored in vertex_worldPosition.w (see main.vs)
|
|
// we always compute the "negative" side of ELVSM because the cost is small, and this allows
|
|
// EVSM/ELVSM choice to be done on the CPU side more easily.
|
|
highp float depth = vertex_worldPosition.w;
|
|
depth = exp(frameUniforms.vsmExponent * depth);
|
|
fragColor.xy = computeDepthMomentsVSM(depth);
|
|
fragColor.zw = computeDepthMomentsVSM(-1.0 / depth); // requires at least RGBA16F
|
|
#elif defined(VARIANT_HAS_PICKING)
|
|
#if MATERIAL_FEATURE_LEVEL == 0
|
|
outPicking.a = float((object_uniforms.objectId / 65536) % 256) / 255.0;
|
|
outPicking.b = float((object_uniforms.objectId / 256) % 256) / 255.0;
|
|
outPicking.g = float( object_uniforms.objectId % 256) / 255.0;
|
|
outPicking.r = vertex_position.z / vertex_position.w;
|
|
#else
|
|
outPicking.x = float(object_uniforms.objectId);
|
|
outPicking.y = vertex_position.z / vertex_position.w;
|
|
#endif
|
|
#if __VERSION__ == 100
|
|
gl_FragData[0] = outPicking;
|
|
#endif
|
|
#else
|
|
// that's it
|
|
#endif
|
|
}
|
|
|
|
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
|
|
highp vec2 moments;
|
|
|
|
// the first moment is just the depth (average)
|
|
moments.x = depth;
|
|
|
|
// compute the 2nd moment over the pixel extents.
|
|
moments.y = depth * depth;
|
|
|
|
// the local linear approximation is not correct with a warped depth
|
|
//highp float dx = dFdx(depth);
|
|
//highp float dy = dFdy(depth);
|
|
//moments.y += 0.25 * (dx * dx + dy * dy);
|
|
|
|
return moments;
|
|
}
|