diff --git a/src/apps/render-test/state.ts b/src/apps/render-test/state.ts
index bb22845aa08610aba040d98747a1638d647c93af..f25b0cd1fd489d2d1b3552b5c4d79456bfd059c6 100644
--- a/src/apps/render-test/state.ts
+++ b/src/apps/render-test/state.ts
@@ -40,8 +40,8 @@ export type ColorTheme = keyof typeof ColorTheme
 
 export default class State {
     viewer: Viewer
-    pdbId = ''
-    emdId = '8689'
+    pdbId = '5ire'
+    emdId = '8116'
     model = new BehaviorSubject<Model | undefined>(undefined)
     volume = new BehaviorSubject<Volume | undefined>(undefined)
     initialized = new BehaviorSubject<boolean>(false)
@@ -115,7 +115,8 @@ export default class State {
         const { viewer } = this
         if (!viewer || !this.model.getValue()) return
 
-        viewer.clear()
+        if (this.pointRepr) this.viewer.remove(this.pointRepr)
+        if (this.spacefillRepr) this.viewer.remove(this.spacefillRepr)
 
         const structure = await this.getStructure()
         if (!structure) return
@@ -150,7 +151,7 @@ export default class State {
         const v = this.volume.getValue()
         if (!viewer || !v) return
 
-        viewer.clear()
+        if (this.surfaceRepr) this.viewer.remove(this.surfaceRepr)
 
         this.surfaceRepr = VolumeRepresentation(Surface)
         await Run(this.surfaceRepr.create(v.volume, { isoValue: VolumeIsoValue.relative(v.volume.dataStats, 1.5) }), log, 500)
@@ -161,7 +162,8 @@ export default class State {
     }
 
     async loadPdbId () {
-        this.viewer.clear()
+        if (this.pointRepr) this.viewer.remove(this.pointRepr)
+        if (this.spacefillRepr) this.viewer.remove(this.spacefillRepr)
         if (this.pdbId.length !== 4) return
         this.loading.next(true)
         this.setModel((await getModelFromPdbId(this.pdbId))[0])
@@ -174,7 +176,7 @@ export default class State {
     }
 
     async loadEmdId () {
-        this.viewer.clear()
+        if (this.surfaceRepr) this.viewer.remove(this.surfaceRepr)
         if (this.emdId.length !== 4) return
         this.loading.next(true)
         this.setVolume(await getVolumeFromEmdId(this.emdId))
diff --git a/src/mol-geo/representation/structure/point.ts b/src/mol-geo/representation/structure/point.ts
index 8a9d28fa61298d8e752ad4997772254052d4e42a..5b567b3690edc44332e491ef1cc7fe16942146fd 100644
--- a/src/mol-geo/representation/structure/point.ts
+++ b/src/mol-geo/representation/structure/point.ts
@@ -19,7 +19,8 @@ import { deepEqual } from 'mol-util';
 
 export const DefaultPointProps = {
     colorTheme: { name: 'instance-index' } as ColorTheme,
-    sizeTheme: { name: 'vdw' } as SizeTheme
+    sizeTheme: { name: 'vdw' } as SizeTheme,
+    alpha: 1
 }
 export type PointProps = Partial<typeof DefaultPointProps>
 
@@ -59,7 +60,7 @@ export default function Point(): UnitsRepresentation<PointProps> {
                 _units = units
                 _elementGroup = elementGroup
 
-                const { colorTheme, sizeTheme } = curProps
+                const { colorTheme, sizeTheme, alpha } = curProps
                 const elementCount = OrderedSet.size(elementGroup.elements)
                 const unitCount = units.length
 
@@ -84,6 +85,7 @@ export default function Point(): UnitsRepresentation<PointProps> {
 
                 points = createPointRenderObject({
                     objectId: 0,
+                    alpha,
 
                     position: ValueCell.create(vertices),
                     id: ValueCell.create(fillSerial(new Float32Array(elementCount))),
diff --git a/src/mol-geo/representation/structure/spacefill.ts b/src/mol-geo/representation/structure/spacefill.ts
index 1362927bf4597208785b9337dcea83df5d1cb419..a4b2c485182b94c3697c1ea67d06efaaa969f457 100644
--- a/src/mol-geo/representation/structure/spacefill.ts
+++ b/src/mol-geo/representation/structure/spacefill.ts
@@ -23,6 +23,7 @@ import { icosahedronVertexCount } from '../../primitive/icosahedron';
 export const DefaultSpacefillProps = {
     detail: 0,
     colorTheme: { name: 'instance-index' } as ColorTheme,
+    alpha: 1
 }
 export type SpacefillProps = Partial<typeof DefaultSpacefillProps>
 
@@ -78,7 +79,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
             return Task.create('Spacefill.create', async ctx => {
                 renderObjects.length = 0 // clear
 
-                const { detail, colorTheme } = { ...DefaultSpacefillProps, ...props }
+                const { detail, colorTheme, alpha } = { ...DefaultSpacefillProps, ...props }
 
                 await ctx.update('Computing spacefill mesh');
                 const mesh = await ctx.runChild(createSpacefillMesh(units[0], elementGroup, detail))
@@ -94,6 +95,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
 
                 spheres = createMeshRenderObject({
                     objectId: 0,
+                    alpha,
 
                     position: mesh.vertexBuffer,
                     normal: mesh.normalBuffer as ValueCell<Float32Array>,
diff --git a/src/mol-geo/representation/volume/surface.ts b/src/mol-geo/representation/volume/surface.ts
index 2298ed467b8e21682453973db92b5b8fda68eaff..fd22678fe086cd1068ab90e03f9dd0657a0bd77c 100644
--- a/src/mol-geo/representation/volume/surface.ts
+++ b/src/mol-geo/representation/volume/surface.ts
@@ -34,7 +34,8 @@ export function computeVolumeSurface(volume: VolumeData, isoValue: VolumeIsoValu
 }
 
 export const DefaultSurfaceProps = {
-    isoValue: VolumeIsoValue.relative({ min: 0, max: 0, mean: 0, sigma: 0 }, 0)
+    isoValue: VolumeIsoValue.relative({ min: 0, max: 0, mean: 0, sigma: 0 }, 0),
+    alpha: 0.5
 }
 export type SurfaceProps = Partial<typeof DefaultSurfaceProps>
 
@@ -49,11 +50,13 @@ export default function Surface(): VolumeElementRepresentation<SurfaceProps> {
             return Task.create('Point.create', async ctx => {
                 renderObjects.length = 0 // clear
                 curProps = { ...DefaultSurfaceProps, ...props }
+                const { alpha } = curProps
 
                 const mesh = await ctx.runChild(computeVolumeSurface(volume, curProps.isoValue))
 
                 surface = createMeshRenderObject({
                     objectId: 0,
+                    alpha,
 
                     position: mesh.vertexBuffer,
                     normal: mesh.normalBuffer,
diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts
index 7465af899e56b57f7f1f8dfe29a1a58feb7886f0..ff80f1218f50efd3be9b7b0de4c3f63c9e87152a 100644
--- a/src/mol-gl/_spec/renderer.spec.ts
+++ b/src/mol-gl/_spec/renderer.spec.ts
@@ -50,6 +50,7 @@ function createPoints() {
 
     return createPointRenderObject({
         objectId: 0,
+        alpha: 1.0,
 
         position,
         id,
diff --git a/src/mol-gl/renderable/mesh.ts b/src/mol-gl/renderable/mesh.ts
index 38d202788c73b83452392fe1bbef57b71f39bacc..7aa2a1eb67715ed4735c5b4a3ac7bc53c6a95c2d 100644
--- a/src/mol-gl/renderable/mesh.ts
+++ b/src/mol-gl/renderable/mesh.ts
@@ -18,6 +18,7 @@ type Mesh = 'mesh'
 namespace Mesh {
     export type Props = {
         objectId: number
+        alpha: number
 
         position: ValueCell<Float32Array>
         normal: ValueCell<Float32Array | undefined>
diff --git a/src/mol-gl/renderable/point.ts b/src/mol-gl/renderable/point.ts
index 7ff653779138a7afd7275f48bc2e0df0143c255a..f0d4b78e0c605432bef6083095c2a251c4d4052f 100644
--- a/src/mol-gl/renderable/point.ts
+++ b/src/mol-gl/renderable/point.ts
@@ -19,6 +19,7 @@ type Point = 'point'
 namespace Point {
     export type Props = {
         objectId: number
+        alpha: number
 
         position: ValueCell<Float32Array>
         id: ValueCell<Float32Array>
diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts
index 59caeafaa2676dc4dd6403b4c0686e23255ad905..87504a7db07493a68c15c6503588c0c8fea63493 100644
--- a/src/mol-gl/renderable/util.ts
+++ b/src/mol-gl/renderable/util.ts
@@ -65,6 +65,7 @@ interface BaseProps {
     instanceCount: number,
     elementCount: number,
     positionCount: number,
+    alpha: number,
 
     position: ValueCell<Float32Array>
     normal?: ValueCell<Float32Array | undefined>
@@ -87,6 +88,7 @@ export function getBaseUniformDefs(props: BaseProps) {
         // light_position: 'v3',
         light_color: 'v3',
         light_ambient: 'v3',
+        alpha: 'f',
 
         objectId: 'i',
         instanceCount: 'i',
@@ -107,9 +109,9 @@ export function getBaseUniformDefs(props: BaseProps) {
 }
 
 export function getBaseUniformValues(props: BaseProps) {
-    const { objectId, instanceCount, elementCount } = props
+    const { objectId, instanceCount, elementCount, alpha } = props
     const uniformValues: UniformValues = {
-        objectId, instanceCount, elementCount
+        objectId, instanceCount, elementCount, alpha
     }
     const color = props.color
     if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts
index 8fe4c2707afacaaf4762aa3cd6a2c227a1c51b0b..aea1cc8386a8f994b9f69f2beec6e3c8c6fd4b5b 100644
--- a/src/mol-gl/renderer.ts
+++ b/src/mol-gl/renderer.ts
@@ -11,6 +11,8 @@ import { Camera } from 'mol-view/camera/base';
 import Scene, { RenderObject } from './scene';
 import { Context } from './webgl/context';
 import { Mat4, Vec3 } from 'mol-math/linear-algebra';
+import { Renderable } from './renderable';
+import { Color } from 'mol-util/color';
 
 export interface RendererStats {
     renderableCount: number
@@ -29,6 +31,7 @@ interface Renderer {
     draw: () => void
 
     setViewport: (viewport: Viewport) => void
+    setClearColor: (color: Color) => void
 
     stats: RendererStats
     dispose: () => void
@@ -38,47 +41,69 @@ function getPixelRatio() {
     return (typeof window !== 'undefined') ? window.devicePixelRatio : 1
 }
 
+export const DefaultRendererProps = {
+    clearColor: 0x000000 as Color,
+    viewport: Viewport.create(0, 0, 0, 0)
+}
+export type RendererProps = Partial<typeof DefaultRendererProps>
+
 namespace Renderer {
-    export function create(ctx: Context, camera: Camera): Renderer {
+    export function create(ctx: Context, camera: Camera, props: RendererProps = {}): Renderer {
         const { gl } = ctx
+        let { clearColor, viewport: _viewport } = { ...DefaultRendererProps, ...props }
         const scene = Scene.create(ctx)
 
         const model = Mat4.identity()
-        const viewport = Viewport.create(0, 0, 0, 0)
+        const viewport = Viewport.clone(_viewport)
         const pixelRatio = getPixelRatio()
 
         // const light_position = Vec3.create(0, 0, -100)
         const light_color = Vec3.create(1.0, 1.0, 1.0)
         const light_ambient = Vec3.create(0.5, 0.5, 0.5)
 
+        function setClearColor(color: Color) {
+            const [ r, g, b ] = Color.toRgbNormalized(color)
+            gl.clearColor(r, g, b, 1.0)
+        }
+        setClearColor(clearColor)
+
+        let currentProgramId = -1
+        const drawObject = (r: Renderable<any>, o: RenderObject) => {
+            if (o.visible) {
+                if (currentProgramId !== r.program.id) {
+                    r.program.use()
+                    r.program.setUniforms({
+                        model,
+                        view: camera.view,
+                        projection: camera.projection,
+
+                        pixelRatio,
+                        viewportHeight: viewport.height,
+
+                        // light_position,
+                        light_color,
+                        light_ambient,
+                    })
+                    currentProgramId = r.program.id
+                }
+                r.draw()
+            }
+        }
+
         const draw = () => {
-            // TODO clear color
+            currentProgramId = -1
+
+            gl.depthMask(true)
             gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
+
+            gl.disable(gl.BLEND)
             gl.enable(gl.DEPTH_TEST)
+            scene.eachOpaque(drawObject)
 
-            // TODO painters sort, filter visible, filter picking, visibility culling?
-            let currentProgramId = -1
-            scene.forEach((r, o) => {
-                if (o.visible) {
-                    if (currentProgramId !== r.program.id) {
-                        r.program.use()
-                        r.program.setUniforms({
-                            model,
-                            view: camera.view,
-                            projection: camera.projection,
-
-                            pixelRatio,
-                            viewportHeight: viewport.height,
-
-                            // light_position,
-                            light_color,
-                            light_ambient,
-                        })
-                        currentProgramId = r.program.id
-                    }
-                    r.draw()
-                }
-            })
+            gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
+            gl.enable(gl.BLEND)
+            gl.depthMask(false)
+            scene.eachTransparent(drawObject)
         }
 
         return {
@@ -95,10 +120,13 @@ namespace Renderer {
                 scene.clear()
             },
             draw,
+
+            setClearColor,
             setViewport: (newViewport: Viewport) => {
                 Viewport.copy(viewport, newViewport)
                 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height)
             },
+
             get stats(): RendererStats {
                 return {
                     renderableCount: scene.count,
diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts
index 92faf5e27e14031434515bb3706acdad921d3d5d..28789540a70daf65c75a0b7e14bbc44561637c07 100644
--- a/src/mol-gl/scene.ts
+++ b/src/mol-gl/scene.ts
@@ -16,16 +16,16 @@ function getNextId() {
 
 export type RenderData = { [k: string]: ValueCell<Helpers.TypedArray> }
 
-export interface BaseRenderObject { id: number, type: string, props: {}, visible: boolean }
+export interface BaseRenderObject { id: number, type: string, props: {}, visible: boolean, transparent: boolean }
 export interface MeshRenderObject extends BaseRenderObject { type: 'mesh', props: MeshRenderable.Props }
 export interface PointRenderObject extends BaseRenderObject { type: 'point', props: PointRenderable.Props }
 export type RenderObject = MeshRenderObject | PointRenderObject
 
 export function createMeshRenderObject(props: MeshRenderable.Props): MeshRenderObject {
-    return { id: getNextId(), type: 'mesh', props, visible: true }
+    return { id: getNextId(), type: 'mesh', props, visible: true, transparent: props.alpha < 1 }
 }
 export function createPointRenderObject(props: PointRenderable.Props): PointRenderObject {
-    return { id: getNextId(), type: 'point', props, visible: true }
+    return { id: getNextId(), type: 'point', props, visible: true, transparent: props.alpha < 1 }
 }
 
 export function createRenderable(ctx: Context, o: RenderObject) {
@@ -40,6 +40,8 @@ interface Scene {
     remove: (o: RenderObject) => void
     clear: () => void
     forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
+    eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
+    eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
     count: number
 }
 
@@ -69,6 +71,16 @@ namespace Scene {
             forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
                 renderableMap.forEach(callbackFn)
             },
+            eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
+                renderableMap.forEach((r, o) => {
+                    if (!o.transparent) callbackFn(r, o)
+                })
+            },
+            eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
+                renderableMap.forEach((r, o) => {
+                    if (o.transparent) callbackFn(r, o)
+                })
+            },
             get count() {
                 return renderableMap.size
             }
diff --git a/src/mol-gl/shader/mesh.frag b/src/mol-gl/shader/mesh.frag
index 89191d411a5b4691d4eea3e058d25aa9c5534150..088812ec63079cf1aa1f9ef504fa090bc705f0a3 100644
--- a/src/mol-gl/shader/mesh.frag
+++ b/src/mol-gl/shader/mesh.frag
@@ -14,6 +14,7 @@ precision highp float;
 uniform vec3 light_color;
 uniform vec3 light_ambient;
 uniform mat4 view;
+uniform float alpha;
 
 #ifndef FLAT_SHADED
     varying vec3 vNormal;
@@ -47,7 +48,7 @@ void main() {
     #ifdef FLAT_SHADED
         vec3 fdx = dFdx(vViewPosition);
         vec3 fdy = dFdy(vViewPosition);
-        vec3 N = -normalize(cross(fdx, fdy));
+        vec3 N = normalize(cross(fdx, fdy));
     #else
         vec3 N = -normalize(vNormal);
         #ifdef DOUBLE_SIDED
@@ -66,5 +67,5 @@ void main() {
     // gl_FragColor.rgb = N;
     // gl_FragColor.rgb = vec3(1.0, 0.0, 0.0);
     gl_FragColor.rgb = finalColor;
-    gl_FragColor.a = 1.0;
+    gl_FragColor.a = alpha;
 }
\ No newline at end of file
diff --git a/src/mol-gl/shader/point.frag b/src/mol-gl/shader/point.frag
index 7afba8f5e1baf326d903e6f898495ca201ef52fd..a39cf8d9866968633113ac50252b91cc2cfcc67e 100644
--- a/src/mol-gl/shader/point.frag
+++ b/src/mol-gl/shader/point.frag
@@ -6,9 +6,11 @@
 
 precision highp float;
 
+uniform float alpha;
+
 #pragma glslify: import('./chunks/color-frag-params.glsl')
 
 void main(){
     #pragma glslify: import('./chunks/color-assign-material.glsl')
-    gl_FragColor = vec4(material, 1.0);
+    gl_FragColor = vec4(material, alpha);
 }
\ No newline at end of file
diff --git a/src/mol-view/viewer.ts b/src/mol-view/viewer.ts
index 22169186d2e350fae3ae7d181d53b95e189f329e..48ff8e3d4bcbdc838f932feed804449c6cd22b66 100644
--- a/src/mol-view/viewer.ts
+++ b/src/mol-view/viewer.ts
@@ -64,7 +64,12 @@ namespace Viewer {
 
         })
 
-        const gl = getWebGLContext(canvas)
+        const gl = getWebGLContext(canvas, {
+            alpha: true,
+            antialias: true,
+            depth: true,
+            preserveDrawingBuffer: true
+        })
         if (gl === null) {
             throw new Error('Could not create a WebGL rendering context')
         }