diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 8f231b245f7260f44b7e127da81a0c73105e02d9..3a9bcfc99deafbe50c2767e94012db7fd1292e89 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -34,6 +34,7 @@ import { getPostprocessingRenderable, PostprocessingParams, setPostprocessingPro import { JitterVectors, getComposeRenderable } from './helper/multi-sample'; import { GLRenderingContext } from 'mol-gl/webgl/compat'; import { PixelData } from 'mol-util/image'; +import { readTexture } from 'mol-gl/compute/util'; export const Canvas3DParams = { // TODO: FPS cap? @@ -90,6 +91,8 @@ interface Canvas3D { dispose: () => void } +const requestAnimationFrame = typeof window !== 'undefined' ? window.requestAnimationFrame : (f: (time: number) => void) => setImmediate(()=>f(Date.now())) + namespace Canvas3D { export interface HighlightEvent { current: Representation.Loci, prev: Representation.Loci, modifiers?: ModifiersKeys } export interface ClickEvent { current: Representation.Loci, buttons: ButtonsType, modifiers: ModifiersKeys } @@ -134,12 +137,15 @@ namespace Canvas3D { const renderer = Renderer.create(webgl, camera, p.renderer) const drawTarget = createRenderTarget(webgl, width, height) - const depthTexture = createTexture(webgl, 'image-depth', 'depth', 'ushort', 'nearest') - depthTexture.define(width, height) - depthTexture.attachFramebuffer(drawTarget.framebuffer, 'depth') + const depthTarget = webgl.extensions.depthTexture ? null : createRenderTarget(webgl, width, height) + const depthTexture = depthTarget ? depthTarget.texture : createTexture(webgl, 'image-depth', 'depth', 'ushort', 'nearest') + if (!depthTarget) { + depthTexture.define(width, height) + depthTexture.attachFramebuffer(drawTarget.framebuffer, 'depth') + } const postprocessingTarget = createRenderTarget(webgl, width, height) - const postprocessing = getPostprocessingRenderable(webgl, drawTarget.texture, depthTexture, p.postprocessing) + const postprocessing = getPostprocessingRenderable(webgl, drawTarget.texture, depthTexture, !!depthTarget, p.postprocessing) const composeTarget = createRenderTarget(webgl, width, height) const holdTarget = createRenderTarget(webgl, width, height) @@ -226,12 +232,21 @@ namespace Canvas3D { } } - function renderDraw() { + function renderDraw(postprocessingEnabled: boolean) { renderer.setViewport(0, 0, width, height) - renderer.render(scene, 'draw') + renderer.render(scene, 'draw', true) if (debugHelper.isEnabled) { debugHelper.syncVisibility() - renderer.render(debugHelper.scene, 'draw') + renderer.render(debugHelper.scene, 'draw', false) + } + + if (postprocessingEnabled && depthTarget) { + depthTarget.bind() + renderer.render(scene, 'depth', true) + if (debugHelper.isEnabled) { + debugHelper.syncVisibility() + renderer.render(debugHelper.scene, 'depth', false) + } } } @@ -262,7 +277,7 @@ namespace Canvas3D { if (i === 0) { drawTarget.bind() - renderDraw() + renderDraw(postprocessingEnabled) if (postprocessingEnabled) { postprocessingTarget.bind() renderPostprocessing() @@ -295,7 +310,7 @@ namespace Canvas3D { // render scene and optionally postprocess drawTarget.bind() - renderDraw() + renderDraw(postprocessingEnabled) if (postprocessingEnabled) { postprocessingTarget.bind() renderPostprocessing() @@ -378,7 +393,7 @@ namespace Canvas3D { // render scene and optionally postprocess drawTarget.bind() - renderDraw() + renderDraw(postprocessingEnabled) if (postprocessingEnabled) { postprocessingTarget.bind() renderPostprocessing() @@ -441,11 +456,11 @@ namespace Canvas3D { case 'pick': renderer.setViewport(0, 0, pickWidth, pickHeight); objectPickTarget.bind(); - renderer.render(scene, 'pickObject'); + renderer.render(scene, 'pickObject', true); instancePickTarget.bind(); - renderer.render(scene, 'pickInstance'); + renderer.render(scene, 'pickInstance', true); groupPickTarget.bind(); - renderer.render(scene, 'pickGroup'); + renderer.render(scene, 'pickGroup', true); break; case 'draw': renderer.setViewport(0, 0, width, height); @@ -458,7 +473,7 @@ namespace Canvas3D { } else { if (postprocessingEnabled) drawTarget.bind() else webgl.unbindFramebuffer() - renderDraw() + renderDraw(postprocessingEnabled) if (postprocessingEnabled) { webgl.unbindFramebuffer() renderPostprocessing() @@ -496,7 +511,7 @@ namespace Canvas3D { camera.transition.tick(currentTime); draw(false); if (!camera.transition.inTransition) interactionHelper.tick(currentTime); - window.requestAnimationFrame(animate) + requestAnimationFrame(animate) } function pick() { @@ -627,6 +642,12 @@ namespace Canvas3D { case 'pickObject': return objectPickTarget.getPixelData() case 'pickInstance': return instancePickTarget.getPixelData() case 'pickGroup': return groupPickTarget.getPixelData() + case 'depth': + if (depthTarget) { + return depthTarget.getPixelData() + } else { + return readTexture(webgl, depthTexture) as PixelData + } } }, didDraw, @@ -699,7 +720,11 @@ namespace Canvas3D { postprocessingTarget.setSize(width, height) composeTarget.setSize(width, height) holdTarget.setSize(width, height) - depthTexture.define(width, height) + if (depthTarget) { + depthTarget.setSize(width, height) + } else { + depthTexture.define(width, height) + } ValueCell.update(postprocessing.values.uTexSize, Vec2.set(postprocessing.values.uTexSize.ref.value, width, height)) ValueCell.update(compose.values.uTexSize, Vec2.set(compose.values.uTexSize.ref.value, width, height)) diff --git a/src/mol-canvas3d/helper/postprocessing.ts b/src/mol-canvas3d/helper/postprocessing.ts index f7252a72556f4c7e4865e93807bae935ca5e908c..3f56ebad935764d9b656f3447cff702d0dcc5163 100644 --- a/src/mol-canvas3d/helper/postprocessing.ts +++ b/src/mol-canvas3d/helper/postprocessing.ts @@ -29,6 +29,8 @@ const PostprocessingSchema = { dOutlineEnable: DefineSpec('boolean'), uOutlineScale: UniformSpec('f'), uOutlineThreshold: UniformSpec('f'), + + dPackedDepth: DefineSpec('boolean'), } export const PostprocessingParams = { @@ -45,8 +47,8 @@ export type PostprocessingProps = PD.Values<typeof PostprocessingParams> type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>> -export function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTexture: Texture, props: Partial<PostprocessingProps>): PostprocessingRenderable { - const p = { ...PD.getDefaultValues(PostprocessingParams), props } +export function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTexture: Texture, packedDepth: boolean, props: Partial<PostprocessingProps>): PostprocessingRenderable { + const p = { ...PD.getDefaultValues(PostprocessingParams), ...props } const values: Values<typeof PostprocessingSchema> = { ...QuadValues, tColor: ValueCell.create(colorTexture), @@ -61,6 +63,8 @@ export function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Tex dOutlineEnable: ValueCell.create(p.outlineEnable), uOutlineScale: ValueCell.create(p.outlineScale * ctx.pixelRatio), uOutlineThreshold: ValueCell.create(p.outlineThreshold), + + dPackedDepth: ValueCell.create(packedDepth), } const schema = { ...PostprocessingSchema } diff --git a/src/mol-gl/compute/util.ts b/src/mol-gl/compute/util.ts index 0508154cf2a6e5900bcdcd5202d372d5b92ca5ef..bfd56369047a6515ebec80082870f3fb2d65d9e5 100644 --- a/src/mol-gl/compute/util.ts +++ b/src/mol-gl/compute/util.ts @@ -33,7 +33,7 @@ export const QuadValues: Values<typeof QuadSchema> = { // -function getArrayForTexture(gl:GLRenderingContext, texture: Texture, size: number) { +function getArrayForTexture(gl: GLRenderingContext, texture: Texture, size: number) { switch (texture.type) { case gl.UNSIGNED_BYTE: return new Uint8Array(size) case gl.FLOAT: return new Float32Array(size) diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 0944f523202eea629b8703c6bcf29df0fe17cb40..d4e6d30e67c267408b13af04cd2b5b4006515537 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -38,7 +38,7 @@ interface Renderer { readonly props: Readonly<RendererProps> clear: () => void - render: (scene: Scene, variant: GraphicsRenderVariant) => void + render: (scene: Scene, variant: GraphicsRenderVariant, clear: boolean) => void setProps: (props: Partial<RendererProps>) => void setViewport: (x: number, y: number, width: number, height: number) => void dispose: () => void @@ -153,7 +153,7 @@ namespace Renderer { } } - const render = (scene: Scene, variant: GraphicsRenderVariant) => { + const render = (scene: Scene, variant: GraphicsRenderVariant, clear: boolean) => { ValueCell.update(globalUniforms.uModel, scene.view) ValueCell.update(globalUniforms.uView, camera.view) ValueCell.update(globalUniforms.uInvView, Mat4.invert(invView, camera.view)) @@ -182,8 +182,15 @@ namespace Renderer { state.depthMask(true) state.colorMask(true, true, true, true) state.enable(gl.DEPTH_TEST) - state.clearColor(bgColor[0], bgColor[1], bgColor[2], 1.0) - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + + if (clear) { + if (variant === 'draw') { + state.clearColor(bgColor[0], bgColor[1], bgColor[2], 1.0) + } else { + state.clearColor(1, 1, 1, 1) + } + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + } if (variant === 'draw') { for (let i = 0, il = renderables.length; i < il; ++i) { @@ -198,8 +205,7 @@ namespace Renderer { state.depthMask(r.values.uAlpha.ref.value === 1.0) if (!r.state.opaque) renderObject(r, variant) } - } else { - // picking + } else { // picking & depth for (let i = 0, il = renderables.length; i < il; ++i) { renderObject(renderables[i], variant) } @@ -211,6 +217,7 @@ namespace Renderer { return { clear: () => { state.depthMask(true) + state.colorMask(true, true, true, true) state.clearColor(bgColor[0], bgColor[1], bgColor[2], 1.0) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) }, diff --git a/src/mol-gl/shader/chunks/assign-material-color.glsl.ts b/src/mol-gl/shader/chunks/assign-material-color.glsl.ts index cc6f553f040e498dc96c5acfb1d0eb0e4386a269..b7157328a4cb89822a825bb7bb39c6179dfab122 100644 --- a/src/mol-gl/shader/chunks/assign-material-color.glsl.ts +++ b/src/mol-gl/shader/chunks/assign-material-color.glsl.ts @@ -5,6 +5,12 @@ export default ` vec4 material = vec4(vColor.rgb, uAlpha); #elif defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking) vec4 material = uPickable == 1 ? vColor : vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id +#elif defined(dColorType_depth) + #ifdef enabledFragDepth + vec4 material = packDepthToRGBA(gl_FragDepthEXT); + #else + vec4 material = packDepthToRGBA(gl_FragCoord.z); + #endif #endif // mix material with overpaint diff --git a/src/mol-gl/shader/chunks/common.glsl.ts b/src/mol-gl/shader/chunks/common.glsl.ts index 45c85660c2ff9157ba2f7c40d0cbd7b0db705818..20dc1440709d2547f8ccd522635aba51b4b3963b 100644 --- a/src/mol-gl/shader/chunks/common.glsl.ts +++ b/src/mol-gl/shader/chunks/common.glsl.ts @@ -29,6 +29,21 @@ float decodeFloatRGB(const in vec3 rgb) { return (rgb.r * 256.0 * 256.0 * 255.0 + rgb.g * 256.0 * 255.0 + rgb.b * 255.0) - 1.0; } +const float PackUpscale = 256.0 / 255.0; // fraction -> 0..1 (including 1) +const float UnpackDownscale = 255.0 / 256.0; // 0..1 -> fraction (excluding 1) +const vec3 PackFactors = vec3(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0); +const vec4 UnpackFactors = UnpackDownscale / vec4(PackFactors, 1.0); +const float ShiftRight8 = 1.0 / 256.0; + +vec4 packDepthToRGBA(const in float v) { + vec4 r = vec4(fract(v * PackFactors), v); + r.yzw -= r.xyz * ShiftRight8; // tidy overflow + return r * PackUpscale; +} +float unpackRGBAToDepth(const in vec4 v) { + return dot(v, UnpackFactors); +} + #if __VERSION__ != 300 // transpose diff --git a/src/mol-gl/shader/direct-volume.frag.ts b/src/mol-gl/shader/direct-volume.frag.ts index f8fb11865f9b0d17f08d9d21e4cd9b84a1782e40..a96070e5e2946a53615a3f421b9a939f986addbd 100644 --- a/src/mol-gl/shader/direct-volume.frag.ts +++ b/src/mol-gl/shader/direct-volume.frag.ts @@ -128,6 +128,8 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) { #elif defined(dColorType_groupPicking) float group = floor(decodeFloatRGB(textureGroup(isoPos).rgb) + 0.5); return vec4(encodeFloatRGB(group), 1.0); + #elif defined(dColorType_depth) + return packDepthToRGBA(gl_FragCoord.z); // TODO calculate isosurface depth #else // compute gradient by central differences gradient.x = textureVal(isoPos - dx).a - textureVal(isoPos + dx).a; diff --git a/src/mol-gl/shader/lines.frag.ts b/src/mol-gl/shader/lines.frag.ts index 861bacf50a5d5299940866545f1956e389d34058..0e7981060441eb1d6faa7f0b7924f49d93fe94df 100644 --- a/src/mol-gl/shader/lines.frag.ts +++ b/src/mol-gl/shader/lines.frag.ts @@ -19,6 +19,8 @@ void main(){ if (uAlpha < uPickingAlphaThreshold) discard; // ignore so the element below can be picked gl_FragColor = material; + #elif defined(dColorType_depth) + gl_FragColor = material; #else gl_FragColor = material; diff --git a/src/mol-gl/shader/mesh.frag.ts b/src/mol-gl/shader/mesh.frag.ts index 10f09309bb827dda97aa91e4fba9410fa03ea752..9289ea66c0b65e683e8dc52b527766cdbc28f4ec 100644 --- a/src/mol-gl/shader/mesh.frag.ts +++ b/src/mol-gl/shader/mesh.frag.ts @@ -21,6 +21,8 @@ void main() { if (uAlpha < uPickingAlphaThreshold) discard; // ignore so the element below can be picked gl_FragColor = material; + #elif defined(dColorType_depth) + gl_FragColor = material; #else #include assign_normal #include apply_light_color diff --git a/src/mol-gl/shader/points.frag.ts b/src/mol-gl/shader/points.frag.ts index 0d5b6f67599b7fef45b5ec52f7c458b18e484aff..b858a1c2589a4957f84b0ff22eca7e37267903a6 100644 --- a/src/mol-gl/shader/points.frag.ts +++ b/src/mol-gl/shader/points.frag.ts @@ -26,6 +26,8 @@ void main(){ if (uAlpha < uPickingAlphaThreshold) discard; // ignore so the element below can be picked gl_FragColor = material; + #elif defined(dColorType_depth) + gl_FragColor = material; #else gl_FragColor = material; diff --git a/src/mol-gl/shader/postprocessing.frag.ts b/src/mol-gl/shader/postprocessing.frag.ts index 31d0ca5a58bff5ace45ecaf1b551bcc04be5248e..29af1fc1d5604cc982aafe0b1a5693813ab1c425 100644 --- a/src/mol-gl/shader/postprocessing.frag.ts +++ b/src/mol-gl/shader/postprocessing.frag.ts @@ -15,6 +15,8 @@ uniform float uOutlineThreshold; const float noiseAmount = 0.0002; +#include common + float noise(vec2 coords) { float a = 12.9898; float b = 78.233; @@ -25,6 +27,14 @@ float noise(vec2 coords) { return fract(sin(sn) * c); } +float getDepth(in vec2 coords) { + #ifdef dPackedDepth + return unpackRGBAToDepth(texture2D(tDepth, coords)); + #else + return texture2D(tDepth, coords).r; + #endif +} + float calcSSAO(in vec2 coords, in float depth) { float occlusionFactor = 0.0; @@ -33,7 +43,7 @@ float calcSSAO(in vec2 coords, in float depth) { vec2 coordsDelta = coords + uOcclusionRadius / float(dOcclusionKernelSize) * vec2(float(i) / uTexSize.x, float(j) / uTexSize.y); coordsDelta += noiseAmount * (noise(coordsDelta) - 0.5) / uTexSize; coordsDelta = clamp(coordsDelta, 0.5 / uTexSize, 1.0 - 1.0 / uTexSize); - if (texture2D(tDepth, coordsDelta).r < depth) occlusionFactor += 1.0; + if (getDepth(coordsDelta) < depth) occlusionFactor += 1.0; } } @@ -50,10 +60,10 @@ float calcEdgeDepth(in vec2 coords) { vec2 bottomRightUV = coords + vec2(invTexSize.x * halfScaleCeil, -invTexSize.y * halfScaleFloor); vec2 topLeftUV = coords + vec2(-invTexSize.x * halfScaleFloor, invTexSize.y * halfScaleCeil); - float depth0 = texture2D(tDepth, bottomLeftUV).r; - float depth1 = texture2D(tDepth, topRightUV).r; - float depth2 = texture2D(tDepth, bottomRightUV).r; - float depth3 = texture2D(tDepth, topLeftUV).r; + float depth0 = getDepth(bottomLeftUV); + float depth1 = getDepth(topRightUV); + float depth2 = getDepth(bottomRightUV); + float depth3 = getDepth(topLeftUV); float depthFiniteDifference0 = depth1 - depth0; float depthFiniteDifference1 = depth3 - depth2; @@ -66,7 +76,7 @@ void main(void) { vec4 color = texture2D(tColor, coords); #ifdef dOcclusionEnable - float depth = texture2D(tDepth, coords).r; + float depth = getDepth(coords); if (depth != 1.0) { float occlusionFactor = calcSSAO(coords, depth); color = mix(color, vec4(0.0, 0.0, 0.0, 1.0), uOcclusionBias * occlusionFactor); diff --git a/src/mol-gl/shader/spheres.frag.ts b/src/mol-gl/shader/spheres.frag.ts index 4a460fbc18bdd19f8881ada589021c8e4c6d05fe..e40b9f15e4f6decffe7bf381c574149d23b66990 100644 --- a/src/mol-gl/shader/spheres.frag.ts +++ b/src/mol-gl/shader/spheres.frag.ts @@ -125,6 +125,8 @@ void main(void){ if (uAlpha < uPickingAlphaThreshold) discard; // ignore so the element below can be picked gl_FragColor = material; + #elif defined(dColorType_depth) + gl_FragColor = material; #else vec3 normal = cameraNormal; vec3 vViewPosition = -cameraPos; diff --git a/src/mol-gl/shader/text.frag.ts b/src/mol-gl/shader/text.frag.ts index c6f534df2870820c50e2f81a7a92973e7521c18a..efee9bfdaeba445dcd713078dc8513037ac9e54b 100644 --- a/src/mol-gl/shader/text.frag.ts +++ b/src/mol-gl/shader/text.frag.ts @@ -59,6 +59,8 @@ void main(){ #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking) if (uAlpha < uPickingAlphaThreshold) discard; // ignore so the element below can be picked + #elif defined(dColorType_depth) + gl_FragColor = material; #else #include apply_marker_color #include apply_fog diff --git a/src/mol-gl/webgl/extensions.ts b/src/mol-gl/webgl/extensions.ts index dbc00402875c50d25ad2157828aadc5cd81f994d..fdecddc9c6e5cf97b2caf55f834b5a3e8d0a305b 100644 --- a/src/mol-gl/webgl/extensions.ts +++ b/src/mol-gl/webgl/extensions.ts @@ -8,13 +8,13 @@ import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivative export type WebGLExtensions = { instancedArrays: COMPAT_instanced_arrays - standardDerivatives: COMPAT_standard_derivatives - blendMinMax: COMPAT_blend_minmax textureFloat: COMPAT_texture_float - textureFloatLinear: COMPAT_texture_float_linear elementIndexUint: COMPAT_element_index_uint - depthTexture: COMPAT_depth_texture + standardDerivatives: COMPAT_standard_derivatives | null + textureFloatLinear: COMPAT_texture_float_linear | null + depthTexture: COMPAT_depth_texture | null + blendMinMax: COMPAT_blend_minmax | null vertexArrayObject: COMPAT_vertex_array_object | null fragDepth: COMPAT_frag_depth | null colorBufferFloat: COMPAT_color_buffer_float | null @@ -27,31 +27,35 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions { if (instancedArrays === null) { throw new Error('Could not find support for "instanced_arrays"') } - const standardDerivatives = getStandardDerivatives(gl) - if (standardDerivatives === null) { - throw new Error('Could not find support for "standard_derivatives"') - } - const blendMinMax = getBlendMinMax(gl) - if (blendMinMax === null) { - throw new Error('Could not find support for "blend_minmax"') - } const textureFloat = getTextureFloat(gl) if (textureFloat === null) { throw new Error('Could not find support for "texture_float"') } - const textureFloatLinear = getTextureFloatLinear(gl) - if (textureFloatLinear === null) { - throw new Error('Could not find support for "texture_float_linear"') - } const elementIndexUint = getElementIndexUint(gl) if (elementIndexUint === null) { throw new Error('Could not find support for "element_index_uint"') } + + const standardDerivatives = getStandardDerivatives(gl) + if (standardDerivatives === null) { + // TODO handle non-support downstream (e.g. no flat shading) + // throw new Error('Could not find support for "standard_derivatives"') + console.log('Could not find support for "standard_derivatives"') + } + const textureFloatLinear = getTextureFloatLinear(gl) + if (textureFloatLinear === null) { + // TODO handle non-support downstream (no gpu gaussian calc, no gpu mc???) + // throw new Error('Could not find support for "texture_float_linear"') + console.log('Could not find support for "texture_float_linear"') + } const depthTexture = getDepthTexture(gl) if (depthTexture === null) { - throw new Error('Could not find support for "depth_texture"') + console.log('Could not find support for "depth_texture"') + } + const blendMinMax = getBlendMinMax(gl) + if (blendMinMax === null) { + console.log('Could not find support for "blend_minmax"') } - const vertexArrayObject = getVertexArrayObject(gl) if (vertexArrayObject === null) { console.log('Could not find support for "vertex_array_object"') @@ -76,12 +80,12 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions { return { instancedArrays, standardDerivatives, - blendMinMax, textureFloat, textureFloatLinear, elementIndexUint, depthTexture, + blendMinMax, vertexArrayObject, fragDepth, colorBufferFloat, diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts index b516fb8099172ed50c21646934ab016174f4a947..5707df15b05af8135b806dbbcd29605e086da206 100644 --- a/src/mol-gl/webgl/render-item.ts +++ b/src/mol-gl/webgl/render-item.ts @@ -51,7 +51,8 @@ const GraphicsRenderVariantDefines = { 'draw': {}, 'pickObject': { dColorType: ValueCell.create('objectPicking') }, 'pickInstance': { dColorType: ValueCell.create('instancePicking') }, - 'pickGroup': { dColorType: ValueCell.create('groupPicking') } + 'pickGroup': { dColorType: ValueCell.create('groupPicking') }, + 'depth': { dColorType: ValueCell.create('depth') } } export type GraphicsRenderVariant = keyof typeof GraphicsRenderVariantDefines diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts index ef8b625ba34771aac264a0db06e5c194f79e3f11..1915926b973fd5f4240886582ce18d18bdbb10fd 100644 --- a/src/mol-math/geometry/gaussian-density/gpu.ts +++ b/src/mol-math/geometry/gaussian-density/gpu.ts @@ -307,6 +307,9 @@ function setupMinDistanceRendering(webgl: WebGLContext, renderable: ComputeRende state.colorMask(false, false, false, true) state.blendFunc(gl.ONE, gl.ONE) // the shader writes 1 - dist so we set blending to MAX + if (!webgl.extensions.blendMinMax) { + throw new Error('GPU gaussian surface calculation requires EXT_blend_minmax') + } state.blendEquation(webgl.extensions.blendMinMax.MAX) }