playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
3 lines (2 loc) • 4 kB
TypeScript
declare const _default: "\nvar texture_msdfMap: texture_2d<f32>;\nvar texture_msdfMapSampler: sampler;\n\nfn median(r: f32, g: f32, b: f32) -> f32 {\n return max(min(r, g), min(max(r, g), b));\n}\n\nuniform font_sdfIntensity: f32; // intensity is used to boost the value read from the SDF, 0 is no boost, 1.0 is max boost\nuniform font_pxrange: f32; // number of texels of SDF spread (inside <-> outside) in the atlas\n\n#ifndef LIT_MSDF_TEXT_ATTRIBUTE\n uniform outline_color: vec4f;\n uniform outline_thickness: f32;\n uniform shadow_color: vec4f;\n uniform shadow_offset: vec2f;\n#else\n varying outline_color: vec4f;\n varying outline_thickness: f32;\n varying shadow_color: vec4f;\n varying shadow_offset: vec2f;\n#endif\n\nfn applyMsdf(color_in: vec4f) -> vec4f {\n\n #ifndef LIT_MSDF_TEXT_ATTRIBUTE\n var outline_colorValue = uniform.outline_color;\n var outline_thicknessValue = uniform.outline_thickness;\n var shadow_colorValue = uniform.shadow_color;\n var shadow_offsetValue = uniform.shadow_offset;\n #else\n var outline_colorValue = outline_color;\n var outline_thicknessValue = outline_thickness;\n var shadow_colorValue = shadow_color;\n var shadow_offsetValue = shadow_offset;\n #endif\n\n // Convert to linear space before processing\n // TODO: ideally this would receive the color in linear space, but that would require larger changes\n // on the engine side, with the way premultiplied alpha is handled as well.\n var color = vec4f(gammaCorrectInputVec3(color_in.rgb), color_in.a);\n\n // sample the field\n let tsample: vec3f = textureSample(texture_msdfMap, texture_msdfMapSampler, vUv0).rgb;\n let uvShdw: vec2f = vUv0 - shadow_offsetValue;\n let ssample: vec3f = textureSample(texture_msdfMap, texture_msdfMapSampler, uvShdw).rgb;\n\n // get the signed distance value\n let sigDist: f32 = median(tsample.r, tsample.g, tsample.b);\n let sigDistShdw: f32 = median(ssample.r, ssample.g, ssample.b);\n\n // coverage threshold (0.5 = glyph edge); font_sdfIntensity fattens the glyph\n let edge: f32 = 0.5 - 0.5 * uniform.font_sdfIntensity;\n\n // Width of the distance-field transition in screen pixels, from the uv magnification (both\n // axes) and the atlas spread. Stable under motion and minification, unlike the distance-field\n // gradient whose noise on undersampled glyphs makes small text shimmer. Floored at 2.5 so the\n // minified coverage ramp spans at most 0.4 of the field's range ([edge - 0.2, edge + 0.2]):\n // a lower floor lets the ramp (and its outline/shadow-shifted copies) reach the field's far\n // tail, which washes translucent outline across the whole glyph quad and hazes distant text.\n let unitRange: vec2f = vec2f(uniform.font_pxrange) / vec2f(textureDimensions(texture_msdfMap, 0));\n let uvDeriv: vec2f = max(abs(dpdx(vUv0)) + abs(dpdy(vUv0)), vec2f(1e-6));\n let screenPxRange: f32 = max(0.5 * dot(unitRange, vec2f(1.0) / uvDeriv), 2.5);\n\n let inside: f32 = clamp(screenPxRange * (sigDist - edge) + 0.5, 0.0, 1.0);\n let outline: f32 = clamp(screenPxRange * (sigDist + outline_thicknessValue - edge) + 0.5, 0.0, 1.0);\n let shadow: f32 = clamp(screenPxRange * (sigDistShdw + outline_thicknessValue - edge) + 0.5, 0.0, 1.0);\n\n let tcolor_outline: vec4f = outline * vec4f(outline_colorValue.a * outline_colorValue.rgb, outline_colorValue.a);\n var tcolor: vec4f = select(vec4f(0.0), tcolor_outline, outline > inside);\n tcolor = mix(tcolor, color, inside);\n\n let scolor_shadow: vec4f = shadow * vec4f(shadow_colorValue.a * shadow_colorValue.rgb, shadow_colorValue.a);\n let scolor: vec4f = select(tcolor, scolor_shadow, shadow > outline);\n tcolor = mix(scolor, tcolor, outline);\n\n // Convert back to gamma space before returning\n tcolor = vec4f(gammaCorrectOutput(tcolor.rgb), tcolor.a);\n\n return tcolor;\n}\n";
export default _default;