Skip to content
Snippets Groups Projects
Commit 3ea3fb89 authored by Alexander Rose's avatar Alexander Rose
Browse files

support rendering with transparent background

parent b4bbc544
No related branches found
No related tags found
No related merge requests found
...@@ -93,10 +93,11 @@ namespace Canvas3D { ...@@ -93,10 +93,11 @@ namespace Canvas3D {
export function fromCanvas(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}, runTask = DefaultRunTask) { export function fromCanvas(canvas: HTMLCanvasElement, props: Partial<Canvas3DProps> = {}, runTask = DefaultRunTask) {
const gl = getGLContext(canvas, { const gl = getGLContext(canvas, {
alpha: false, alpha: true,
antialias: true, antialias: true,
depth: true, depth: true,
preserveDrawingBuffer: true preserveDrawingBuffer: true,
premultipliedAlpha: false,
}) })
if (gl === null) throw new Error('Could not create a WebGL rendering context') if (gl === null) throw new Error('Could not create a WebGL rendering context')
const input = InputObserver.fromElement(canvas) const input = InputObserver.fromElement(canvas)
......
...@@ -168,6 +168,7 @@ export const GlobalUniformSchema = { ...@@ -168,6 +168,7 @@ export const GlobalUniformSchema = {
uFogFar: UniformSpec('f'), uFogFar: UniformSpec('f'),
uFogColor: UniformSpec('v3'), uFogColor: UniformSpec('v3'),
uTransparentBackground: UniformSpec('i'),
uPickingAlphaThreshold: UniformSpec('f'), uPickingAlphaThreshold: UniformSpec('f'),
uInteriorDarkening: UniformSpec('f'), uInteriorDarkening: UniformSpec('f'),
} }
......
...@@ -46,6 +46,7 @@ interface Renderer { ...@@ -46,6 +46,7 @@ interface Renderer {
export const RendererParams = { export const RendererParams = {
backgroundColor: PD.Color(Color(0x000000), { description: 'Background color of the 3D canvas' }), 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.' }), 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 }), interiorDarkening: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }),
...@@ -107,6 +108,7 @@ namespace Renderer { ...@@ -107,6 +108,7 @@ namespace Renderer {
uFogFar: ValueCell.create(camera.fogFar), uFogFar: ValueCell.create(camera.fogFar),
uFogColor: ValueCell.create(bgColor), uFogColor: ValueCell.create(bgColor),
uTransparentBackground: ValueCell.create(p.transparentBackground ? 1 : 0),
uPickingAlphaThreshold: ValueCell.create(p.pickingAlphaThreshold), uPickingAlphaThreshold: ValueCell.create(p.pickingAlphaThreshold),
uInteriorDarkening: ValueCell.create(p.interiorDarkening), uInteriorDarkening: ValueCell.create(p.interiorDarkening),
} }
...@@ -191,7 +193,7 @@ namespace Renderer { ...@@ -191,7 +193,7 @@ namespace Renderer {
if (clear) { if (clear) {
if (variant === 'color') { 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 { } else {
state.clearColor(1, 1, 1, 1) state.clearColor(1, 1, 1, 1)
} }
...@@ -204,7 +206,7 @@ namespace Renderer { ...@@ -204,7 +206,7 @@ namespace Renderer {
if (r.state.opaque) renderObject(r, variant) 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) state.enable(gl.BLEND)
for (let i = 0, il = renderables.length; i < il; ++i) { for (let i = 0, il = renderables.length; i < il; ++i) {
const r = renderables[i] const r = renderables[i]
...@@ -224,7 +226,7 @@ namespace Renderer { ...@@ -224,7 +226,7 @@ namespace Renderer {
clear: () => { clear: () => {
state.depthMask(true) state.depthMask(true)
state.colorMask(true, true, true, 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) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
}, },
render, render,
...@@ -243,6 +245,10 @@ namespace Renderer { ...@@ -243,6 +245,10 @@ namespace Renderer {
Color.toVec3Normalized(bgColor, p.backgroundColor) Color.toVec3Normalized(bgColor, p.backgroundColor)
ValueCell.update(globalUniforms.uFogColor, Vec3.copy(globalUniforms.uFogColor.ref.value, bgColor)) 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) { if (props.lightIntensity !== undefined && props.lightIntensity !== p.lightIntensity) {
p.lightIntensity = props.lightIntensity p.lightIntensity = props.lightIntensity
ValueCell.update(globalUniforms.uLightIntensity, p.lightIntensity) ValueCell.update(globalUniforms.uLightIntensity, p.lightIntensity)
......
...@@ -2,10 +2,11 @@ export default ` ...@@ -2,10 +2,11 @@ export default `
#ifdef dUseFog #ifdef dUseFog
float depth = length(vViewPosition); float depth = length(vViewPosition);
float fogFactor = smoothstep(uFogNear, uFogFar, depth); float fogFactor = smoothstep(uFogNear, uFogFar, depth);
gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor); if (uTransparentBackground == 0) {
float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a; gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor);
if (fogAlpha < 0.01) } else {
discard; float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a;
gl_FragColor = vec4(gl_FragColor.rgb, fogAlpha); gl_FragColor.a = fogAlpha;
}
#endif #endif
` `
\ No newline at end of file
...@@ -22,6 +22,7 @@ uniform vec3 uFogColor; ...@@ -22,6 +22,7 @@ uniform vec3 uFogColor;
uniform float uAlpha; uniform float uAlpha;
uniform float uPickingAlphaThreshold; uniform float uPickingAlphaThreshold;
uniform int uPickable; uniform int uPickable;
uniform int uTransparentBackground;
uniform float uInteriorDarkening; uniform float uInteriorDarkening;
` `
\ No newline at end of file
...@@ -27,6 +27,14 @@ ...@@ -27,6 +27,14 @@
-webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-touch-callout: none; -webkit-touch-callout: none;
touch-action: manipulation; 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 { .msp-viewport-controls {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment