UNPKG

molstar

Version:

A comprehensive macromolecular library.

123 lines (103 loc) 3.96 kB
"use strict"; /** * Copyright (c) 2024 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Ludovic Autin <autin@scripps.edu> * @author Alexander Rose <alexander.rose@weirdbyte.de> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.dof_frag = void 0; exports.dof_frag = ` precision highp float; precision highp int; precision highp sampler2D; #include common uniform sampler2D tColor; uniform sampler2D tDepthOpaque; uniform sampler2D tDepthTransparent; uniform vec2 uTexSize; uniform vec4 uBounds; uniform float uBlurSpread; uniform float uInFocus; uniform float uPPM; uniform float uNear; // Near plane uniform float uFar; // Far plane uniform mat4 uInvProjection; // Inverse projection uniform mat4 uProjection; // projection uniform int uMode; // 0-planar, 1-spherical uniform vec3 uCenter; // Center of focus sphere in view space // Function to convert depth value from depth buffer to view space Z float getViewZ(const in float depth) { #if dOrthographic == 1 return orthographicDepthToViewZ(depth, uNear, uFar); #else return perspectiveDepthToViewZ(depth, uNear, uFar); #endif } // Retrieve depth from opaque depth texture float getDepthOpaque(const in vec2 coords) { #ifdef depthTextureSupport return texture2D(tDepthOpaque, coords).r; #else return unpackRGBAToDepth(texture2D(tDepthOpaque, coords)); #endif } // Retrieve depth from transparent depth texture float getDepthTransparent(const in vec2 coords) { return unpackRGBAToDepthWithAlpha(texture2D(tDepthTransparent, coords)).x; } bool isBackground(const in float depth) { return depth == 1.0; } float getDepth(const in vec2 coords) { return min(getDepthOpaque(coords), getDepthTransparent(coords)); } float getCOC(vec2 uv) { float depth = getDepth(uv); float viewDist = getViewZ(depth); vec3 aposition = screenSpaceToViewSpace(vec3(uv.xy, depth), uInvProjection); float focusDist = length(aposition - uCenter); float coc = 0.0; // Circle of Confusion if (uMode == 0) { // planar Depth of field coc = (abs(viewDist) - uInFocus) / uPPM; //focus distance, focus range } else if(uMode == 1) { // spherical Depth of field coc = focusDist / uPPM ; } coc = clamp(coc, -1.0, 1.0); return coc; } // Simple box blur for blurring the image vec3 getBlurredImage(vec2 coords) { vec4 blurColor = vec4(0); vec2 texelSize = vec2(1.0 / uTexSize.x, 1.0 / uTexSize.y); float count = 0.0; for (int x = 0; x < int(dBlurSize); x++) { for (int y = 0; y < int(dBlurSize); y++) { vec2 offset = vec2(float(x) - float(dBlurSize) / 2.0, float(y) - float(dBlurSize) / 2.0); vec2 uvPixel = coords.xy + offset * texelSize * uBlurSpread; float coc = getCOC(uvPixel); coc = smoothstep(0.0, 1.0, abs(coc)); // mix blurColor with new color with weight coc blurColor.rgb = blurColor.rgb + texture2D(tColor, uvPixel).xyz * coc; count+=coc; } } blurColor = blurColor / count; return blurColor.rgb; } // simplification from https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/ void main() { vec2 uv = gl_FragCoord.xy / uTexSize; vec4 color = texture2D(tColor, uv); float depth = getDepth(uv); float viewDist = getViewZ(depth); vec3 aposition = screenSpaceToViewSpace(vec3(uv.xy, depth), uInvProjection); float focusDist = length(aposition - uCenter); vec3 blurColor = getBlurredImage(uv); float coc = getCOC(uv); // Circle of Confusion // for debugging the coc // color.rgb = (coc < 0.0) ? (1.0 - abs(coc)) * vec3(1.0,0.0,0.0) : vec3(0.0, 1.0 - coc, 0.0) ;//mix(color.rgb, blurColor.rgb, abs(coc)); color.rgb = mix(color.rgb, blurColor, smoothstep(0.0, 1.0, abs(coc))); // Smooth blending based on CoC gl_FragColor = color; } `;