UNPKG

molstar

Version:

A comprehensive macromolecular library.

219 lines (169 loc) 8.29 kB
"use strict"; /** * Slightly adapted from https://github.com/mrdoob/three.js * MIT License Copyright (c) 2010-2020 three.js authors * * WebGL port of Subpixel Morphological Antialiasing (SMAA) v2.8 * Preset: SMAA 1x Medium (with color edge detection) * https://github.com/iryoku/smaa/releases/tag/v2.8 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.weights_frag = void 0; exports.weights_frag = ` precision highp float; precision highp int; precision highp sampler2D; #define SMAASampleLevelZeroOffset(tex, coord, offset) texture2D(tex, coord + float(offset) * uTexSizeInv, 0.0) #define SMAA_AREATEX_MAX_DISTANCE 16 #define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0)) #define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) uniform sampler2D tEdges; uniform sampler2D tArea; uniform sampler2D tSearch; uniform vec2 uTexSizeInv; varying vec2 vUv; varying vec4 vOffset[3]; varying vec2 vPixCoord; #if __VERSION__ == 100 vec2 round(vec2 x) { return sign(x) * floor(abs(x) + 0.5); } #endif float SMAASearchLength(sampler2D searchTex, vec2 e, float bias, float scale) { // Not required if searchTex accesses are set to point: // float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0); // e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE + // e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE; e.r = bias + e.r * scale; return 255.0 * texture2D(searchTex, e, 0.0).r; } float SMAASearchXLeft(sampler2D edgesTex, sampler2D searchTex, vec2 texCoord, float end) { /** * @PSEUDO_GATHER4 * This texCoord has been offset by (-0.25, -0.125) in the vertex shader to * sample between edge, thus fetching four edges in a row. * Sampling with different offsets in each direction allows to disambiguate * which edges are active from the four fetched ones. */ vec2 e = vec2(0.0, 1.0); for (int i = 0; i < dMaxSearchSteps; i++) { // WebGL port note: Changed while to for e = texture2D( edgesTex, texCoord, 0.0).rg; texCoord -= vec2(2.0, 0.0) * uTexSizeInv; if (!(texCoord.x > end && e.g > 0.8281 && e.r == 0.0)) break; } // We correct the previous (-0.25, -0.125) offset we applied: texCoord.x += 0.25 * uTexSizeInv.x; // The searches are bias by 1, so adjust the coords accordingly: texCoord.x += uTexSizeInv.x; // Disambiguate the length added by the last step: texCoord.x += 2.0 * uTexSizeInv.x; // Undo last step texCoord.x -= uTexSizeInv.x * SMAASearchLength(searchTex, e, 0.0, 0.5); return texCoord.x; } float SMAASearchXRight(sampler2D edgesTex, sampler2D searchTex, vec2 texCoord, float end) { vec2 e = vec2( 0.0, 1.0 ); for (int i = 0; i < dMaxSearchSteps; i++) { // WebGL port note: Changed while to for e = texture2D(edgesTex, texCoord, 0.0).rg; texCoord += vec2(2.0, 0.0) * uTexSizeInv; if (!(texCoord.x < end && e.g > 0.8281 && e.r == 0.0)) break; } texCoord.x -= 0.25 * uTexSizeInv.x; texCoord.x -= uTexSizeInv.x; texCoord.x -= 2.0 * uTexSizeInv.x; texCoord.x += uTexSizeInv.x * SMAASearchLength( searchTex, e, 0.5, 0.5 ); return texCoord.x; } float SMAASearchYUp(sampler2D edgesTex, sampler2D searchTex, vec2 texCoord, float end) { vec2 e = vec2( 1.0, 0.0 ); for (int i = 0; i < dMaxSearchSteps; i++) { // WebGL port note: Changed while to for e = texture2D(edgesTex, texCoord, 0.0).rg; texCoord += vec2(0.0, 2.0) * uTexSizeInv; // WebGL port note: Changed sign if (!(texCoord.y > end && e.r > 0.8281 && e.g == 0.0)) break; } texCoord.y -= 0.25 * uTexSizeInv.y; // WebGL port note: Changed sign texCoord.y -= uTexSizeInv.y; // WebGL port note: Changed sign texCoord.y -= 2.0 * uTexSizeInv.y; // WebGL port note: Changed sign texCoord.y += uTexSizeInv.y * SMAASearchLength(searchTex, e.gr, 0.0, 0.5); // WebGL port note: Changed sign return texCoord.y; } float SMAASearchYDown(sampler2D edgesTex, sampler2D searchTex, vec2 texCoord, float end) { vec2 e = vec2( 1.0, 0.0 ); for (int i = 0; i < dMaxSearchSteps; i++) { // WebGL port note: Changed while to for e = texture2D(edgesTex, texCoord, 0.0).rg; texCoord -= vec2( 0.0, 2.0 ) * uTexSizeInv; // WebGL port note: Changed sign if (!(texCoord.y < end && e.r > 0.8281 && e.g == 0.0)) break; } texCoord.y += 0.25 * uTexSizeInv.y; // WebGL port note: Changed sign texCoord.y += uTexSizeInv.y; // WebGL port note: Changed sign texCoord.y += 2.0 * uTexSizeInv.y; // WebGL port note: Changed sign texCoord.y -= uTexSizeInv.y * SMAASearchLength(searchTex, e.gr, 0.5, 0.5); // WebGL port note: Changed sign return texCoord.y; } vec2 SMAAArea(sampler2D areaTex, vec2 dist, float e1, float e2, float offset) { // Rounding prevents precision errors of bilinear filtering: vec2 texCoord = float(SMAA_AREATEX_MAX_DISTANCE) * round(4.0 * vec2(e1, e2)) + dist; // We do a scale and bias for mapping to texel space: texCoord = SMAA_AREATEX_PIXEL_SIZE * texCoord + (0.5 * SMAA_AREATEX_PIXEL_SIZE); // Move to proper place, according to the subpixel offset: texCoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; return texture2D(areaTex, texCoord, 0.0).rg; } vec4 SMAABlendingWeightCalculationPS(vec2 texCoord, vec2 pixCoord, vec4 offset[3], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices) { vec4 weights = vec4(0.0, 0.0, 0.0, 0.0); vec2 e = texture2D(edgesTex, texCoord).rg; if (e.g > 0.0) { // Edge at north vec2 d; // Find the distance to the left: vec2 coords; coords.x = SMAASearchXLeft(edgesTex, searchTex, offset[0].xy, offset[2].x ); coords.y = offset[1].y; // offset[1].y = texCoord.y - 0.25 * uTexSizeInv.y (@CROSSING_OFFSET) d.x = coords.x; // Now fetch the left crossing edges, two at a time using bilinear // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to // discern what value each edge has: float e1 = texture2D(edgesTex, coords, 0.0).r; // Find the distance to the right: coords.x = SMAASearchXRight(edgesTex, searchTex, offset[0].zw, offset[2].y); d.y = coords.x; // We want the distances to be in pixel units (doing this here allow to // better interleave arithmetic and memory accesses): d = d / uTexSizeInv.x - pixCoord.x; // SMAAArea below needs a sqrt, as the areas texture is compressed // quadratically: vec2 sqrt_d = sqrt(abs(d)); // Fetch the right crossing edges: coords.y -= 1.0 * uTexSizeInv.y; // WebGL port note: Added float e2 = SMAASampleLevelZeroOffset(edgesTex, coords, ivec2(1, 0)).r; // Ok, we know how this pattern looks like, now it is time for getting // the actual area: weights.rg = SMAAArea(areaTex, sqrt_d, e1, e2, float(subsampleIndices.y)); } if (e.r > 0.0) { // Edge at west vec2 d; // Find the distance to the top: vec2 coords; coords.y = SMAASearchYUp(edgesTex, searchTex, offset[1].xy, offset[2].z ); coords.x = offset[0].x; // offset[1].x = texCoord.x - 0.25 * uTexSizeInv.x; d.x = coords.y; // Fetch the top crossing edges: float e1 = texture2D(edgesTex, coords, 0.0).g; // Find the distance to the bottom: coords.y = SMAASearchYDown(edgesTex, searchTex, offset[1].zw, offset[2].w); d.y = coords.y; // We want the distances to be in pixel units: d = d / uTexSizeInv.y - pixCoord.y; // SMAAArea below needs a sqrt, as the areas texture is compressed // quadratically: vec2 sqrt_d = sqrt(abs(d)); // Fetch the bottom crossing edges: coords.y -= 1.0 * uTexSizeInv.y; // WebGL port note: Added float e2 = SMAASampleLevelZeroOffset(edgesTex, coords, ivec2(0, 1)).g; // Get the area for this direction: weights.ba = SMAAArea(areaTex, sqrt_d, e1, e2, float(subsampleIndices.x)); } return weights; } void main() { gl_FragColor = SMAABlendingWeightCalculationPS(vUv, vPixCoord, vOffset, tEdges, tArea, tSearch, ivec4(0.0)); } `;