UNPKG

molstar

Version:

A comprehensive macromolecular library.

8 lines (7 loc) 3.64 kB
/** * Copyright (c) 2022-2024 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Ludovic Autin <ludovic.autin@gmail.com> * @author Alexander Rose <alexander.rose@weirdbyte.de> */ export declare const shadows_frag = "\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\n#include common\n\nuniform sampler2D tDepth;\nuniform vec2 uTexSize;\nuniform vec4 uBounds;\n\nuniform float uNear;\nuniform float uFar;\n\n#if dLightCount != 0\n uniform vec3 uLightDirection[dLightCount];\n uniform vec3 uLightColor[dLightCount];\n#endif\nuniform vec3 uAmbientColor;\n\nuniform mat4 uProjection;\nuniform mat4 uInvProjection;\n\nuniform float uMaxDistance;\nuniform float uTolerance;\n\nbool isBackground(const in float depth) {\n return depth == 1.0;\n}\n\nbool outsideBounds(const in vec2 p) {\n return p.x < uBounds.x || p.y < uBounds.y || p.x > uBounds.z || p.y > uBounds.w;\n}\n\nfloat getViewZ(const in float depth) {\n #if dOrthographic == 1\n return orthographicDepthToViewZ(depth, uNear, uFar);\n #else\n return perspectiveDepthToViewZ(depth, uNear, uFar);\n #endif\n}\n\nfloat getDepth(const in vec2 coords) {\n #ifdef depthTextureSupport\n return texture2D(tDepth, coords).r;\n #else\n return unpackRGBAToDepth(texture2D(tDepth, coords));\n #endif\n}\n\nfloat screenFade(const in vec2 coords) {\n vec2 c = (coords - uBounds.xy) / (uBounds.zw - uBounds.xy);\n vec2 fade = max(12.0 * abs(c - 0.5) - 5.0, vec2(0.0));\n return saturate(1.0 - dot(fade, fade));\n}\n\n// based on https://panoskarabelas.com/posts/screen_space_shadows/\nvec3 screenSpaceShadow(const in vec3 position, const in vec3 lightDirection, const in vec3 lightColor, const in float stepLength) {\n // Ray position and direction (in view-space)\n vec3 rayPos = position;\n vec3 rayDir = -lightDirection;\n\n // Compute ray step\n vec3 rayStep = rayDir * stepLength;\n\n // Ray march towards the light\n vec4 rayCoords = vec4(0.0);\n for (int i = 0; i < dSteps; ++i) {\n // Step the ray\n rayPos += rayStep;\n\n rayCoords = uProjection * vec4(rayPos, 1.0);\n rayCoords.xyz = (rayCoords.xyz / rayCoords.w) * 0.5 + 0.5;\n\n if (outsideBounds(rayCoords.xy)) {\n return lightColor;\n }\n\n // Compute the difference between the ray's and the camera's depth\n float depth = getDepth(rayCoords.xy);\n float viewZ = getViewZ(depth);\n float zDelta = rayPos.z - viewZ;\n\n if (zDelta < uTolerance) {\n // Fade out as we approach the edges of the screen\n return mix(vec3(0.0), lightColor, 1.0 - screenFade(rayCoords.xy));\n }\n }\n\n return lightColor;\n}\n\nvoid main(void) {\n vec2 invTexSize = 1.0 / uTexSize;\n vec2 selfCoords = gl_FragCoord.xy * invTexSize;\n\n float selfDepth = getDepth(selfCoords);\n\n if (isBackground(selfDepth)) {\n gl_FragColor = vec4(0.0);\n return;\n }\n\n vec3 selfViewPos = screenSpaceToViewSpace(vec3(selfCoords, selfDepth), uInvProjection);\n float stepLength = uMaxDistance / float(dSteps);\n\n float l = length(uAmbientColor);\n float a = l;\n #if dLightCount != 0\n vec3 s;\n #pragma unroll_loop_start\n for (int i = 0; i < dLightCount; ++i) {\n s = screenSpaceShadow(selfViewPos, uLightDirection[i], uLightColor[i], stepLength);\n l += length(s);\n a += length(uLightColor[i]);\n }\n #pragma unroll_loop_end\n #endif\n\n gl_FragColor = vec4(l / a);\n}\n";