From 3ea3fb898459628d0e9cadc2d5c473cb412cc7b1 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Wed, 9 Oct 2019 16:07:04 -0700 Subject: [PATCH] support rendering with transparent background --- src/mol-canvas3d/canvas3d.ts | 5 +++-- src/mol-gl/renderable/schema.ts | 1 + src/mol-gl/renderer.ts | 12 +++++++++--- src/mol-gl/shader/chunks/apply-fog.glsl.ts | 11 ++++++----- src/mol-gl/shader/chunks/common-frag-params.glsl.ts | 1 + src/mol-plugin/skin/base/components/viewport.scss | 8 ++++++++ 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 0950c4ced..75e995aac 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -93,10 +93,11 @@ namespace Canvas3D { export function fromCanvas(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}, runTask = DefaultRunTask) { const gl = getGLContext(canvas, { - alpha: false, + alpha: true, antialias: true, depth: true, - preserveDrawingBuffer: true + preserveDrawingBuffer: true, + premultipliedAlpha: false, }) if (gl === null) throw new Error('Could not create a WebGL rendering context') const input = InputObserver.fromElement(canvas) diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index da4a273a9..24ab5c36d 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -168,6 +168,7 @@ export const GlobalUniformSchema = { uFogFar: UniformSpec('f'), uFogColor: UniformSpec('v3'), + uTransparentBackground: UniformSpec('i'), uPickingAlphaThreshold: UniformSpec('f'), uInteriorDarkening: UniformSpec('f'), } diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index a4ba67c88..db06d23bd 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -46,6 +46,7 @@ interface Renderer { export const RendererParams = { backgroundColor: PD.Color(Color(0x000000), { description: 'Background color of the 3D canvas' }), + transparentBackground: PD.Boolean(false, { description: 'Background opacity of the 3D canvas' }), pickingAlphaThreshold: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }, { description: 'The minimum opacity value needed for an object to be pickable.' }), interiorDarkening: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }), @@ -107,6 +108,7 @@ namespace Renderer { uFogFar: ValueCell.create(camera.fogFar), uFogColor: ValueCell.create(bgColor), + uTransparentBackground: ValueCell.create(p.transparentBackground ? 1 : 0), uPickingAlphaThreshold: ValueCell.create(p.pickingAlphaThreshold), uInteriorDarkening: ValueCell.create(p.interiorDarkening), } @@ -191,7 +193,7 @@ namespace Renderer { if (clear) { if (variant === 'color') { - state.clearColor(bgColor[0], bgColor[1], bgColor[2], 1.0) + state.clearColor(bgColor[0], bgColor[1], bgColor[2], p.transparentBackground ? 0 : 1) } else { state.clearColor(1, 1, 1, 1) } @@ -204,7 +206,7 @@ namespace Renderer { if (r.state.opaque) renderObject(r, variant) } - state.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + 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] @@ -224,7 +226,7 @@ namespace Renderer { clear: () => { state.depthMask(true) state.colorMask(true, true, true, true) - state.clearColor(bgColor[0], bgColor[1], bgColor[2], 1.0) + state.clearColor(bgColor[0], bgColor[1], bgColor[2], p.transparentBackground ? 0 : 1) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) }, render, @@ -243,6 +245,10 @@ namespace Renderer { Color.toVec3Normalized(bgColor, p.backgroundColor) ValueCell.update(globalUniforms.uFogColor, Vec3.copy(globalUniforms.uFogColor.ref.value, bgColor)) } + if (props.transparentBackground !== undefined && props.transparentBackground !== p.transparentBackground) { + p.transparentBackground = props.transparentBackground + ValueCell.update(globalUniforms.uTransparentBackground, p.transparentBackground ? 1 : 0) + } if (props.lightIntensity !== undefined && props.lightIntensity !== p.lightIntensity) { p.lightIntensity = props.lightIntensity ValueCell.update(globalUniforms.uLightIntensity, p.lightIntensity) diff --git a/src/mol-gl/shader/chunks/apply-fog.glsl.ts b/src/mol-gl/shader/chunks/apply-fog.glsl.ts index d7308351b..2bfd2cd87 100644 --- a/src/mol-gl/shader/chunks/apply-fog.glsl.ts +++ b/src/mol-gl/shader/chunks/apply-fog.glsl.ts @@ -2,10 +2,11 @@ export default ` #ifdef dUseFog float depth = length(vViewPosition); float fogFactor = smoothstep(uFogNear, uFogFar, depth); - gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor); - float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a; - if (fogAlpha < 0.01) - discard; - gl_FragColor = vec4(gl_FragColor.rgb, fogAlpha); + if (uTransparentBackground == 0) { + gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor); + } else { + float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a; + gl_FragColor.a = fogAlpha; + } #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 6ee029edb..28d04173c 100644 --- a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts +++ b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts @@ -22,6 +22,7 @@ uniform vec3 uFogColor; uniform float uAlpha; uniform float uPickingAlphaThreshold; uniform int uPickable; +uniform int uTransparentBackground; uniform float uInteriorDarkening; ` \ No newline at end of file diff --git a/src/mol-plugin/skin/base/components/viewport.scss b/src/mol-plugin/skin/base/components/viewport.scss index b77e628d4..54472ba0c 100644 --- a/src/mol-plugin/skin/base/components/viewport.scss +++ b/src/mol-plugin/skin/base/components/viewport.scss @@ -27,6 +27,14 @@ -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-touch-callout: none; touch-action: manipulation; + + > canvas { + background-color: $default-background; + background-image: linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey), + linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey); + background-size: 60px 60px; + background-position: 0 0, 30px 30px; + } } .msp-viewport-controls { -- GitLab