diff --git a/src/apps/viewer/index.html b/src/apps/viewer/index.html index c05ed16bc5b439ae7ad931c55acc3366afb10541..9fe81219e16721be9b77f5bbba68b30dbf0bb317 100644 --- a/src/apps/viewer/index.html +++ b/src/apps/viewer/index.html @@ -50,14 +50,12 @@ var disableAntialiasing = getParam('disable-antialiasing', '[^&]+').trim() === '1'; var pixelScale = parseFloat(getParam('pixel-scale', '[^&]+').trim() || '1'); - var enableWboit = getParam('enable-wboit', '[^&]+').trim() === '1'; var hideControls = getParam('hide-controls', '[^&]+').trim() === '1'; var pdbProvider = getParam('pdb-provider', '[^&]+').trim().toLowerCase(); var emdbProvider = getParam('emdb-provider', '[^&]+').trim().toLowerCase(); var viewer = new molstar.Viewer('app', { disableAntialiasing: disableAntialiasing, pixelScale: pixelScale, - enableWboit: enableWboit, layoutShowControls: !hideControls, viewportShowExpand: false, pdbProvider: pdbProvider || 'pdbe', diff --git a/src/apps/viewer/index.ts b/src/apps/viewer/index.ts index 99448e793c6fbb91dbed01a8c1a874bed3d97013..d62b7440e0a40226ca667962bc8cd2e0c0278382 100644 --- a/src/apps/viewer/index.ts +++ b/src/apps/viewer/index.ts @@ -68,7 +68,6 @@ const DefaultViewerOptions = { layoutShowLeftPanel: true, disableAntialiasing: false, pixelScale: 1, - enableWboit: false, viewportShowExpand: PluginConfig.Viewport.ShowExpand.defaultValue, viewportShowControls: PluginConfig.Viewport.ShowControls.defaultValue, @@ -118,7 +117,6 @@ export class Viewer { config: [ [PluginConfig.General.DisableAntialiasing, o.disableAntialiasing], [PluginConfig.General.PixelScale, o.pixelScale], - [PluginConfig.General.EnableWboit, o.enableWboit], [PluginConfig.Viewport.ShowExpand, o.viewportShowExpand], [PluginConfig.Viewport.ShowControls, o.viewportShowControls], [PluginConfig.Viewport.ShowSettings, o.viewportShowSettings], diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 5322f1bf133722c7802b474166e7fcca28dff341..412b2b8aac9c2064c6d643306193ad17508b0d4b 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -149,7 +149,7 @@ namespace Canvas3D { export interface DragEvent { current: Representation.Loci, buttons: ButtonsType, button: ButtonsType.Flag, modifiers: ModifiersKeys, pageStart: Vec2, pageEnd: Vec2 } export interface ClickEvent { current: Representation.Loci, buttons: ButtonsType, button: ButtonsType.Flag, modifiers: ModifiersKeys, position?: Vec3 } - export function fromCanvas(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}, attribs: Partial<{ antialias: boolean, pixelScale: number, pickScale: number, enableWboit: boolean }> = {}) { + export function fromCanvas(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}, attribs: Partial<{ antialias: boolean, pixelScale: number, pickScale: number }> = {}) { const gl = getGLContext(canvas, { alpha: true, antialias: attribs.antialias ?? true, @@ -301,7 +301,7 @@ namespace Canvas3D { if (MultiSamplePass.isEnabled(p.multiSample)) { multiSampleHelper.render(renderer, cam, scene, helper, true, p.transparentBackground, p); } else { - const toDrawingBuffer = !PostprocessingPass.isEnabled(p.postprocessing) && scene.volumes.renderables.length === 0 && !passes.draw.wboitEnabled; + const toDrawingBuffer = !PostprocessingPass.isEnabled(p.postprocessing) && scene.volumes.renderables.length === 0; passes.draw.render(renderer, cam, scene, helper, toDrawingBuffer, p.transparentBackground); if (!toDrawingBuffer) passes.postprocessing.render(cam, true, p.postprocessing); } @@ -667,7 +667,7 @@ namespace Canvas3D { } }, getImagePass: (props: Partial<ImageProps> = {}) => { - return new ImagePass(webgl, renderer, scene, camera, helper, passes.draw.wboitEnabled, props); + return new ImagePass(webgl, renderer, scene, camera, helper, props); }, get props() { diff --git a/src/mol-canvas3d/passes/draw.ts b/src/mol-canvas3d/passes/draw.ts index 861c8500850fc6458c20772adeef9d2137ecb34d..bd04e66ce9835c6450734f62e360415d5fbb4e8b 100644 --- a/src/mol-canvas3d/passes/draw.ts +++ b/src/mol-canvas3d/passes/draw.ts @@ -2,11 +2,10 @@ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> - * @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz> */ import { WebGLContext } from '../../mol-gl/webgl/context'; -import { createNullRenderTarget, RenderTarget } from '../../mol-gl/webgl/render-target'; +import { RenderTarget } from '../../mol-gl/webgl/render-target'; import Renderer from '../../mol-gl/renderer'; import Scene from '../../mol-gl/scene'; import { Texture } from '../../mol-gl/webgl/texture'; @@ -23,7 +22,6 @@ import { Helper } from '../helper/helper'; import quad_vert from '../../mol-gl/shader/quad.vert'; import depthMerge_frag from '../../mol-gl/shader/depth-merge.frag'; import { StereoCamera } from '../camera/stereo'; -import { WboitPass } from './wboit'; const DepthMergeSchema = { ...QuadSchema, @@ -51,8 +49,6 @@ function getDepthMergeRenderable(ctx: WebGLContext, depthTexturePrimitives: Text } export class DrawPass { - private readonly drawTarget: RenderTarget - readonly colorTarget: RenderTarget readonly depthTexture: Texture readonly depthTexturePrimitives: Texture @@ -64,17 +60,9 @@ export class DrawPass { private depthTextureVolumes: Texture private depthMerge: DepthMergeRenderable - private wboit: WboitPass | undefined - - get wboitEnabled() { - return !!this.wboit?.enabled; - } - - constructor(private webgl: WebGLContext, width: number, height: number, enableWboit: boolean) { + constructor(private webgl: WebGLContext, width: number, height: number) { const { extensions, resources } = webgl; - this.drawTarget = createNullRenderTarget(webgl.gl); - this.colorTarget = webgl.createRenderTarget(width, height); this.packedDepth = !extensions.depthTexture; @@ -91,8 +79,6 @@ export class DrawPass { this.depthTextureVolumes.define(width, height); } this.depthMerge = getDepthMergeRenderable(webgl, this.depthTexturePrimitives, this.depthTextureVolumes, this.packedDepth); - - this.wboit = enableWboit ? new WboitPass(webgl, width, height) : undefined; } setSize(width: number, height: number) { @@ -116,60 +102,13 @@ export class DrawPass { } ValueCell.update(this.depthMerge.values.uTexSize, Vec2.set(this.depthMerge.values.uTexSize.ref.value, width, height)); - - if (this.wboit?.enabled) { - this.wboit.setSize(width, height); - } } } - private _depthMerge() { - const { state, gl } = this.webgl; - - this.depthMerge.update(); - this.depthTarget.bind(); - state.disable(gl.BLEND); - state.disable(gl.DEPTH_TEST); - state.disable(gl.CULL_FACE); - state.depthMask(false); - state.clearColor(1, 1, 1, 1); - gl.clear(gl.COLOR_BUFFER_BIT); - this.depthMerge.render(); - } - - private _renderWboit(renderer: Renderer, camera: ICamera, scene: Scene, toDrawingBuffer: boolean) { - if (!this.wboit?.enabled) throw new Error('expected wboit to be enabled'); - - const renderTarget = toDrawingBuffer ? this.drawTarget : this.colorTarget; - renderTarget.bind(); - renderer.clear(true); - - // render opaque primitives - this.depthTexturePrimitives.attachFramebuffer(renderTarget.framebuffer, 'depth'); - renderTarget.bind(); - renderer.renderWboitOpaque(scene.primitives, camera, null); - - // render opaque volumes - this.depthTextureVolumes.attachFramebuffer(renderTarget.framebuffer, 'depth'); - renderTarget.bind(); - renderer.clearDepth(); - renderer.renderWboitOpaque(scene.volumes, camera, this.depthTexturePrimitives); - - // merge depth of opaque primitives and volumes - this._depthMerge(); - - // render transparent primitives and volumes - this.wboit.bind(); - renderer.renderWboitTransparent(scene.primitives, camera, this.depthTexture); - renderer.renderWboitTransparent(scene.volumes, camera, this.depthTexture); - - // evaluate wboit - this.depthTexturePrimitives.attachFramebuffer(renderTarget.framebuffer, 'depth'); - renderTarget.bind(); - this.wboit.render(); - } + _render(renderer: Renderer, camera: ICamera, scene: Scene, helper: Helper, toDrawingBuffer: boolean, transparentBackground: boolean) { + const { x, y, width, height } = camera.viewport; + renderer.setViewport(x, y, width, height); - private _renderBlended(renderer: Renderer, camera: ICamera, scene: Scene, toDrawingBuffer: boolean) { if (toDrawingBuffer) { this.webgl.unbindFramebuffer(); } else { @@ -179,16 +118,13 @@ export class DrawPass { } } - renderer.clear(true); - // TODO: split into opaque and transparent pass to handle opaque volume isosurfaces - renderer.renderBlended(scene.primitives, camera, null); + renderer.render(scene.primitives, camera, 'color', true, transparentBackground, 1, null); // do a depth pass if not rendering to drawing buffer and // extensions.depthTexture is unsupported (i.e. depthTarget is set) if (!toDrawingBuffer && this.depthTargetPrimitives) { this.depthTargetPrimitives.bind(); - renderer.clear(false); - renderer.renderDepth(scene.primitives, camera, null); + renderer.render(scene.primitives, camera, 'depth', true, transparentBackground, 1, null); this.colorTarget.bind(); } @@ -196,53 +132,49 @@ export class DrawPass { if (!toDrawingBuffer) { if (!this.packedDepth) { this.depthTextureVolumes.attachFramebuffer(this.colorTarget.framebuffer, 'depth'); - renderer.clearDepth(); + this.webgl.state.depthMask(true); + this.webgl.gl.viewport(x, y, width, height); + this.webgl.gl.scissor(x, y, width, height); + this.webgl.gl.clear(this.webgl.gl.DEPTH_BUFFER_BIT); } - renderer.renderBlended(scene.volumes, camera, this.depthTexturePrimitives); + renderer.render(scene.volumes, camera, 'color', false, transparentBackground, 1, this.depthTexturePrimitives); // do volume depth pass if extensions.depthTexture is unsupported (i.e. depthTarget is set) if (this.depthTargetVolumes) { this.depthTargetVolumes.bind(); - renderer.clear(false); - renderer.renderDepth(scene.volumes, camera, this.depthTexturePrimitives); + renderer.render(scene.volumes, camera, 'depth', true, transparentBackground, 1, this.depthTexturePrimitives); this.colorTarget.bind(); } } // merge depths from primitive and volume rendering if (!toDrawingBuffer) { - this._depthMerge(); + this.depthMerge.update(); + this.depthTarget.bind(); + // this.webgl.state.disable(this.webgl.gl.SCISSOR_TEST); + this.webgl.state.disable(this.webgl.gl.BLEND); + this.webgl.state.disable(this.webgl.gl.DEPTH_TEST); + this.webgl.state.disable(this.webgl.gl.CULL_FACE); + this.webgl.state.depthMask(false); + this.webgl.state.clearColor(1, 1, 1, 1); + this.webgl.gl.viewport(x, y, width, height); + this.webgl.gl.scissor(x, y, width, height); + this.webgl.gl.clear(this.webgl.gl.COLOR_BUFFER_BIT); + this.depthMerge.render(); this.colorTarget.bind(); } - } - - private _render(renderer: Renderer, camera: ICamera, scene: Scene, helper: Helper, toDrawingBuffer: boolean, transparentBackground: boolean) { - const { x, y, width, height } = camera.viewport; - renderer.setViewport(x, y, width, height); - renderer.setTransparentBackground(transparentBackground); - renderer.setDrawingBufferScale(1); - renderer.update(camera); - - if (this.wboitEnabled) { - this._renderWboit(renderer, camera, scene, toDrawingBuffer); - } else { - this._renderBlended(renderer, camera, scene, toDrawingBuffer); - } if (helper.debug.isEnabled) { helper.debug.syncVisibility(); - renderer.renderBlended(helper.debug.scene, camera, null); + renderer.render(helper.debug.scene, camera, 'color', false, transparentBackground, 1, null); } if (helper.handle.isEnabled) { - renderer.renderBlended(helper.handle.scene, camera, null); + renderer.render(helper.handle.scene, camera, 'color', false, transparentBackground, 1, null); } if (helper.camera.isEnabled) { helper.camera.update(camera); - renderer.update(helper.camera.camera); - renderer.renderBlended(helper.camera.scene, helper.camera.camera, null); + renderer.render(helper.camera.scene, helper.camera.camera, 'color', false, transparentBackground, 1, null); } - - this.webgl.gl.flush(); } render(renderer: Renderer, camera: Camera | StereoCamera, scene: Scene, helper: Helper, toDrawingBuffer: boolean, transparentBackground: boolean) { diff --git a/src/mol-canvas3d/passes/image.ts b/src/mol-canvas3d/passes/image.ts index 740c66949d30cb6d47e2cbe88cbedf8c0f1576a0..36a12f6fce280a913feed2fda7a32eb0d8ede377 100644 --- a/src/mol-canvas3d/passes/image.ts +++ b/src/mol-canvas3d/passes/image.ts @@ -46,10 +46,10 @@ export class ImagePass { get width() { return this._width; } get height() { return this._height; } - constructor(private webgl: WebGLContext, private renderer: Renderer, private scene: Scene, private camera: Camera, helper: Helper, enableWboit: boolean, props: Partial<ImageProps>) { + constructor(private webgl: WebGLContext, private renderer: Renderer, private scene: Scene, private camera: Camera, helper: Helper, props: Partial<ImageProps>) { this.props = { ...PD.getDefaultValues(ImageParams), ...props }; - this.drawPass = new DrawPass(webgl, 128, 128, enableWboit); + this.drawPass = new DrawPass(webgl, 128, 128); this.postprocessingPass = new PostprocessingPass(webgl, this.drawPass); this.multiSamplePass = new MultiSamplePass(webgl, this.drawPass, this.postprocessingPass); this.multiSampleHelper = new MultiSampleHelper(this.multiSamplePass); diff --git a/src/mol-canvas3d/passes/multi-sample.ts b/src/mol-canvas3d/passes/multi-sample.ts index 6db628cd96cc1cec14066676dabc18eea85913d6..12dbadc6a3b450f49aeecab91d5d35c73a374677 100644 --- a/src/mol-canvas3d/passes/multi-sample.ts +++ b/src/mol-canvas3d/passes/multi-sample.ts @@ -69,11 +69,11 @@ export class MultiSamplePass { private compose: ComposeRenderable constructor(private webgl: WebGLContext, private drawPass: DrawPass, private postprocessing: PostprocessingPass) { - const { colorBufferFloat, textureFloat } = webgl.extensions; + const { extensions } = webgl; const width = drawPass.colorTarget.getWidth(); const height = drawPass.colorTarget.getHeight(); this.colorTarget = webgl.createRenderTarget(width, height, false); - this.composeTarget = webgl.createRenderTarget(width, height, false, colorBufferFloat && textureFloat ? 'float32' : 'uint8'); + this.composeTarget = webgl.createRenderTarget(width, height, false, extensions.colorBufferFloat ? 'float32' : 'uint8'); this.holdTarget = webgl.createRenderTarget(width, height, false); this.compose = getComposeRenderable(webgl, drawPass.colorTarget.texture); } @@ -100,14 +100,6 @@ export class MultiSamplePass { } } - private bindOutputTarget(toDrawingBuffer: boolean) { - if (toDrawingBuffer) { - this.webgl.unbindFramebuffer(); - } else { - this.colorTarget.bind(); - } - } - private renderMultiSample(renderer: Renderer, camera: Camera | StereoCamera, scene: Scene, helper: Helper, toDrawingBuffer: boolean, transparentBackground: boolean, props: Props) { const { compose, composeTarget, drawPass, postprocessing, webgl } = this; const { gl, state } = webgl; @@ -167,7 +159,12 @@ export class MultiSamplePass { ValueCell.update(compose.values.tColor, composeTarget.texture); compose.update(); - this.bindOutputTarget(toDrawingBuffer); + if (toDrawingBuffer) { + webgl.unbindFramebuffer(); + } else { + this.colorTarget.bind(); + } + gl.viewport(x, y, width, height); gl.scissor(x, y, width, height); @@ -248,7 +245,12 @@ export class MultiSamplePass { } } - this.bindOutputTarget(toDrawingBuffer); + if (toDrawingBuffer) { + webgl.unbindFramebuffer(); + } else { + this.colorTarget.bind(); + } + gl.viewport(x, y, width, height); gl.scissor(x, y, width, height); diff --git a/src/mol-canvas3d/passes/passes.ts b/src/mol-canvas3d/passes/passes.ts index 8e06be24334680d4d5f97a4d5115355e2e746d1b..24660ab3f49d6f7af26f914a040ac30321b857dd 100644 --- a/src/mol-canvas3d/passes/passes.ts +++ b/src/mol-canvas3d/passes/passes.ts @@ -16,9 +16,9 @@ export class Passes { readonly postprocessing: PostprocessingPass readonly multiSample: MultiSamplePass - constructor(private webgl: WebGLContext, attribs: Partial<{ pickScale: number, enableWboit: boolean }> = {}) { + constructor(private webgl: WebGLContext, attribs: Partial<{ pickScale: number }> = {}) { const { gl } = webgl; - this.draw = new DrawPass(webgl, gl.drawingBufferWidth, gl.drawingBufferHeight, attribs.enableWboit || false); + this.draw = new DrawPass(webgl, gl.drawingBufferWidth, gl.drawingBufferHeight); this.pick = new PickPass(webgl, this.draw, attribs.pickScale || 0.25); this.postprocessing = new PostprocessingPass(webgl, this.draw); this.multiSample = new MultiSamplePass(webgl, this.draw, this.postprocessing); diff --git a/src/mol-canvas3d/passes/pick.ts b/src/mol-canvas3d/passes/pick.ts index 841fc7a1819684c5e351c238b35ecbee57cafdea..348180eae64322f32fd96755a4e9bee70fa347d4 100644 --- a/src/mol-canvas3d/passes/pick.ts +++ b/src/mol-canvas3d/passes/pick.ts @@ -64,16 +64,14 @@ export class PickPass { } private renderVariant(renderer: Renderer, camera: ICamera, scene: Scene, helper: Helper, variant: GraphicsRenderVariant) { + const pickScale = this.pickBaseScale / this.webgl.pixelRatio; const depth = this.drawPass.depthTexturePrimitives; - renderer.clear(false); - renderer.renderPick(scene.primitives, camera, variant, null); - renderer.renderPick(scene.volumes, camera, variant, depth); - renderer.renderPick(helper.handle.scene, camera, variant, null); + renderer.render(scene.primitives, camera, variant, true, false, pickScale, null); + renderer.render(scene.volumes, camera, variant, false, false, pickScale, depth); + renderer.render(helper.handle.scene, camera, variant, false, false, pickScale, null); } render(renderer: Renderer, camera: ICamera, scene: Scene, helper: Helper) { - renderer.update(camera); - this.objectPickTarget.bind(); this.renderVariant(renderer, camera, scene, helper, 'pickObject'); @@ -167,19 +165,17 @@ export class PickHelper { private render(camera: Camera | StereoCamera) { const { pickX, pickY, pickWidth, pickHeight, halfPickWidth } = this; - const { renderer, scene, helper } = this; - renderer.setTransparentBackground(false); - renderer.setDrawingBufferScale(this.pickScale); + const { renderer, scene, helper } = this; if (StereoCamera.is(camera)) { - renderer.setViewport(pickX, pickY, halfPickWidth, pickHeight); + this.renderer.setViewport(pickX, pickY, halfPickWidth, pickHeight); this.pickPass.render(renderer, camera.left, scene, helper); - renderer.setViewport(pickX + halfPickWidth, pickY, pickWidth - halfPickWidth, pickHeight); + this.renderer.setViewport(pickX + halfPickWidth, pickY, pickWidth - halfPickWidth, pickHeight); this.pickPass.render(renderer, camera.right, scene, helper); } else { - renderer.setViewport(pickX, pickY, pickWidth, pickHeight); + this.renderer.setViewport(pickX, pickY, pickWidth, pickHeight); this.pickPass.render(renderer, camera, scene, helper); } diff --git a/src/mol-canvas3d/passes/postprocessing.ts b/src/mol-canvas3d/passes/postprocessing.ts index 7880a0cb5337a8b5e60ba12a04aaedc0d52c0254..49aa45fb12c9b9b84fff558a65aec9839d18b53c 100644 --- a/src/mol-canvas3d/passes/postprocessing.ts +++ b/src/mol-canvas3d/passes/postprocessing.ts @@ -110,14 +110,6 @@ export class PostprocessingPass { this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTexture); } - private bindTarget(toDrawingBuffer: boolean) { - if (toDrawingBuffer) { - this.webgl.unbindFramebuffer(); - } else { - this.target.bind(); - } - } - syncSize() { const width = this.drawPass.colorTarget.getWidth(); const height = this.drawPass.colorTarget.getHeight(); @@ -167,8 +159,11 @@ export class PostprocessingPass { } const { gl, state } = this.webgl; - this.bindTarget(toDrawingBuffer); - + if (toDrawingBuffer) { + this.webgl.unbindFramebuffer(); + } else { + this.target.bind(); + } state.disable(gl.SCISSOR_TEST); state.disable(gl.BLEND); state.disable(gl.DEPTH_TEST); diff --git a/src/mol-canvas3d/passes/wboit.ts b/src/mol-canvas3d/passes/wboit.ts deleted file mode 100644 index d9ea9a1b54c4b54d97889c744a48369e7bf9d7e3..0000000000000000000000000000000000000000 --- a/src/mol-canvas3d/passes/wboit.ts +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz> - * @author Alexander Rose <alexander.rose@weirdbyte.de> - */ - -import { QuadSchema, QuadValues } from '../../mol-gl/compute/util'; -import { ComputeRenderable, createComputeRenderable } from '../../mol-gl/renderable'; -import { TextureSpec, UniformSpec, Values } from '../../mol-gl/renderable/schema'; -import { ShaderCode } from '../../mol-gl/shader-code'; -import { WebGLContext } from '../../mol-gl/webgl/context'; -import { createComputeRenderItem } from '../../mol-gl/webgl/render-item'; -import { Texture } from '../../mol-gl/webgl/texture'; -import { ValueCell } from '../../mol-util'; -import quad_vert from '../../mol-gl/shader/quad.vert'; -import evaluate_wboit_frag from '../../mol-gl/shader/evaluate-wboit.frag'; -import { Framebuffer } from '../../mol-gl/webgl/framebuffer'; -import { Vec2 } from '../../mol-math/linear-algebra'; -import { isDebugMode } from '../../mol-util/debug'; - -const EvaluateWboitSchema = { - ...QuadSchema, - tWboitA: TextureSpec('texture', 'rgba', 'float', 'nearest'), - tWboitB: TextureSpec('texture', 'rgba', 'float', 'nearest'), - uTexSize: UniformSpec('v2'), -}; -const EvaluateWboitShaderCode = ShaderCode('evaluate-wboit', quad_vert, evaluate_wboit_frag); -type EvaluateWboitRenderable = ComputeRenderable<Values<typeof EvaluateWboitSchema>> - -function getEvaluateWboitRenderable(ctx: WebGLContext, wboitATexture: Texture, wboitBTexture: Texture): EvaluateWboitRenderable { - const values: Values<typeof EvaluateWboitSchema> = { - ...QuadValues, - tWboitA: ValueCell.create(wboitATexture), - tWboitB: ValueCell.create(wboitBTexture), - uTexSize: ValueCell.create(Vec2.create(wboitATexture.getWidth(), wboitATexture.getHeight())), - }; - - const schema = { ...EvaluateWboitSchema }; - const renderItem = createComputeRenderItem(ctx, 'triangles', EvaluateWboitShaderCode, schema, values); - - return createComputeRenderable(renderItem, values); -} - -// - -export class WboitPass { - private readonly renderable: EvaluateWboitRenderable - - private readonly framebuffer: Framebuffer - private readonly textureA: Texture - private readonly textureB: Texture - - private _enabled = false; - get enabled() { - return this._enabled; - } - - bind() { - const { state, gl } = this.webgl; - - this.framebuffer.bind(); - - state.clearColor(0, 0, 0, 1); - gl.clear(gl.COLOR_BUFFER_BIT); - - state.disable(gl.DEPTH_TEST); - - state.blendFuncSeparate(gl.ONE, gl.ONE, gl.ZERO, gl.ONE_MINUS_SRC_ALPHA); - state.enable(gl.BLEND); - } - - render() { - const { state, gl } = this.webgl; - - state.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE); - state.enable(gl.BLEND); - - this.renderable.update(); - this.renderable.render(); - } - - setSize(width: number, height: number) { - const [w, h] = this.renderable.values.uTexSize.ref.value; - if (width !== w || height !== h) { - this.textureA.define(width, height); - this.textureB.define(width, height); - ValueCell.update(this.renderable.values.uTexSize, Vec2.set(this.renderable.values.uTexSize.ref.value, width, height)); - } - } - - constructor(private webgl: WebGLContext, width: number, height: number) { - const { resources, extensions } = webgl; - const { drawBuffers, textureFloat, colorBufferFloat, depthTexture } = extensions; - if (!textureFloat || !colorBufferFloat || !depthTexture || !drawBuffers) { - if (isDebugMode) console.log('Missing extensions required for "wboit"'); - return; - } - - this.textureA = resources.texture('image-float32', 'rgba', 'float', 'nearest'); - this.textureA.define(width, height); - - this.textureB = resources.texture('image-float32', 'rgba', 'float', 'nearest'); - this.textureB.define(width, height); - - this.renderable = getEvaluateWboitRenderable(webgl, this.textureA, this.textureB); - - this.framebuffer = resources.framebuffer(); - this.framebuffer.bind(); - drawBuffers.drawBuffers([ - drawBuffers.COLOR_ATTACHMENT0, - drawBuffers.COLOR_ATTACHMENT1, - ]); - - this.textureA.attachFramebuffer(this.framebuffer, 'color0'); - this.textureB.attachFramebuffer(this.framebuffer, 'color1'); - - this._enabled = true; - } -} \ No newline at end of file diff --git a/src/mol-geo/geometry/transparency-data.ts b/src/mol-geo/geometry/transparency-data.ts index 85e79813510cffddfb0e6cfa6c45169d9bea901f..22879551be9ae5d7999ff0439e4a2de61174a029 100644 --- a/src/mol-geo/geometry/transparency-data.ts +++ b/src/mol-geo/geometry/transparency-data.ts @@ -13,7 +13,6 @@ export type TransparencyData = { uTransparencyTexDim: ValueCell<Vec2> dTransparency: ValueCell<boolean>, dTransparencyVariant: ValueCell<string>, - transparencyAverage: ValueCell<number>, } export function applyTransparencyValue(array: Uint8Array, start: number, end: number, value: number) { @@ -23,14 +22,6 @@ export function applyTransparencyValue(array: Uint8Array, start: number, end: nu return true; } -export function getTransparencyAverage(array: Uint8Array, count: number): number { - let sum = 0; - for (let i = 0; i < count; ++i) { - sum += array[i]; - } - return sum / (255 * count); -} - export function clearTransparency(array: Uint8Array, start: number, end: number) { array.fill(0, start, end); } @@ -41,7 +32,6 @@ export function createTransparency(count: number, transparencyData?: Transparenc ValueCell.update(transparencyData.tTransparency, transparency); ValueCell.update(transparencyData.uTransparencyTexDim, Vec2.create(transparency.width, transparency.height)); ValueCell.updateIfChanged(transparencyData.dTransparency, count > 0); - ValueCell.updateIfChanged(transparencyData.transparencyAverage, getTransparencyAverage(transparency.array, count)); return transparencyData; } else { return { @@ -49,7 +39,6 @@ export function createTransparency(count: number, transparencyData?: Transparenc uTransparencyTexDim: ValueCell.create(Vec2.create(transparency.width, transparency.height)), dTransparency: ValueCell.create(count > 0), dTransparencyVariant: ValueCell.create('single'), - transparencyAverage: ValueCell.create(0), }; } } @@ -66,7 +55,6 @@ export function createEmptyTransparency(transparencyData?: TransparencyData): Tr uTransparencyTexDim: ValueCell.create(Vec2.create(1, 1)), dTransparency: ValueCell.create(false), dTransparencyVariant: ValueCell.create('single'), - transparencyAverage: ValueCell.create(0), }; } } \ No newline at end of file diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index 342eac9dd1bfe16527700b481e13915bd6039cde..7c4872bd3aa1e3cbe6ea35ea917b95bd56147a34 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/src/mol-gl/_spec/renderer.spec.ts @@ -132,17 +132,17 @@ describe('renderer', () => { scene.commit(); expect(ctx.stats.resourceCounts.attribute).toBe(ctx.isWebGL2 ? 4 : 5); expect(ctx.stats.resourceCounts.texture).toBe(6); - expect(ctx.stats.resourceCounts.vertexArray).toBe(6); - expect(ctx.stats.resourceCounts.program).toBe(6); - expect(ctx.stats.resourceCounts.shader).toBe(12); + expect(ctx.stats.resourceCounts.vertexArray).toBe(5); + expect(ctx.stats.resourceCounts.program).toBe(5); + expect(ctx.stats.resourceCounts.shader).toBe(10); scene.remove(points); scene.commit(); expect(ctx.stats.resourceCounts.attribute).toBe(0); expect(ctx.stats.resourceCounts.texture).toBe(0); expect(ctx.stats.resourceCounts.vertexArray).toBe(0); - expect(ctx.stats.resourceCounts.program).toBe(6); - expect(ctx.stats.resourceCounts.shader).toBe(12); + expect(ctx.stats.resourceCounts.program).toBe(5); + expect(ctx.stats.resourceCounts.shader).toBe(10); ctx.resources.destroy(); expect(ctx.stats.resourceCounts.program).toBe(0); diff --git a/src/mol-gl/renderable.ts b/src/mol-gl/renderable.ts index 7e70cfec82a43fc3b2f0d07d2d5dc86d55bd8514..51f087b79b309950499064488082646990a4a909 100644 --- a/src/mol-gl/renderable.ts +++ b/src/mol-gl/renderable.ts @@ -1,16 +1,15 @@ /** - * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { Program } from './webgl/program'; -import { RenderableValues, Values, RenderableSchema, BaseValues } from './renderable/schema'; +import { RenderableValues, Values, RenderableSchema } from './renderable/schema'; import { GraphicsRenderItem, ComputeRenderItem, GraphicsRenderVariant } from './webgl/render-item'; import { ValueCell } from '../mol-util'; import { idFactory } from '../mol-util/id-factory'; import { clamp } from '../mol-math/interpolate'; -import { Textures } from './webgl/texture'; const getNextRenderableId = idFactory(); @@ -20,7 +19,7 @@ export type RenderableState = { pickable: boolean colorOnly: boolean opaque: boolean - writeDepth: boolean + writeDepth: boolean, } export interface Renderable<T extends RenderableValues> { @@ -29,7 +28,7 @@ export interface Renderable<T extends RenderableValues> { readonly values: T readonly state: RenderableState - render: (variant: GraphicsRenderVariant, sharedTexturesList?: Textures) => void + render: (variant: GraphicsRenderVariant) => void getProgram: (variant: GraphicsRenderVariant) => Program update: () => void dispose: () => void @@ -42,11 +41,11 @@ export function createRenderable<T extends Values<RenderableSchema>>(renderItem: values, state, - render: (variant: GraphicsRenderVariant, sharedTexturesList?: Textures) => { + render: (variant: GraphicsRenderVariant) => { if (values.uAlpha && values.alpha) { ValueCell.updateIfChanged(values.uAlpha, clamp(values.alpha.ref.value * state.alphaFactor, 0, 1)); } - renderItem.render(variant, sharedTexturesList); + renderItem.render(variant); }, getProgram: (variant: GraphicsRenderVariant) => renderItem.getProgram(variant), update: () => renderItem.update(), @@ -54,8 +53,6 @@ export function createRenderable<T extends Values<RenderableSchema>>(renderItem: }; } -export type GraphicsRenderable = Renderable<RenderableValues & BaseValues> - // export interface ComputeRenderable<T extends RenderableValues> { diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 3ab83368fb85a8c8065255371c7198bd6081b038..a0fd532f6b031ba3547c9a04021200fce39dcce6 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/src/mol-gl/renderable/direct-volume.ts @@ -28,7 +28,6 @@ export const DirectVolumeSchema = { tTransparency: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'), dTransparency: DefineSpec('boolean'), dTransparencyVariant: DefineSpec('string', ['single', 'multi']), - transparencyAverage: ValueSpec('number'), dClipObjectCount: DefineSpec('number'), dClipVariant: DefineSpec('string', ['instance', 'pixel']), diff --git a/src/mol-gl/renderable/image.ts b/src/mol-gl/renderable/image.ts index 82c5172132755ee064546fa403ebf7224f74b18a..0ba595cca0e1d49c1cc73c7cba7964664b8cc6a2 100644 --- a/src/mol-gl/renderable/image.ts +++ b/src/mol-gl/renderable/image.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { AttributeSpec, Values, GlobalUniformSchema, InternalSchema, TextureSpec, ElementsSpec, DefineSpec, InternalValues, BaseSchema, UniformSpec, GlobalTextureSchema } from './schema'; +import { AttributeSpec, Values, GlobalUniformSchema, InternalSchema, TextureSpec, ElementsSpec, DefineSpec, InternalValues, BaseSchema, UniformSpec } from './schema'; import { ImageShaderCode } from '../shader-code'; import { ValueCell } from '../../mol-util'; import { InterpolationTypeNames } from '../../mol-geo/geometry/image/image'; @@ -30,7 +30,7 @@ export type ImageSchema = typeof ImageSchema export type ImageValues = Values<ImageSchema> export function ImageRenderable(ctx: WebGLContext, id: number, values: ImageValues, state: RenderableState, materialId: number): Renderable<ImageValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...ImageSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...ImageSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderable/lines.ts b/src/mol-gl/renderable/lines.ts index a8272b29cca6434e272be5e0c043d2196894f2f0..aa6c31bbb6f95e195880871fde0845aba2714344 100644 --- a/src/mol-gl/renderable/lines.ts +++ b/src/mol-gl/renderable/lines.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { GlobalUniformSchema, BaseSchema, AttributeSpec, DefineSpec, Values, InternalSchema, SizeSchema, ElementsSpec, InternalValues, GlobalTextureSchema } from './schema'; +import { GlobalUniformSchema, BaseSchema, AttributeSpec, DefineSpec, Values, InternalSchema, SizeSchema, ElementsSpec, InternalValues } from './schema'; import { ValueCell } from '../../mol-util'; import { LinesShaderCode } from '../shader-code'; @@ -26,7 +26,7 @@ export type LinesSchema = typeof LinesSchema export type LinesValues = Values<LinesSchema> export function LinesRenderable(ctx: WebGLContext, id: number, values: LinesValues, state: RenderableState, materialId: number): Renderable<LinesValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...LinesSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...LinesSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderable/mesh.ts b/src/mol-gl/renderable/mesh.ts index 50de083a80a73d3e2086e5ad441a944a0a2f0c76..5c56c062cd7373b15388715d36da78e8f2491b3c 100644 --- a/src/mol-gl/renderable/mesh.ts +++ b/src/mol-gl/renderable/mesh.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { GlobalUniformSchema, BaseSchema, AttributeSpec, ElementsSpec, DefineSpec, Values, InternalSchema, InternalValues, GlobalTextureSchema } from './schema'; +import { GlobalUniformSchema, BaseSchema, AttributeSpec, ElementsSpec, DefineSpec, Values, InternalSchema, InternalValues } from './schema'; import { MeshShaderCode } from '../shader-code'; import { ValueCell } from '../../mol-util'; @@ -25,7 +25,7 @@ export type MeshSchema = typeof MeshSchema export type MeshValues = Values<MeshSchema> export function MeshRenderable(ctx: WebGLContext, id: number, values: MeshValues, state: RenderableState, materialId: number): Renderable<MeshValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...MeshSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...MeshSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderable/points.ts b/src/mol-gl/renderable/points.ts index a97b8bb597525ae33dea1f87055b445a9f9f8abd..4f50b314e84b77f8e55303936e283a08d2f14830 100644 --- a/src/mol-gl/renderable/points.ts +++ b/src/mol-gl/renderable/points.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { GlobalUniformSchema, BaseSchema, AttributeSpec, UniformSpec, DefineSpec, Values, InternalSchema, SizeSchema, InternalValues, GlobalTextureSchema } from './schema'; +import { GlobalUniformSchema, BaseSchema, AttributeSpec, UniformSpec, DefineSpec, Values, InternalSchema, SizeSchema, InternalValues } from './schema'; import { PointsShaderCode } from '../shader-code'; import { ValueCell } from '../../mol-util'; @@ -23,7 +23,7 @@ export type PointsSchema = typeof PointsSchema export type PointsValues = Values<PointsSchema> export function PointsRenderable(ctx: WebGLContext, id: number, values: PointsValues, state: RenderableState, materialId: number): Renderable<PointsValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...PointsSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...PointsSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 40f0c0854e94f47955665f0c87948ddc71b7b3d5..06f65477c0393f337969b1c1cc124fe58ccc1554 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -155,8 +155,6 @@ export const GlobalUniformSchema = { uHighlightColor: UniformSpec('v3'), uSelectColor: UniformSpec('v3'), - - uRenderWboit: UniformSpec('i'), } as const; export type GlobalUniformSchema = typeof GlobalUniformSchema export type GlobalUniformValues = Values<GlobalUniformSchema> @@ -214,7 +212,6 @@ export const TransparencySchema = { tTransparency: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'), dTransparency: DefineSpec('boolean'), dTransparencyVariant: DefineSpec('string', ['single', 'multi']), - transparencyAverage: ValueSpec('number'), } as const; export type TransparencySchema = typeof TransparencySchema export type TransparencyValues = Values<TransparencySchema> diff --git a/src/mol-gl/renderable/spheres.ts b/src/mol-gl/renderable/spheres.ts index ebb602fbf5d27f16ecf9aa0e6cfdea8d1ca0a461..fbc5d0ec6b7db04ae2ef7554d8324fdcb27d440f 100644 --- a/src/mol-gl/renderable/spheres.ts +++ b/src/mol-gl/renderable/spheres.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { GlobalUniformSchema, BaseSchema, AttributeSpec, Values, InternalSchema, SizeSchema, InternalValues, ElementsSpec, ValueSpec, DefineSpec, GlobalTextureSchema } from './schema'; +import { GlobalUniformSchema, BaseSchema, AttributeSpec, Values, InternalSchema, SizeSchema, InternalValues, ElementsSpec, ValueSpec, DefineSpec } from './schema'; import { SpheresShaderCode } from '../shader-code'; import { ValueCell } from '../../mol-util'; @@ -26,7 +26,7 @@ export type SpheresSchema = typeof SpheresSchema export type SpheresValues = Values<SpheresSchema> export function SpheresRenderable(ctx: WebGLContext, id: number, values: SpheresValues, state: RenderableState, materialId: number): Renderable<SpheresValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...SpheresSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...SpheresSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderable/text.ts b/src/mol-gl/renderable/text.ts index a31ca9939613df91ec0d334b89d88e575da65729..a655bf144271ed92f81c78e4654ab9e8b51df28c 100644 --- a/src/mol-gl/renderable/text.ts +++ b/src/mol-gl/renderable/text.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { GlobalUniformSchema, BaseSchema, AttributeSpec, UniformSpec, Values, InternalSchema, SizeSchema, InternalValues, TextureSpec, ElementsSpec, ValueSpec, GlobalTextureSchema } from './schema'; +import { GlobalUniformSchema, BaseSchema, AttributeSpec, UniformSpec, Values, InternalSchema, SizeSchema, InternalValues, TextureSpec, ElementsSpec, ValueSpec } from './schema'; import { TextShaderCode } from '../shader-code'; import { ValueCell } from '../../mol-util'; @@ -35,7 +35,7 @@ export type TextSchema = typeof TextSchema export type TextValues = Values<TextSchema> export function TextRenderable(ctx: WebGLContext, id: number, values: TextValues, state: RenderableState, materialId: number): Renderable<TextValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...TextSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...TextSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderable/texture-mesh.ts b/src/mol-gl/renderable/texture-mesh.ts index 062936f5f5578591d0cebf92f3b4b466a458b9f9..a0d9be2ba1ff06d5649f36b085a11f97dbbf13ef 100644 --- a/src/mol-gl/renderable/texture-mesh.ts +++ b/src/mol-gl/renderable/texture-mesh.ts @@ -7,7 +7,7 @@ import { Renderable, RenderableState, createRenderable } from '../renderable'; import { WebGLContext } from '../webgl/context'; import { createGraphicsRenderItem } from '../webgl/render-item'; -import { GlobalUniformSchema, BaseSchema, DefineSpec, Values, InternalSchema, InternalValues, UniformSpec, TextureSpec, GlobalTextureSchema } from './schema'; +import { GlobalUniformSchema, BaseSchema, DefineSpec, Values, InternalSchema, InternalValues, UniformSpec, TextureSpec } from './schema'; import { MeshShaderCode } from '../shader-code'; import { ValueCell } from '../../mol-util'; @@ -28,7 +28,7 @@ export type TextureMeshSchema = typeof TextureMeshSchema export type TextureMeshValues = Values<TextureMeshSchema> export function TextureMeshRenderable(ctx: WebGLContext, id: number, values: TextureMeshValues, state: RenderableState, materialId: number): Renderable<TextureMeshValues> { - const schema = { ...GlobalUniformSchema, ...GlobalTextureSchema, ...InternalSchema, ...TextureMeshSchema }; + const schema = { ...GlobalUniformSchema, ...InternalSchema, ...TextureMeshSchema }; const internalValues: InternalValues = { uObjectId: ValueCell.create(id), }; diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index ea27728397c023b0ad202af6d7b31112a47fb005..09c94035d5f6e09dca17aad38bb6d67c27e5eb1b 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -9,18 +9,17 @@ import { ICamera } from '../mol-canvas3d/camera'; import Scene from './scene'; import { WebGLContext } from './webgl/context'; import { Mat4, Vec3, Vec4, Vec2, Quat } from '../mol-math/linear-algebra'; -import { GraphicsRenderable } from './renderable'; +import { Renderable } from './renderable'; import { Color } from '../mol-util/color'; import { ValueCell, deepEqual } from '../mol-util'; -import { GlobalUniformValues } from './renderable/schema'; +import { RenderableValues, GlobalUniformValues, BaseValues } from './renderable/schema'; import { GraphicsRenderVariant } from './webgl/render-item'; import { ParamDefinition as PD } from '../mol-util/param-definition'; import { Clipping } from '../mol-theme/clipping'; import { stringToWords } from '../mol-util/string'; import { Transparency } from '../mol-theme/transparency'; import { degToRad } from '../mol-math/misc'; -import { createNullTexture, Texture, Textures } from './webgl/texture'; -import { arrayMapUpsert } from '../mol-util/array'; +import { Texture } from './webgl/texture'; export interface RendererStats { programCount: number @@ -42,21 +41,10 @@ interface Renderer { readonly stats: RendererStats readonly props: Readonly<RendererProps> - clear: (toBackgroundColor: boolean) => void - clearDepth: () => void - update: (camera: ICamera) => void - - renderPick: (group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, depthTexture: Texture | null) => void - renderDepth: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void - renderBlended: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void - renderWboitOpaque: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void - renderWboitTransparent: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void - + clear: (transparentBackground: boolean) => void + render: (group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, clear: boolean, transparentBackground: boolean, drawingBufferScale: number, depthTexture: Texture | null) => void setProps: (props: Partial<RendererProps>) => void setViewport: (x: number, y: number, width: number, height: number) => void - setTransparentBackground: (value: boolean) => void - setDrawingBufferScale: (value: number) => void - dispose: () => void } @@ -179,14 +167,6 @@ namespace Renderer { const drawingBufferSize = Vec2.create(gl.drawingBufferWidth, gl.drawingBufferHeight); const bgColor = Color.toVec3Normalized(Vec3(), p.backgroundColor); - let transparentBackground = false; - let drawingBufferScale = 1; - - const nullDepthTexture = createNullTexture(gl, 'image-depth'); - const sharedTexturesList: Textures = [ - ['tDepth', nullDepthTexture] - ]; - const view = Mat4(); const invView = Mat4(); const modelView = Mat4(); @@ -224,9 +204,6 @@ namespace Renderer { uFogNear: ValueCell.create(1), uFogFar: ValueCell.create(10000), uFogColor: ValueCell.create(bgColor), - - uRenderWboit: ValueCell.create(0), - uTransparentBackground: ValueCell.create(false), uClipObjectType: ValueCell.create(clip.objects.type), @@ -255,7 +232,7 @@ namespace Renderer { let globalUniformsNeedUpdate = true; - const renderObject = (r: GraphicsRenderable, variant: GraphicsRenderVariant) => { + const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: GraphicsRenderVariant, depthTexture: Texture | null) => { if (!r.state.visible || (!r.state.pickable && variant[0] === 'p')) { return; } @@ -288,23 +265,26 @@ namespace Renderer { globalUniformsNeedUpdate = false; } + if (depthTexture) program.bindTextures([['tDepth', depthTexture]]); + if (r.values.dRenderMode) { // indicates direct-volume - // culling done in fragment shader - state.disable(gl.CULL_FACE); - state.frontFace(gl.CCW); - - if (variant === 'colorBlended') { - // depth test done manually in shader against `depthTexture` - // still need to enable when fragDepth can be used to write depth - if (r.values.dRenderMode.ref.value === 'volume' || !fragDepth) { - state.disable(gl.DEPTH_TEST); - state.depthMask(false); - } else { - state.enable(gl.DEPTH_TEST); - state.depthMask(r.state.writeDepth); - } + // always cull front + state.enable(gl.CULL_FACE); + state.frontFace(gl.CW); + state.cullFace(gl.BACK); + + // depth test done manually in shader against `depthTexture` + // still need to enable when fragDepth can be used to write depth + // (unclear why depthMask is insufficient) + if (r.values.dRenderMode.ref.value === 'volume' || !fragDepth) { + state.disable(gl.DEPTH_TEST); + state.depthMask(false); + } else { + state.enable(gl.DEPTH_TEST); + state.depthMask(r.state.writeDepth); } } else { + state.enable(gl.DEPTH_TEST); if (r.values.dDoubleSided) { if (r.values.dDoubleSided.ref.value || r.values.hasReflection.ref.value) { state.disable(gl.CULL_FACE); @@ -330,17 +310,22 @@ namespace Renderer { state.cullFace(gl.BACK); } - if (variant === 'colorBlended') state.depthMask(r.state.writeDepth); + state.depthMask(r.state.writeDepth); } - r.render(variant, sharedTexturesList); + r.render(variant); }; - const update = (camera: ICamera) => { + const render = (group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, clear: boolean, transparentBackground: boolean, drawingBufferScale: number, depthTexture: Texture | null) => { + ValueCell.update(globalUniforms.uModel, group.view); ValueCell.update(globalUniforms.uView, camera.view); ValueCell.update(globalUniforms.uInvView, Mat4.invert(invView, camera.view)); + ValueCell.update(globalUniforms.uModelView, Mat4.mul(modelView, group.view, camera.view)); + ValueCell.update(globalUniforms.uInvModelView, Mat4.invert(invModelView, modelView)); ValueCell.update(globalUniforms.uProjection, camera.projection); ValueCell.update(globalUniforms.uInvProjection, Mat4.invert(invProjection, camera.projection)); + ValueCell.update(globalUniforms.uModelViewProjection, Mat4.mul(modelViewProjection, modelView, camera.projection)); + ValueCell.update(globalUniforms.uInvModelViewProjection, Mat4.invert(invModelViewProjection, modelViewProjection)); ValueCell.updateIfChanged(globalUniforms.uIsOrtho, camera.state.mode === 'orthographic' ? 1 : 0); ValueCell.update(globalUniforms.uViewOffset, camera.viewOffset.enabled ? Vec2.set(viewOffset, camera.viewOffset.offsetX * 16, camera.viewOffset.offsetY * 16) : Vec2.set(viewOffset, 0, 0)); @@ -362,150 +347,74 @@ namespace Renderer { gl.drawingBufferHeight * drawingBufferScale )); } - }; - const updateInternal = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null, renderWboit: boolean) => { - arrayMapUpsert(sharedTexturesList, 'tDepth', depthTexture || nullDepthTexture); - - ValueCell.update(globalUniforms.uModel, group.view); - ValueCell.update(globalUniforms.uModelView, Mat4.mul(modelView, group.view, camera.view)); - ValueCell.update(globalUniforms.uInvModelView, Mat4.invert(invModelView, modelView)); - ValueCell.update(globalUniforms.uModelViewProjection, Mat4.mul(modelViewProjection, modelView, camera.projection)); - ValueCell.update(globalUniforms.uInvModelViewProjection, Mat4.invert(invModelViewProjection, modelViewProjection)); + globalUniformsNeedUpdate = true; + state.currentRenderItemId = -1; - ValueCell.updateIfChanged(globalUniforms.uRenderWboit, renderWboit ? 1 : 0); + const { renderables } = group; state.enable(gl.SCISSOR_TEST); + state.disable(gl.BLEND); state.colorMask(true, true, true, true); + state.enable(gl.DEPTH_TEST); const { x, y, width, height } = viewport; gl.viewport(x, y, width, height); gl.scissor(x, y, width, height); - globalUniformsNeedUpdate = true; - state.currentRenderItemId = -1; - }; - - const renderPick = (group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, depthTexture: Texture | null) => { - state.disable(gl.BLEND); - state.enable(gl.DEPTH_TEST); - state.depthMask(true); - - updateInternal(group, camera, depthTexture, false); - - const { renderables } = group; - for (let i = 0, il = renderables.length; i < il; ++i) { - if (!renderables[i].state.colorOnly) { - renderObject(renderables[i], variant); + if (clear) { + state.depthMask(true); + if (variant === 'color') { + state.clearColor(bgColor[0], bgColor[1], bgColor[2], transparentBackground ? 0 : 1); + } else { + state.clearColor(1, 1, 1, 1); } + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); } - }; - - const renderDepth = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => { - state.disable(gl.BLEND); - state.enable(gl.DEPTH_TEST); - state.depthMask(true); - - updateInternal(group, camera, depthTexture, false); - - const { renderables } = group; - for (let i = 0, il = renderables.length; i < il; ++i) { - renderObject(renderables[i], 'depth'); - } - }; - - const renderBlended = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => { - state.disable(gl.BLEND); - state.enable(gl.DEPTH_TEST); - state.depthMask(true); - - updateInternal(group, camera, depthTexture, false); - const { renderables } = group; - for (let i = 0, il = renderables.length; i < il; ++i) { - const r = renderables[i]; - if (r.state.opaque) { - renderObject(r, 'colorBlended'); + if (variant === 'color') { + for (let i = 0, il = renderables.length; i < il; ++i) { + const r = renderables[i]; + if (r.state.opaque) { + renderObject(r, variant, depthTexture); + } } - } - state.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE); - state.enable(gl.BLEND); - - state.depthMask(true); - for (let i = 0, il = renderables.length; i < il; ++i) { - const r = renderables[i]; - if (!r.state.opaque && r.state.writeDepth) { - renderObject(r, 'colorBlended'); + state.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE); + state.enable(gl.BLEND); + for (let i = 0, il = renderables.length; i < il; ++i) { + const r = renderables[i]; + if (!r.state.opaque && r.state.writeDepth) { + renderObject(r, variant, depthTexture); + } } - } - - state.depthMask(false); - for (let i = 0, il = renderables.length; i < il; ++i) { - const r = renderables[i]; - if (!r.state.opaque && !r.state.writeDepth) { - renderObject(r, 'colorBlended'); + for (let i = 0, il = renderables.length; i < il; ++i) { + const r = renderables[i]; + if (!r.state.opaque && !r.state.writeDepth) { + renderObject(r, variant, depthTexture); + } } - } - }; - - const renderWboitOpaque = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => { - state.disable(gl.BLEND); - state.enable(gl.DEPTH_TEST); - state.depthMask(true); - - updateInternal(group, camera, depthTexture, false); - - const { renderables } = group; - for (let i = 0, il = renderables.length; i < il; ++i) { - const r = renderables[i]; - if (r.values.uAlpha.ref.value === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values?.dRenderMode?.ref.value !== 'volume') { - renderObject(r, 'colorWboit'); + } else { // picking & depth + for (let i = 0, il = renderables.length; i < il; ++i) { + if (!renderables[i].state.colorOnly) { + renderObject(renderables[i], variant, depthTexture); + } } } - }; - - const renderWboitTransparent = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => { - updateInternal(group, camera, depthTexture, true); - const { renderables } = group; - for (let i = 0, il = renderables.length; i < il; ++i) { - const r = renderables[i]; - if (r.values.uAlpha.ref.value < 1 || r.values.transparencyAverage.ref.value > 0 || r.values?.dRenderMode?.ref.value === 'volume') { - renderObject(r, 'colorWboit'); - } - } + gl.flush(); }; return { - clear: (toBackgroundColor: boolean) => { + clear: (transparentBackground: boolean) => { + ctx.unbindFramebuffer(); state.enable(gl.SCISSOR_TEST); - state.enable(gl.DEPTH_TEST); - state.colorMask(true, true, true, true); state.depthMask(true); - - if (transparentBackground) { - state.clearColor(1, 1, 1, 0); - } else if (toBackgroundColor) { - state.clearColor(bgColor[0], bgColor[1], bgColor[2], 1); - } else { - state.clearColor(1, 1, 1, 1); - } + state.colorMask(true, true, true, true); + state.clearColor(bgColor[0], bgColor[1], bgColor[2], transparentBackground ? 0 : 1); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); }, - clearDepth: () => { - state.enable(gl.SCISSOR_TEST); - state.enable(gl.DEPTH_TEST); - state.depthMask(true); - gl.clear(gl.DEPTH_BUFFER_BIT); - }, - update, - - renderPick, - renderDepth, - renderBlended, - renderWboitOpaque, - renderWboitTransparent, + render, setProps: (props: Partial<RendererProps>) => { if (props.backgroundColor !== undefined && props.backgroundColor !== p.backgroundColor) { @@ -572,12 +481,6 @@ namespace Renderer { ValueCell.update(globalUniforms.uViewport, Vec4.set(globalUniforms.uViewport.ref.value, x, y, width, height)); } }, - setTransparentBackground: (value: boolean) => { - transparentBackground = value; - }, - setDrawingBufferScale: (value: number) => { - drawingBufferScale = value; - }, get props() { return p; diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts index 9974f3b80bcc4d0f837020c2c277f59787e17bd7..3834adc1e73773006579c1cdbce40d8afe8f33b0 100644 --- a/src/mol-gl/scene.ts +++ b/src/mol-gl/scene.ts @@ -5,7 +5,9 @@ * @author David Sehnal <david.sehnal@gmail.com> */ +import { Renderable } from './renderable'; import { WebGLContext } from './webgl/context'; +import { RenderableValues, BaseValues } from './renderable/schema'; import { GraphicsRenderObject, createRenderable } from './render-object'; import { Object3D } from './object3d'; import { Sphere3D } from '../mol-math/geometry'; @@ -14,11 +16,10 @@ import { now } from '../mol-util/now'; import { arraySetRemove } from '../mol-util/array'; import { BoundaryHelper } from '../mol-math/geometry/boundary-helper'; import { hash1 } from '../mol-data/util'; -import { GraphicsRenderable } from './renderable'; const boundaryHelper = new BoundaryHelper('98'); -function calculateBoundingSphere(renderables: GraphicsRenderable[], boundingSphere: Sphere3D, onlyVisible: boolean): Sphere3D { +function calculateBoundingSphere(renderables: Renderable<RenderableValues & BaseValues>[], boundingSphere: Sphere3D, onlyVisible: boolean): Sphere3D { boundaryHelper.reset(); for (let i = 0, il = renderables.length; i < il; ++i) { @@ -42,9 +43,9 @@ function calculateBoundingSphere(renderables: GraphicsRenderable[], boundingSphe return boundaryHelper.getSphere(boundingSphere); } -function renderableSort(a: GraphicsRenderable, b: GraphicsRenderable) { - const drawProgramIdA = a.getProgram('colorBlended').id; - const drawProgramIdB = b.getProgram('colorBlended').id; +function renderableSort(a: Renderable<RenderableValues & BaseValues>, b: Renderable<RenderableValues & BaseValues>) { + const drawProgramIdA = a.getProgram('color').id; + const drawProgramIdB = b.getProgram('color').id; const materialIdA = a.materialId; const materialIdB = b.materialId; @@ -61,7 +62,7 @@ function renderableSort(a: GraphicsRenderable, b: GraphicsRenderable) { interface Scene extends Object3D { readonly count: number - readonly renderables: ReadonlyArray<GraphicsRenderable> + readonly renderables: ReadonlyArray<Renderable<RenderableValues & BaseValues>> readonly boundingSphere: Sphere3D readonly boundingSphereVisible: Sphere3D @@ -71,28 +72,28 @@ interface Scene extends Object3D { /** Returns `true` if some visibility has changed, `false` otherwise. */ syncVisibility: () => boolean update: (objects: ArrayLike<GraphicsRenderObject> | undefined, keepBoundingSphere: boolean) => void - add: (o: GraphicsRenderObject) => void // GraphicsRenderable + add: (o: GraphicsRenderObject) => void // Renderable<any> remove: (o: GraphicsRenderObject) => void commit: (maxTimeMs?: number) => boolean readonly needsCommit: boolean has: (o: GraphicsRenderObject) => boolean clear: () => void - forEach: (callbackFn: (value: GraphicsRenderable, key: GraphicsRenderObject) => void) => void + forEach: (callbackFn: (value: Renderable<RenderableValues & BaseValues>, key: GraphicsRenderObject) => void) => void } namespace Scene { export interface Group extends Object3D { - readonly renderables: ReadonlyArray<GraphicsRenderable> + readonly renderables: ReadonlyArray<Renderable<RenderableValues & BaseValues>> } export function create(ctx: WebGLContext): Scene { - const renderableMap = new Map<GraphicsRenderObject, GraphicsRenderable>(); - const renderables: GraphicsRenderable[] = []; + const renderableMap = new Map<GraphicsRenderObject, Renderable<RenderableValues & BaseValues>>(); + const renderables: Renderable<RenderableValues & BaseValues>[] = []; const boundingSphere = Sphere3D(); const boundingSphereVisible = Sphere3D(); - const primitives: GraphicsRenderable[] = []; - const volumes: GraphicsRenderable[] = []; + const primitives: Renderable<RenderableValues & BaseValues>[] = []; + const volumes: Renderable<RenderableValues & BaseValues>[] = []; let boundingSphereDirty = true; let boundingSphereVisibleDirty = true; @@ -222,7 +223,7 @@ namespace Scene { boundingSphereDirty = true; boundingSphereVisibleDirty = true; }, - forEach: (callbackFn: (value: GraphicsRenderable, key: GraphicsRenderObject) => void) => { + forEach: (callbackFn: (value: Renderable<any>, key: GraphicsRenderObject) => void) => { renderableMap.forEach(callbackFn); }, get count() { diff --git a/src/mol-gl/shader-code.ts b/src/mol-gl/shader-code.ts index d37bcc0d3a02638676b136da75f273e304136050..3b85e1800ca82654970e38f8574769d84f19a0bb 100644 --- a/src/mol-gl/shader-code.ts +++ b/src/mol-gl/shader-code.ts @@ -59,8 +59,6 @@ import size_vert_params from './shader/chunks/size-vert-params.glsl'; import texture3d_from_1d_trilinear from './shader/chunks/texture3d-from-1d-trilinear.glsl'; import texture3d_from_2d_linear from './shader/chunks/texture3d-from-2d-linear.glsl'; import texture3d_from_2d_nearest from './shader/chunks/texture3d-from-2d-nearest.glsl'; -import wboit_params from './shader/chunks/wboit-params.glsl'; -import wboit_write from './shader/chunks/wboit-write.glsl'; const ShaderChunks: { [k: string]: string } = { apply_fog, @@ -90,9 +88,7 @@ const ShaderChunks: { [k: string]: string } = { size_vert_params, texture3d_from_1d_trilinear, texture3d_from_2d_linear, - texture3d_from_2d_nearest, - wboit_params, - wboit_write + texture3d_from_2d_nearest }; const reInclude = /^(?!\/\/)\s*#include\s+(\S+)/gmi; @@ -119,31 +115,31 @@ export function ShaderCode(name: string, vert: string, frag: string, extensions: import points_vert from './shader/points.vert'; import points_frag from './shader/points.frag'; -export const PointsShaderCode = ShaderCode('points', points_vert, points_frag, { drawBuffers: 'optional' }); +export const PointsShaderCode = ShaderCode('points', points_vert, points_frag); import spheres_vert from './shader/spheres.vert'; import spheres_frag from './shader/spheres.frag'; -export const SpheresShaderCode = ShaderCode('spheres', spheres_vert, spheres_frag, { fragDepth: 'required', drawBuffers: 'optional' }); +export const SpheresShaderCode = ShaderCode('spheres', spheres_vert, spheres_frag, { fragDepth: 'required' }); import text_vert from './shader/text.vert'; import text_frag from './shader/text.frag'; -export const TextShaderCode = ShaderCode('text', text_vert, text_frag, { standardDerivatives: 'required', drawBuffers: 'optional' }); +export const TextShaderCode = ShaderCode('text', text_vert, text_frag, { standardDerivatives: 'required' }); import lines_vert from './shader/lines.vert'; import lines_frag from './shader/lines.frag'; -export const LinesShaderCode = ShaderCode('lines', lines_vert, lines_frag, { drawBuffers: 'optional' }); +export const LinesShaderCode = ShaderCode('lines', lines_vert, lines_frag); import mesh_vert from './shader/mesh.vert'; import mesh_frag from './shader/mesh.frag'; -export const MeshShaderCode = ShaderCode('mesh', mesh_vert, mesh_frag, { standardDerivatives: 'optional', drawBuffers: 'optional' }); +export const MeshShaderCode = ShaderCode('mesh', mesh_vert, mesh_frag, { standardDerivatives: 'optional' }); import direct_volume_vert from './shader/direct-volume.vert'; import direct_volume_frag from './shader/direct-volume.frag'; -export const DirectVolumeShaderCode = ShaderCode('direct-volume', direct_volume_vert, direct_volume_frag, { fragDepth: 'optional', drawBuffers: 'optional' }); +export const DirectVolumeShaderCode = ShaderCode('direct-volume', direct_volume_vert, direct_volume_frag, { fragDepth: 'optional' }); import image_vert from './shader/image.vert'; import image_frag from './shader/image.frag'; -export const ImageShaderCode = ShaderCode('image', image_vert, image_frag, { drawBuffers: 'optional' }); +export const ImageShaderCode = ShaderCode('image', image_vert, image_frag); // @@ -190,7 +186,6 @@ function getGlsl100FragPrefix(extensions: WebGLExtensions, shaderExtensions: Sha if (extensions.drawBuffers) { prefix.push('#extension GL_EXT_draw_buffers : require'); prefix.push('#define requiredDrawBuffers'); - prefix.push('#define gl_FragColor gl_FragData[0]'); } else if (shaderExtensions.drawBuffers === 'required') { throw new Error(`required 'GL_EXT_draw_buffers' extension not available`); } @@ -203,9 +198,6 @@ function getGlsl100FragPrefix(extensions: WebGLExtensions, shaderExtensions: Sha throw new Error(`required 'GL_EXT_shader_texture_lod' extension not available`); } } - if (extensions.depthTexture) { - prefix.push('#define depthTextureSupport'); - } return prefix.join('\n') + '\n'; } @@ -216,8 +208,6 @@ const glsl300VertPrefix = `#version 300 es `; const glsl300FragPrefixCommon = ` -layout(location = 0) out highp vec4 out_FragData0; - #define varying in #define texture2D texture #define texture2DLodEXT textureLod @@ -225,7 +215,7 @@ layout(location = 0) out highp vec4 out_FragData0; #define gl_FragColor out_FragData0 #define gl_FragDepthEXT gl_FragDepth -#define depthTextureSupport +#define requiredDrawBuffers `; function getGlsl300FragPrefix(gl: WebGL2RenderingContext, extensions: WebGLExtensions, shaderExtensions: ShaderExtensions) { @@ -236,16 +226,12 @@ function getGlsl300FragPrefix(gl: WebGL2RenderingContext, extensions: WebGLExten if (shaderExtensions.fragDepth) { prefix.push('#define enabledFragDepth'); } - if (shaderExtensions.drawBuffers) { - prefix.push('#define requiredDrawBuffers'); + if (extensions.drawBuffers) { const maxDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS) as number; - for (let i = 1, il = maxDrawBuffers; i < il; ++i) { + for (let i = 0, il = maxDrawBuffers; i < il; ++i) { prefix.push(`layout(location = ${i}) out highp vec4 out_FragData${i};`); } } - if (shaderExtensions.shaderTextureLod) { - prefix.push('#define enabledShaderTextureLod'); - } prefix.push(glsl300FragPrefixCommon); return prefix.join('\n') + '\n'; } diff --git a/src/mol-gl/shader/chunks/apply-fog.glsl.ts b/src/mol-gl/shader/chunks/apply-fog.glsl.ts index 6bd3ef7ebc5fdd75a8cd76027c278bc5e471307f..e58c39ca1bf7857d5005ae73540cf81e4adadda3 100644 --- a/src/mol-gl/shader/chunks/apply-fog.glsl.ts +++ b/src/mol-gl/shader/chunks/apply-fog.glsl.ts @@ -2,12 +2,12 @@ export default ` float fogDepth = length(vViewPosition); float fogFactor = smoothstep(uFogNear, uFogFar, fogDepth); float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a; -float preFogAlpha = gl_FragColor.a < 1.0 ? fogAlpha : 1.0; if (!uTransparentBackground) { gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor); if (gl_FragColor.a < 1.0) gl_FragColor.a = fogAlpha; } else { + float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a; gl_FragColor.a = fogAlpha; } `; \ No newline at end of file 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 a79bb18924f2672a0af13d2973c21f96a244a334..4ad0f6a17c3f5960e9a4269f390aa0e6eaf0aad1 100644 --- a/src/mol-gl/shader/chunks/assign-material-color.glsl.ts +++ b/src/mol-gl/shader/chunks/assign-material-color.glsl.ts @@ -28,30 +28,25 @@ export default ` if (ta < uPickingAlphaThreshold) discard; // ignore so the element below can be picked #else - #if defined(dRenderVariant_colorBlended) - float at = 0.0; + float at = 0.0; - // shift by view-offset during multi-sample rendering to allow for blending - vec2 coord = gl_FragCoord.xy + uViewOffset * 0.25; + // shift by view-offset during multi-sample rendering to allow for blending + vec2 coord = gl_FragCoord.xy + uViewOffset * 0.25; - #if defined(dTransparencyVariant_single) - const mat4 thresholdMatrix = mat4( - 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0, - 13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0, - 4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0, - 16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0 - ); - at = thresholdMatrix[int(intMod(coord.x, 4.0))][int(intMod(coord.y, 4.0))]; - #elif defined(dTransparencyVariant_multi) - at = fract(dot(vec3(coord, vGroup + 0.5), vec3(2.0, 7.0, 23.0) / 17.0f)); - #endif - - if (ta < 0.99 && (ta < 0.01 || ta < at)) { - discard; - } - #elif defined(dRenderVariant_colorWboit) - material.a *= ta; + #if defined(dTransparencyVariant_single) + const mat4 thresholdMatrix = mat4( + 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0, + 13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0, + 4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0, + 16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0 + ); + at = thresholdMatrix[int(intMod(coord.x, 4.0))][int(intMod(coord.y, 4.0))]; + #elif defined(dTransparencyVariant_multi) + at = fract(dot(vec3(coord, vGroup + 0.5), vec3(2.0, 7.0, 23.0) / 17.0f)); #endif + + if (ta < 0.99 && (ta < 0.01 || ta < at)) + discard; #endif #endif `; \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts index 6c784e73b062809b0f6d047331e8b5f3eca14c9a..e5e44da56106b0c335a4cf7d007e72a2847ab90a 100644 --- a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts +++ b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts @@ -43,6 +43,4 @@ uniform float uInteriorDarkening; uniform bool uInteriorColorFlag; uniform vec3 uInteriorColor; bool interior; - -uniform mat4 uProjection; `; \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/common.glsl.ts b/src/mol-gl/shader/chunks/common.glsl.ts index 710e8779fb0938206849f7be11191c8e067b31e6..486632ba92d1ae5d708fc11acb78e05ad571e79f 100644 --- a/src/mol-gl/shader/chunks/common.glsl.ts +++ b/src/mol-gl/shader/chunks/common.glsl.ts @@ -1,10 +1,6 @@ export default ` // TODO find a better place for these convenience defines -#if defined(dRenderVariant_colorBlended) || defined(dRenderVariant_colorWboit) - #define dRenderVariant_color -#endif - #if defined(dRenderVariant_pickObject) || defined(dRenderVariant_pickInstance) || defined(dRenderVariant_pickGroup) #define dRenderVariant_pick #endif diff --git a/src/mol-gl/shader/chunks/wboit-params.glsl.ts b/src/mol-gl/shader/chunks/wboit-params.glsl.ts deleted file mode 100644 index 3655cf1d3528d6d1d770cb0e50360d19599160be..0000000000000000000000000000000000000000 --- a/src/mol-gl/shader/chunks/wboit-params.glsl.ts +++ /dev/null @@ -1,20 +0,0 @@ -export default ` -#if defined(dRenderVariant_colorWboit) - #if !defined(dRenderMode_volume) && !defined(dRenderMode_isosurface) - uniform sampler2D tDepth; - uniform vec2 uDrawingBufferSize; - - float getDepth(const in vec2 coords) { - // always packed due to merged depth from primitives and volumes - return unpackRGBAToDepth(texture2D(tDepth, coords)); - } - #endif -#endif - -uniform int uRenderWboit; - -float calcDepth(const in vec3 pos) { - vec2 clipZW = pos.z * uProjection[2].zw + uProjection[3].zw; - return 0.5 + 0.5 * clipZW.x / clipZW.y; -} -`; \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/wboit-write.glsl.ts b/src/mol-gl/shader/chunks/wboit-write.glsl.ts deleted file mode 100644 index 18b7f229d372050229d1bbfbdd83556893d22421..0000000000000000000000000000000000000000 --- a/src/mol-gl/shader/chunks/wboit-write.glsl.ts +++ /dev/null @@ -1,18 +0,0 @@ -export default ` -#if defined(dRenderVariant_colorWboit) - if (uRenderWboit == 0) { - if (preFogAlpha < 1.0) { - discard; - } - } else if (uRenderWboit == 1) { - if (preFogAlpha != 1.0 && !interior && fragmentDepth < getDepth(gl_FragCoord.xy / uDrawingBufferSize)) { - float alpha = preFogAlpha; - float wboitWeight = alpha * clamp(pow(1.0 - fragmentDepth, 2.0), 0.01, 1.0); - gl_FragColor = vec4(gl_FragColor.rgb * alpha * wboitWeight, alpha); - gl_FragData[1] = vec4(alpha * wboitWeight); - } else { - discard; - } - } -#endif -`; \ No newline at end of file diff --git a/src/mol-gl/shader/direct-volume.frag.ts b/src/mol-gl/shader/direct-volume.frag.ts index b17260d5d5d847aff57e07ccb38e398dc72268cf..bde2839a47f971504a6ed4c2c1480552fd6a8dfb 100644 --- a/src/mol-gl/shader/direct-volume.frag.ts +++ b/src/mol-gl/shader/direct-volume.frag.ts @@ -121,22 +121,21 @@ uniform mat4 uCartnToUnit; } #endif -#include wboit_params - vec4 transferFunction(float value) { return texture2D(tTransferTex, vec2(value, 0.0)); } +// Calculate depth based on the given camera position. +float calcDepth(const in vec3 cameraPos){ + vec2 clipZW = cameraPos.z * uProjection[2].zw + uProjection[3].zw; + return 0.5 + 0.5 * clipZW.x / clipZW.y; +} + float getDepth(const in vec2 coords) { - #ifdef depthTextureSupport - if (uRenderWboit == 0) { - // in case of opaque volumes (and depth texture support) - return texture2D(tDepth, coords).r; - } else { - return unpackRGBAToDepth(texture2D(tDepth, coords)); - } - #else + #ifdef dPackedDepth return unpackRGBAToDepth(texture2D(tDepth, coords)); + #else + return texture2D(tDepth, coords).r; #endif } @@ -146,8 +145,6 @@ vec3 v3m4(vec3 p, mat4 m) { return (m * vec4(p, 1.0)).xyz; } -float preFogAlphaBlended = 0.0; - vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) { #if defined(dRenderVariant_color) && !defined(dIgnoreLight) mat3 normalMatrix = transpose3(inverse3(mat3(uModelView * vTransform))); @@ -324,8 +321,6 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) { float vMarker = readFromTexture(tMarker, vInstance * float(uGroupCount) + group, uMarkerTexDim).a; #include apply_interior_color #include apply_marker_color - - preFogAlphaBlended = (1.0 - preFogAlphaBlended) * gl_FragColor.a + preFogAlphaBlended; #include apply_fog src = gl_FragColor; @@ -387,8 +382,6 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) { float vMarker = readFromTexture(tMarker, vInstance * float(uGroupCount) + group, uMarkerTexDim).a; #include apply_marker_color - - preFogAlphaBlended = (1.0 - preFogAlphaBlended) * gl_FragColor.a + preFogAlphaBlended; #include apply_fog src = gl_FragColor; @@ -418,9 +411,6 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) { // TODO: support clipping exclusion texture support void main () { - if (gl_FrontFacing) - discard; - #if defined(dRenderVariant_pick) || defined(dRenderVariant_depth) #if defined(dRenderMode_volume) // always ignore pick & depth for volume @@ -443,16 +433,5 @@ void main () { if (gl_FragColor == vec4(0.0)) discard; #endif - - #if defined(dRenderVariant_color) - #if defined(dRenderMode_isosurface) && defined(enabledFragDepth) - float fragmentDepth = gl_FragDepthEXT; - #else - float fragmentDepth = calcDepth((uView * vec4(uCameraPosition + (d * rayDir), 1.0)).xyz); - #endif - float preFogAlpha = clamp(preFogAlphaBlended, 0.0, 1.0); - interior = false; - #include wboit_write - #endif } `; \ No newline at end of file diff --git a/src/mol-gl/shader/evaluate-wboit.frag.ts b/src/mol-gl/shader/evaluate-wboit.frag.ts deleted file mode 100644 index d797cf7aa81276f14345ef1022337dd733c4a1d0..0000000000000000000000000000000000000000 --- a/src/mol-gl/shader/evaluate-wboit.frag.ts +++ /dev/null @@ -1,17 +0,0 @@ -export default ` -precision highp float; - -uniform sampler2D tWboitA; -uniform sampler2D tWboitB; -uniform vec2 uTexSize; - -void main() { - vec2 coords = gl_FragCoord.xy / uTexSize; - - vec4 accum = texture2D(tWboitA, coords); - float r = 1.0 - accum.a; - - accum.a = texture2D(tWboitB, coords).r; - gl_FragColor = vec4(accum.rgb / clamp(accum.a, 0.0001, 50000.0), r); -} -`; \ No newline at end of file diff --git a/src/mol-gl/shader/image.frag.ts b/src/mol-gl/shader/image.frag.ts index 995f4797dc6ac124d7e82696b7e070a7d375d227..3b2e076d4d530c30b7ad7e16a8b4100e4f85ae4c 100644 --- a/src/mol-gl/shader/image.frag.ts +++ b/src/mol-gl/shader/image.frag.ts @@ -10,7 +10,6 @@ precision highp int; #include common #include read_from_texture #include common_frag_params -#include wboit_params uniform vec2 uImageTexDim; uniform sampler2D tImageTex; @@ -123,10 +122,6 @@ void main() { float vMarker = readFromTexture(tMarker, vInstance * float(uGroupCount) + group, uMarkerTexDim).a; #include apply_marker_color #include apply_fog - - float fragmentDepth = gl_FragCoord.z; - bool interior = false; - #include wboit_write #endif } `; \ No newline at end of file diff --git a/src/mol-gl/shader/lines.frag.ts b/src/mol-gl/shader/lines.frag.ts index e85fb79e6cc3e8c3c71740e28059ebc115311446..81c91489b990406d39ded0af995917f11098f6d0 100644 --- a/src/mol-gl/shader/lines.frag.ts +++ b/src/mol-gl/shader/lines.frag.ts @@ -12,7 +12,6 @@ precision highp int; #include common_frag_params #include color_frag_params #include common_clip -#include wboit_params void main(){ #include clip_pixel @@ -28,10 +27,6 @@ void main(){ #include apply_marker_color #include apply_fog - - float fragmentDepth = gl_FragCoord.z; - bool interior = false; - #include wboit_write #endif } `; \ No newline at end of file diff --git a/src/mol-gl/shader/mesh.frag.ts b/src/mol-gl/shader/mesh.frag.ts index 1884c5be13766e905138eba3779aaf1650c81dd8..0ed9f7ebe318da42c6fa91bea2d1d1199fa575c4 100644 --- a/src/mol-gl/shader/mesh.frag.ts +++ b/src/mol-gl/shader/mesh.frag.ts @@ -14,7 +14,6 @@ precision highp int; #include light_frag_params #include normal_frag_params #include common_clip -#include wboit_params void main() { #include clip_pixel @@ -60,9 +59,6 @@ void main() { #include apply_interior_color #include apply_marker_color #include apply_fog - - float fragmentDepth = gl_FragCoord.z; - #include wboit_write #endif } `; \ No newline at end of file diff --git a/src/mol-gl/shader/points.frag.ts b/src/mol-gl/shader/points.frag.ts index 9aefed044b946219f472c51510a7c113b9e97d89..e3e8fafb350afdfe991fafd83d8a651f05067d03 100644 --- a/src/mol-gl/shader/points.frag.ts +++ b/src/mol-gl/shader/points.frag.ts @@ -12,7 +12,6 @@ precision highp int; #include common_frag_params #include color_frag_params #include common_clip -#include wboit_params #ifdef dPointFilledCircle uniform float uPointEdgeBleach; @@ -42,10 +41,6 @@ void main(){ #include apply_marker_color #include apply_fog - - float fragmentDepth = gl_FragCoord.z; - bool interior = false; - #include wboit_write #endif } `; \ No newline at end of file diff --git a/src/mol-gl/shader/spheres.frag.ts b/src/mol-gl/shader/spheres.frag.ts index 39829d6c2e4b24ca0ff56cde9a493ef939407d79..de5731f3deaa07513cd6c1bf2666a7ede3bbe0de 100644 --- a/src/mol-gl/shader/spheres.frag.ts +++ b/src/mol-gl/shader/spheres.frag.ts @@ -13,7 +13,8 @@ precision highp int; #include color_frag_params #include light_frag_params #include common_clip -#include wboit_params + +uniform mat4 uProjection; uniform float uClipNear; uniform float uIsOrtho; @@ -26,6 +27,12 @@ varying vec3 vPointViewPosition; vec3 cameraPos; vec3 cameraNormal; +// Calculate depth based on the given camera position. +float calcDepth(const in vec3 cameraPos){ + vec2 clipZW = cameraPos.z * uProjection[2].zw + uProjection[3].zw; + return 0.5 + 0.5 * clipZW.x / clipZW.y; +} + float calcClip(const in vec3 cameraPos) { return dot(vec4(cameraPos, 1.0), vec4(0.0, 0.0, 1.0, uClipNear - 0.5)); } @@ -107,9 +114,6 @@ void main(void){ #include apply_interior_color #include apply_marker_color #include apply_fog - - float fragmentDepth = gl_FragDepthEXT; - #include wboit_write #endif } `; \ No newline at end of file diff --git a/src/mol-gl/shader/text.frag.ts b/src/mol-gl/shader/text.frag.ts index 5fb133bba9133f2c4b34587751b0ebe76658d2d3..c19dc7ab961ecb817f06175dc073cd16b91ff501 100644 --- a/src/mol-gl/shader/text.frag.ts +++ b/src/mol-gl/shader/text.frag.ts @@ -12,7 +12,6 @@ precision highp int; #include common_frag_params #include color_frag_params #include common_clip -#include wboit_params uniform sampler2D tFont; @@ -66,10 +65,6 @@ void main(){ #elif defined(dRenderVariant_color) #include apply_marker_color #include apply_fog - - float fragmentDepth = gl_FragCoord.z; - bool interior = false; - #include wboit_write #endif } `; \ No newline at end of file diff --git a/src/mol-gl/webgl/context.ts b/src/mol-gl/webgl/context.ts index 8823b75f35a3171fa9620eedf80cdac9e20503ee..e9303b859574b1cb6826032105360fe21aab5036 100644 --- a/src/mol-gl/webgl/context.ts +++ b/src/mol-gl/webgl/context.ts @@ -18,17 +18,15 @@ import { now } from '../../mol-util/now'; import { Texture, TextureFilter } from './texture'; import { ComputeRenderable } from '../renderable'; -export function getGLContext(canvas: HTMLCanvasElement, attribs?: WebGLContextAttributes): GLRenderingContext | null { - function get(id: 'webgl' | 'experimental-webgl' | 'webgl2') { +export function getGLContext(canvas: HTMLCanvasElement, contextAttributes?: WebGLContextAttributes): GLRenderingContext | null { + function getContext(contextId: 'webgl' | 'experimental-webgl' | 'webgl2') { try { - return canvas.getContext(id, attribs) as GLRenderingContext | null; + return canvas.getContext(contextId, contextAttributes) as GLRenderingContext | null; } catch (e) { return null; } } - const gl = get('webgl2') || get('webgl') || get('experimental-webgl'); - if (isDebugMode) console.log(`isWebgl2: ${isWebGL2(gl)}`); - return gl; + return getContext('webgl2') || getContext('webgl') || getContext('experimental-webgl'); } export function getErrorDescription(gl: GLRenderingContext, error: number) { @@ -188,7 +186,6 @@ export interface WebGLContext { readonly maxTextureSize: number readonly maxRenderbufferSize: number readonly maxDrawBuffers: number - readonly maxTextureImageUnits: number readonly isContextLost: boolean readonly contextRestored: BehaviorSubject<now.Timestamp> @@ -223,7 +220,6 @@ export function createContext(gl: GLRenderingContext, props: Partial<{ pixelScal maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE) as number, maxRenderbufferSize: gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) as number, maxDrawBuffers: isWebGL2(gl) ? gl.getParameter(gl.MAX_DRAW_BUFFERS) as number : 0, - maxTextureImageUnits: gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) as number, maxVertexTextureImageUnits: gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) as number, }; @@ -289,7 +285,6 @@ export function createContext(gl: GLRenderingContext, props: Partial<{ pixelScal get maxTextureSize () { return parameters.maxTextureSize; }, get maxRenderbufferSize () { return parameters.maxRenderbufferSize; }, get maxDrawBuffers () { return parameters.maxDrawBuffers; }, - get maxTextureImageUnits () { return parameters.maxTextureImageUnits; }, namedComputeRenderables: Object.create(null), namedFramebuffers: Object.create(null), diff --git a/src/mol-gl/webgl/extensions.ts b/src/mol-gl/webgl/extensions.ts index 712dddf18f56e222eb4e8c94724c8973fc2ea222..df056ddb8c64d5fc52a97b765c0d07e7f8cc3c19 100644 --- a/src/mol-gl/webgl/extensions.ts +++ b/src/mol-gl/webgl/extensions.ts @@ -42,6 +42,7 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions { } const textureFloat = getTextureFloat(gl); if (isDebugMode && textureFloat === null) { + // TODO make sure non-support is handled downstream console.log('Could not find support for "texture_float"'); } const textureFloatLinear = getTextureFloatLinear(gl); diff --git a/src/mol-gl/webgl/framebuffer.ts b/src/mol-gl/webgl/framebuffer.ts index 6122f79dec6d4566394ada40a32da15737898640..3f982cfa37d9917af86de6fe61da26c060a7398b 100644 --- a/src/mol-gl/webgl/framebuffer.ts +++ b/src/mol-gl/webgl/framebuffer.ts @@ -50,15 +50,15 @@ function getFramebuffer(gl: GLRenderingContext) { return framebuffer; } -export function createFramebuffer(gl: GLRenderingContext): Framebuffer { +export function createFramebuffer (gl: GLRenderingContext): Framebuffer { let _framebuffer = getFramebuffer(gl); let destroyed = false; return { id: getNextFramebufferId(), - bind: () => gl.bindFramebuffer(gl.FRAMEBUFFER, _framebuffer), + reset: () => { _framebuffer = getFramebuffer(gl); }, @@ -68,16 +68,4 @@ export function createFramebuffer(gl: GLRenderingContext): Framebuffer { destroyed = true; } }; -} - -// - -export function createNullFramebuffer(): Framebuffer { - return { - id: getNextFramebufferId(), - - bind: () => {}, - reset: () => {}, - destroy: () => {} - }; } \ No newline at end of file diff --git a/src/mol-gl/webgl/program.ts b/src/mol-gl/webgl/program.ts index fcf40dca8c20951fa830531758181285c44c0f57..065fed789c6e70607e8eef1cb5ae61bca8ccc638 100644 --- a/src/mol-gl/webgl/program.ts +++ b/src/mol-gl/webgl/program.ts @@ -24,7 +24,7 @@ export interface Program { use: () => void setUniforms: (uniformValues: UniformsList) => void bindAttributes: (attribueBuffers: AttributeBuffers) => void - bindTextures: (textures: Textures, startingTargetUnit?: number) => void + bindTextures: (textures: Textures) => void reset: () => void destroy: () => void @@ -198,15 +198,21 @@ export function createProgram(gl: GLRenderingContext, state: WebGLState, extensi if (l !== -1) buffer.bind(l); } }, - bindTextures: (textures: Textures, startingTargetUnit?: number) => { - startingTargetUnit = startingTargetUnit ?? 0; - + bindTextures: (textures: Textures) => { for (let i = 0, il = textures.length; i < il; ++i) { const [k, texture] = textures[i]; const l = locations[k]; if (l !== null && l !== undefined) { - texture.bind((i + startingTargetUnit) as TextureId); - uniformSetters[k](gl, l, (i + startingTargetUnit) as TextureId); + if (k === 'tDepth') { + // TODO find more explicit way? + texture.bind(15 as TextureId); + uniformSetters[k](gl, l, 15 as TextureId); + } else { + // TODO if the order and count of textures in a material can be made invariant + // bind needs to be called only when the material changes + texture.bind(i as TextureId); + uniformSetters[k](gl, l, i as TextureId); + } } } }, diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts index 02eb1c15e21387bfb592b8281416b6431374906a..88b9058212e518b9245354db4be0135eb128d7fb 100644 --- a/src/mol-gl/webgl/render-item.ts +++ b/src/mol-gl/webgl/render-item.ts @@ -5,7 +5,7 @@ */ import { createAttributeBuffers, ElementsBuffer, AttributeKind } from './buffer'; -import { createTextures, Texture, Textures } from './texture'; +import { createTextures, Texture } from './texture'; import { WebGLContext, checkError } from './context'; import { ShaderCode, DefineValues } from '../shader-code'; import { Program } from './program'; @@ -40,14 +40,14 @@ export interface RenderItem<T extends string> { readonly materialId: number getProgram: (variant: T) => Program - render: (variant: T, sharedTexturesList?: Textures) => void + render: (variant: T) => void update: () => Readonly<ValueChanges> destroy: () => void } // -const GraphicsRenderVariant = { 'colorBlended': '', 'colorWboit': '', 'pickObject': '', 'pickInstance': '', 'pickGroup': '', 'depth': '' }; +const GraphicsRenderVariant = { 'color': '', 'pickObject': '', 'pickInstance': '', 'pickGroup': '', 'depth': '' }; export type GraphicsRenderVariant = keyof typeof GraphicsRenderVariant const GraphicsRenderVariants = Object.keys(GraphicsRenderVariant) as GraphicsRenderVariant[]; @@ -164,17 +164,12 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: materialId, getProgram: (variant: T) => programs[variant], - render: (variant: T, sharedTexturesList?: Textures) => { + render: (variant: T) => { if (drawCount === 0 || instanceCount === 0 || ctx.isContextLost) return; const program = programs[variant]; if (program.id === currentProgramId && state.currentRenderItemId === id) { program.setUniforms(uniformValueEntries); - if (sharedTexturesList && sharedTexturesList.length > 0) { - program.bindTextures(sharedTexturesList, 0); - program.bindTextures(textures, sharedTexturesList.length); - } else { - program.bindTextures(textures); - } + program.bindTextures(textures); } else { const vertexArray = vertexArrays[variant]; if (program.id !== state.currentProgramId || program.id !== currentProgramId || @@ -187,12 +182,7 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: currentProgramId = program.id; } program.setUniforms(uniformValueEntries); - if (sharedTexturesList && sharedTexturesList.length > 0) { - program.bindTextures(sharedTexturesList, 0); - program.bindTextures(textures, sharedTexturesList.length); - } else { - program.bindTextures(textures); - } + program.bindTextures(textures); if (vertexArray) { vertexArray.bind(); // need to bind elements buffer explicitly since it is not always recorded in the VAO @@ -204,11 +194,7 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: state.currentRenderItemId = id; } if (isDebugMode) { - try { - checkFramebufferStatus(ctx.gl); - } catch (e) { - throw new Error(`Framebuffer error rendering item id ${id}: '${e}'`); - } + checkFramebufferStatus(ctx.gl); } if (elementsBuffer) { instancedArrays.drawElementsInstanced(glDrawMode, drawCount, elementsBuffer._dataType, 0, instanceCount); @@ -219,7 +205,7 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: try { checkError(ctx.gl); } catch (e) { - throw new Error(`Draw error rendering item id ${id}: '${e}'`); + throw new Error(`Error rendering item id ${id}: '${e}'`); } } }, diff --git a/src/mol-gl/webgl/render-target.ts b/src/mol-gl/webgl/render-target.ts index a2c9e751240726132b13d74f09ae2a978ef85756..232c0d9d5388da135c61b063ad3bc0c1b396e40c 100644 --- a/src/mol-gl/webgl/render-target.ts +++ b/src/mol-gl/webgl/render-target.ts @@ -5,8 +5,8 @@ */ import { idFactory } from '../../mol-util/id-factory'; -import { createNullTexture, Texture, TextureFilter } from './texture'; -import { createNullFramebuffer, Framebuffer } from './framebuffer'; +import { Texture, TextureFilter } from './texture'; +import { Framebuffer } from './framebuffer'; import { WebGLResources } from './resources'; import { GLRenderingContext } from './compat'; @@ -78,22 +78,3 @@ export function createRenderTarget(gl: GLRenderingContext, resources: WebGLResou } }; } - -// - -export function createNullRenderTarget(gl: GLRenderingContext): RenderTarget { - return { - id: getNextRenderTargetId(), - texture: createNullTexture(gl, 'image-uint8'), - framebuffer: createNullFramebuffer(), - - getWidth: () => 0, - getHeight: () => 0, - bind: () => { - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - }, - setSize: () => {}, - reset: () => {}, - destroy: () => {} - }; -} \ No newline at end of file diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts index 11eb2404657c148591954952e9145eaafc8824e0..3ccd3093cec7727c13e42966478edd75f2ba64a7 100644 --- a/src/mol-gl/webgl/texture.ts +++ b/src/mol-gl/webgl/texture.ts @@ -312,37 +312,4 @@ export function createTextures(ctx: WebGLContext, schema: RenderableSchema, valu } }); return textures; -} - -// - -export function createNullTexture(gl: GLRenderingContext, kind: TextureKind): Texture { - const target = getTarget(gl, kind); - return { - id: getNextTextureId(), - target, - format: 0, - internalFormat: 0, - type: 0, - - getWidth: () => 0, - getHeight: () => 0, - getDepth: () => 0, - - define: () => {}, - load: () => {}, - bind: (id: TextureId) => { - gl.activeTexture(gl.TEXTURE0 + id); - gl.bindTexture(target, null); - }, - unbind: (id: TextureId) => { - gl.activeTexture(gl.TEXTURE0 + id); - gl.bindTexture(target, null); - }, - attachFramebuffer: () => {}, - detachFramebuffer: () => {}, - - reset: () => {}, - destroy: () => {}, - }; } \ No newline at end of file diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts index 7e1fe21903acabf281d7db848a160f3738e20917..181fb35a92dc64dd2a5f74992af1bb04c25c1d76 100644 --- a/src/mol-math/geometry/gaussian-density/gpu.ts +++ b/src/mol-math/geometry/gaussian-density/gpu.ts @@ -119,7 +119,7 @@ type GaussianDensityTextureData = { function calcGaussianDensityTexture2d(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, texture?: Texture): GaussianDensityTextureData { // console.log('2d'); - const { gl, resources, state, extensions: { colorBufferFloat, textureFloat } } = webgl; + const { gl, resources, state, extensions } = webgl; const { smoothness, resolution } = props; const { drawCount, positions, radii, groups, scale, expandedBox, dim, maxRadius } = prepareGaussianDensityData(position, box, radius, props); @@ -143,7 +143,7 @@ function calcGaussianDensityTexture2d(webgl: WebGLContext, position: PositionDat framebuffer.bind(); setRenderingDefaults(webgl); - if (!texture) texture = colorBufferFloat && textureFloat + if (!texture) texture = extensions.colorBufferFloat ? resources.texture('image-float32', 'rgba', 'float', 'linear') : resources.texture('image-uint8', 'rgba', 'ubyte', 'linear'); texture.define(texDimX, texDimY); @@ -191,7 +191,7 @@ function calcGaussianDensityTexture2d(webgl: WebGLContext, position: PositionDat function calcGaussianDensityTexture3d(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, texture?: Texture): GaussianDensityTextureData { // console.log('3d'); - const { gl, resources, state, extensions: { colorBufferFloat, textureFloat } } = webgl; + const { gl, resources, state, extensions } = webgl; const { smoothness, resolution } = props; const { drawCount, positions, radii, groups, scale, expandedBox, dim, maxRadius } = prepareGaussianDensityData(position, box, radius, props); @@ -214,7 +214,7 @@ function calcGaussianDensityTexture3d(webgl: WebGLContext, position: PositionDat setRenderingDefaults(webgl); gl.viewport(0, 0, dx, dy); - if (!texture) texture = colorBufferFloat && textureFloat + if (!texture) texture = extensions.colorBufferFloat ? resources.texture('volume-float32', 'rgba', 'float', 'linear') : resources.texture('volume-uint8', 'rgba', 'ubyte', 'linear'); texture.define(dx, dy, dz); diff --git a/src/mol-plugin/config.ts b/src/mol-plugin/config.ts index 914bea78158d6c9a21ec23e2504a577ab511f26d..b70604b4c8eb8220543461524ab3b6312befe048 100644 --- a/src/mol-plugin/config.ts +++ b/src/mol-plugin/config.ts @@ -24,8 +24,7 @@ export const PluginConfig = { General: { IsBusyTimeoutMs: item('plugin-config.is-busy-timeout', 750), DisableAntialiasing: item('plugin-config.disable-antialiasing', false), - PixelScale: item('plugin-config.pixel-scale', 1), - EnableWboit: item('plugin-config.enable-wboit', false) + PixelScale: item('plugin-config.pixel-scale', 1) }, State: { DefaultServer: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state'), diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts index e534bc50a8f043b612d027e6291c186ebf446833..13c17aa4ad906ba368aefc24a9938f1184150013 100644 --- a/src/mol-plugin/context.ts +++ b/src/mol-plugin/context.ts @@ -190,8 +190,7 @@ export class PluginContext { const antialias = !(this.config.get(PluginConfig.General.DisableAntialiasing) ?? false); const pixelScale = this.config.get(PluginConfig.General.PixelScale) || 1; - const enableWboit = this.config.get(PluginConfig.General.EnableWboit) || false; - (this.canvas3d as Canvas3D) = Canvas3D.fromCanvas(canvas, {}, { antialias, pixelScale, enableWboit }); + (this.canvas3d as Canvas3D) = Canvas3D.fromCanvas(canvas, {}, { antialias, pixelScale }); this.canvas3dInit.next(true); let props = this.spec.components?.viewport?.canvas3d; diff --git a/src/mol-plugin/util/viewport-screenshot.ts b/src/mol-plugin/util/viewport-screenshot.ts index 625dc61f696936fa4c21dac5ddad82817d585bbe..7d1818660c7bb49a85e342b07132617989b633ce 100644 --- a/src/mol-plugin/util/viewport-screenshot.ts +++ b/src/mol-plugin/util/viewport-screenshot.ts @@ -107,13 +107,12 @@ class ViewportScreenshotHelper extends PluginComponent { private createPass(mutlisample: boolean) { const c = this.plugin.canvas3d!; - const { colorBufferFloat, textureFloat } = c.webgl.extensions; return this.plugin.canvas3d!.getImagePass({ transparentBackground: this.values.transparent, cameraHelper: { axes: this.values.axes }, multiSample: { mode: mutlisample ? 'on' : 'off', - sampleLevel: colorBufferFloat && textureFloat ? 4 : 2 + sampleLevel: c.webgl.extensions.colorBufferFloat ? 4 : 2 }, postprocessing: c.props.postprocessing }); diff --git a/src/mol-repr/visual.ts b/src/mol-repr/visual.ts index 7b1651ac030b62e40f525085faeae432bc58d275..b163b9f3ba811ec4e237c8dacc43fd4d6632f4dd 100644 --- a/src/mol-repr/visual.ts +++ b/src/mol-repr/visual.ts @@ -20,7 +20,7 @@ import { Overpaint } from '../mol-theme/overpaint'; import { createOverpaint, clearOverpaint, applyOverpaintColor } from '../mol-geo/geometry/overpaint-data'; import { Interval } from '../mol-data/int'; import { Transparency } from '../mol-theme/transparency'; -import { createTransparency, clearTransparency, applyTransparencyValue, getTransparencyAverage } from '../mol-geo/geometry/transparency-data'; +import { createTransparency, clearTransparency, applyTransparencyValue } from '../mol-geo/geometry/transparency-data'; import { Clipping } from '../mol-theme/clipping'; import { createClipping, applyClippingGroups, clearClipping } from '../mol-geo/geometry/clipping-data'; @@ -114,7 +114,7 @@ namespace Visual { export function setTransparency(renderObject: GraphicsRenderObject | undefined, transparency: Transparency, lociApply: LociApply, clear: boolean) { if (!renderObject) return; - const { tTransparency, transparencyAverage, uGroupCount, instanceCount } = renderObject.values; + const { tTransparency, uGroupCount, instanceCount } = renderObject.values; const count = uGroupCount.ref.value * instanceCount.ref.value; // ensure texture has right size and variant @@ -134,7 +134,6 @@ namespace Visual { lociApply(loci, apply, false); } ValueCell.update(tTransparency, tTransparency.ref.value); - ValueCell.updateIfChanged(transparencyAverage, getTransparencyAverage(array, count)); } export function setClipping(renderObject: GraphicsRenderObject | undefined, clipping: Clipping, lociApply: LociApply, clear: boolean) { diff --git a/src/mol-util/array.ts b/src/mol-util/array.ts index 7a3931e568551c19c646423a467b7fe1dc7ca5b6..16b1ded0ab0905bab17f89e2b2c6b297c557cdc3 100644 --- a/src/mol-util/array.ts +++ b/src/mol-util/array.ts @@ -122,14 +122,4 @@ export function arrayIsIdentity(xs: ArrayLike<number>) { if (xs[i] !== i) return false; } return true; -} - -export function arrayMapUpsert<T>(xs: [string, T][], key: string, value: T) { - for (let i = 0, il = xs.length; i < il; ++i) { - if (xs[i][0] === key) { - xs[i][1] = value; - return; - } - } - xs.push([key, value]); -} +} \ No newline at end of file