diff --git a/src/mol-app/ui/transform/spacefill.tsx b/src/mol-app/ui/transform/spacefill.tsx index 1f20a340a0027c61ba7a1f703dc0f1cf34615072..0c102bc10480479bb35dfeb89eb1b94e71f223da 100644 --- a/src/mol-app/ui/transform/spacefill.tsx +++ b/src/mol-app/ui/transform/spacefill.tsx @@ -51,7 +51,6 @@ export class Spacefill extends View<Controller<any>, SpacefillState, { transform update(state?: Partial<SpacefillState>) { const { transform, entity, ctx } = this.props - console.log('update spacefill', transform, entity) const newState = { ...this.state, ...state } this.setState(newState) transform.apply(ctx, entity, newState) diff --git a/src/mol-gl/renderable/mesh.ts b/src/mol-gl/renderable/mesh.ts index 71ddafacecf8bb7affb5f2eba98debb8d004a066..0fb0305dcb660be25b2c8539e196fef27edb547c 100644 --- a/src/mol-gl/renderable/mesh.ts +++ b/src/mol-gl/renderable/mesh.ts @@ -8,10 +8,11 @@ import { ValueCell } from 'mol-util/value-cell' import { ColorData } from 'mol-geo/util/color-data'; import { Renderable, BaseProps } from '../renderable' -import { getBaseDefs, getBaseValues, getBaseDefines } from './util' +import { getBaseDefs, getBaseValues, getBaseDefines, updateBaseValues } from './util' import { MeshShaderCode, addShaderDefines } from '../shader-code' import { Context } from '../webgl/context'; import { createRenderItem, RenderItemProps, RenderItemState } from '../webgl/render-item'; +import { deepEqual } from 'mol-util'; type Mesh = 'mesh' @@ -31,7 +32,7 @@ namespace Mesh { positionCount: number } & BaseProps - export function create(ctx: Context, props: Props): Renderable<Props> { + function getDefs(props: Props) { const defines = getBaseDefines(props) if (props.flatShaded) defines.FLAT_SHADED = '' if (props.doubleSided) defines.DOUBLE_SIDED = '' @@ -43,15 +44,34 @@ namespace Mesh { drawMode: 'triangles', elementsKind: 'uint32' } - const values: RenderItemState = { + return defs + } + + function getVals(props: Props) { + const vals: RenderItemState = { ...getBaseValues(props), - drawCount: props.indexCount * 3, - instanceCount: props.instanceCount, + drawCount: ValueCell.create(props.indexCount * 3), + instanceCount: ValueCell.create(props.instanceCount), elements: props.index.ref.value } + return vals + } - let renderItem = createRenderItem(ctx, defs, values) - // let curProps = props + function updateVals(vals: RenderItemState, props: Props) { + updateBaseValues(vals, props) + if (props.instanceCount !== vals.instanceCount.ref.value) { + ValueCell.update(vals.instanceCount, props.instanceCount) + } + const drawCount = props.indexCount * 3 + if (drawCount !== vals.drawCount.ref.value) { + ValueCell.update(vals.drawCount, drawCount) + } + } + + export function create(ctx: Context, props: Props): Renderable<Props> { + let curDefs = getDefs(props) + let curVals = getVals(props) + let renderItem = createRenderItem(ctx, curDefs, curVals) return { draw: () => { @@ -60,7 +80,17 @@ namespace Mesh { name: 'mesh', get program () { return renderItem.program }, update: (newProps: Props) => { - console.log('Updating mesh renderable') + const newDefs = getDefs(props) + if (deepEqual(curDefs, newDefs)) { + updateVals(curVals, props) + renderItem.update() + } else { + console.log('mesh defs changed, destroy and rebuild render-item') + renderItem.destroy() + curVals = getVals(props) + curDefs = newDefs + renderItem = createRenderItem(ctx, curDefs, curVals) + } }, dispose: () => { renderItem.destroy() diff --git a/src/mol-gl/renderable/point.ts b/src/mol-gl/renderable/point.ts index 83b206dde577e0aad08a15f3b735334bfd9e7b4a..32d2c14ae0de5185eb270e1f85142d1a4e28fb47 100644 --- a/src/mol-gl/renderable/point.ts +++ b/src/mol-gl/renderable/point.ts @@ -32,7 +32,7 @@ namespace Point { usePointSizeAttenuation?: boolean } & BaseProps - export function create<T = Props>(ctx: Context, props: Props): Renderable<Props> { + function getDefs(props: Props) { const defines = getBaseDefines(props) if (props.usePointSizeAttenuation) defines.POINT_SIZE_ATTENUATION = '' @@ -41,13 +41,28 @@ namespace Point { shaderCode: addShaderDefines(defines, PointShaderCode), drawMode: 'points' } - const values: RenderItemState = { + return defs + } + + function getVals(props: Props) { + const vals: RenderItemState = { ...getBaseValues(props), - drawCount: props.positionCount, - instanceCount: props.instanceCount + drawCount: ValueCell.create(props.positionCount), + instanceCount: ValueCell.create(props.instanceCount) } + return vals + } - let renderItem = createRenderItem(ctx, defs, values) + function getRenderItem(ctx: Context, props: Props) { + const defs = getDefs(props) + const vals = getVals(props) + return createRenderItem(ctx, defs, vals) + } + + export function create<T = Props>(ctx: Context, props: Props): Renderable<Props> { + // const defs = getDefs(props) + + let renderItem = getRenderItem(ctx, props) // let curProps = props return { @@ -58,6 +73,8 @@ namespace Point { get program () { return renderItem.program }, update: (newProps: Props) => { console.log('Updating point renderable') + renderItem.destroy() + renderItem = getRenderItem(ctx, { ...props, ...newProps }) }, dispose: () => { renderItem.destroy() diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts index 87504a7db07493a68c15c6503588c0c8fea63493..47f8c70d9aae556159f3b3452c09709f9374fbaa 100644 --- a/src/mol-gl/renderable/util.ts +++ b/src/mol-gl/renderable/util.ts @@ -85,9 +85,9 @@ export function getBaseUniformDefs(props: BaseProps) { pixelRatio: 'f', viewportHeight: 'f', - // light_position: 'v3', - light_color: 'v3', - light_ambient: 'v3', + // lightPosition: 'v3', + lightColor: 'v3', + lightAmbient: 'v3', alpha: 'f', objectId: 'i', @@ -96,7 +96,6 @@ export function getBaseUniformDefs(props: BaseProps) { } const color = props.color if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') { - // uniformDefs.colorTex = 't2' uniformDefs.colorTexSize = 'v2' } else if (color.type === 'uniform') { uniformDefs.color = 'v3' @@ -111,19 +110,21 @@ export function getBaseUniformDefs(props: BaseProps) { export function getBaseUniformValues(props: BaseProps) { const { objectId, instanceCount, elementCount, alpha } = props const uniformValues: UniformValues = { - objectId, instanceCount, elementCount, alpha + objectId: ValueCell.create(objectId), + instanceCount: ValueCell.create(instanceCount), + elementCount: ValueCell.create(elementCount), + alpha: ValueCell.create(alpha) } const color = props.color if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') { const { width, height } = color.data.ref.value - // uniformValues.colorTex = color.value.ref.value.array - uniformValues.colorTexSize = Vec2.create(width, height) + uniformValues.colorTexSize = ValueCell.create(Vec2.create(width, height)) } else if (color.type === 'uniform') { - uniformValues.color = color.data as Vec3 + uniformValues.color = ValueCell.create(color.data as Vec3) } const size = props.size if (size && size.type === 'uniform') { - uniformValues.size = size.value + uniformValues.size = ValueCell.create(size.value) } return uniformValues } @@ -212,3 +213,31 @@ export function getBaseValues(props: BaseProps) { textureValues: getBaseTextureValues(props), } } + +export interface BaseValues { + uniformValues: UniformValues + attributeValues: AttributeValues + textureValues: TextureValues +} + +export function updateBaseValues(vals: BaseValues, props: BaseProps) { + ValueCell.update(vals.uniformValues.objectId, props.objectId) + ValueCell.update(vals.uniformValues.instanceCount, props.instanceCount) + ValueCell.update(vals.uniformValues.elementCount, props.elementCount) + ValueCell.update(vals.uniformValues.alpha, props.alpha) + + const color = props.color + if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') { + const { width, height } = color.data.ref.value + ValueCell.update( + vals.uniformValues.colorTexSize, + Vec2.set(vals.uniformValues.colorTexSize.ref.value as Vec2, width, height) + ) + } else if (color.type === 'uniform') { + ValueCell.update(vals.uniformValues.color, color.data as Vec3) + } + const size = props.size + if (size && size.type === 'uniform') { + ValueCell.update(vals.uniformValues.size, size.value) + } +} diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 69de95fac41565873e79e852f7fdb9b7245925a3..29d78e7c32026ca595864719df049504996d8a30 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -13,6 +13,7 @@ import { Context } from './webgl/context'; import { Mat4, Vec3 } from 'mol-math/linear-algebra'; import { Renderable } from './renderable'; import { Color } from 'mol-util/color'; +import { ValueCell } from 'mol-util'; export interface RendererStats { renderableCount: number @@ -57,9 +58,9 @@ namespace Renderer { 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) + // const lightPosition = Vec3.create(0, 0, -100) + const lightColor = Vec3.create(1.0, 1.0, 1.0) + const lightAmbient = Vec3.create(0.5, 0.5, 0.5) function setClearColor(color: Color) { const [ r, g, b ] = Color.toRgbNormalized(color) @@ -67,23 +68,24 @@ namespace Renderer { } setClearColor(clearColor) + const baseUniforms = { + model: ValueCell.create(Mat4.clone(model)), + view: ValueCell.create(Mat4.clone(camera.view)), + projection: ValueCell.create(Mat4.clone(camera.projection)), + + pixelRatio: ValueCell.create(pixelRatio), + viewportHeight: ValueCell.create(viewport.height), + + lightColor: ValueCell.create(Vec3.clone(lightColor)), + lightAmbient: ValueCell.create(Vec3.clone(lightAmbient)) + } + let currentProgramId = -1 const drawObject = (r: Renderable<any>, o: RenderObject) => { if (o.props.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, - }) + r.program.setUniforms(baseUniforms) currentProgramId = r.program.id } if (o.props.doubleSided) { @@ -107,6 +109,9 @@ namespace Renderer { } const draw = () => { + ValueCell.update(baseUniforms.view, camera.view) + ValueCell.update(baseUniforms.projection, camera.projection) + currentProgramId = -1 gl.depthMask(true) @@ -129,7 +134,7 @@ namespace Renderer { scene.remove(o) }, update: () => { - scene.forEach((r, o) => r.update(o)) + scene.forEach((r, o) => r.update(o.props)) }, clear: () => { scene.clear() @@ -140,6 +145,7 @@ namespace Renderer { setViewport: (newViewport: Viewport) => { Viewport.copy(viewport, newViewport) gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height) + ValueCell.update(baseUniforms.viewportHeight, viewport.height) }, get stats(): RendererStats { diff --git a/src/mol-gl/shader/mesh.frag b/src/mol-gl/shader/mesh.frag index 9b4fb18cfbb799bfd4a0a9c794c041bb8a5824b4..10aa715aca5fe7208ffd998473062a94828b8d67 100644 --- a/src/mol-gl/shader/mesh.frag +++ b/src/mol-gl/shader/mesh.frag @@ -10,9 +10,9 @@ precision highp float; -// uniform vec3 light_position; -uniform vec3 light_color; -uniform vec3 light_ambient; +// uniform vec3 lightPosition; +uniform vec3 lightColor; +uniform vec3 lightAmbient; uniform mat4 view; uniform float alpha; @@ -37,8 +37,8 @@ void main() { #pragma glslify: import('./chunks/color-assign-material.glsl') // determine surface to light direction - // vec4 lightPosition = view * vec4(light_position, 1.0); - // vec3 lightVector = lightPosition.xyz - vViewPosition; + // vec4 viewLightPosition = view * vec4(lightPosition, 1.0); + // vec3 lightVector = viewLightPosition.xyz - vViewPosition; vec3 lightVector = vViewPosition; vec3 L = normalize(lightVector); // light direction @@ -58,8 +58,8 @@ void main() { // compute our diffuse & specular terms float specular = calculateSpecular(L, V, N, shininess) * specularScale; - vec3 diffuse = light_color * calculateDiffuse(L, V, N, roughness, albedo); - vec3 ambient = light_ambient; + vec3 diffuse = lightColor * calculateDiffuse(L, V, N, roughness, albedo); + vec3 ambient = lightAmbient; // add the lighting vec3 finalColor = material * (diffuse + ambient) + specular; diff --git a/src/mol-gl/webgl/buffer.ts b/src/mol-gl/webgl/buffer.ts index 0e79d368c5dd6ef03f3efb98ff399a0e1848d417..8615c3e4050e23a990404059048642877d0e24c8 100644 --- a/src/mol-gl/webgl/buffer.ts +++ b/src/mol-gl/webgl/buffer.ts @@ -82,6 +82,10 @@ export interface Buffer { readonly _dataType: number readonly _bpe: number + readonly itemSize: number + readonly itemCount: number + readonly length: number + updateData: (array: ArrayType) => void updateSubData: (array: ArrayType, offset: number, count: number) => void destroy: () => void @@ -98,6 +102,8 @@ export function createBuffer(ctx: Context, array: ArrayType, itemSize: BufferIte const _bufferType = getBufferType(ctx, bufferType) const _dataType = dataTypeFromArray(ctx, array) const _bpe = array.BYTES_PER_ELEMENT + const _length = array.length + const _itemCount = Math.floor(_length / itemSize) function updateData(array: ArrayType) { gl.bindBuffer(_bufferType, _buffer) @@ -115,6 +121,10 @@ export function createBuffer(ctx: Context, array: ArrayType, itemSize: BufferIte _dataType, _bpe, + get itemSize () { return itemSize }, + get itemCount () { return _itemCount }, + get length () { return _length }, + updateData, updateSubData: (array: ArrayType, offset: number, count: number) => { gl.bindBuffer(_bufferType, _buffer) diff --git a/src/mol-gl/webgl/program.ts b/src/mol-gl/webgl/program.ts index 29f6d293bb7665083ef78a9f934a231d6ced81fe..b2e22acacb9b199dc16dcae2bdea0c26955e4d17 100644 --- a/src/mol-gl/webgl/program.ts +++ b/src/mol-gl/webgl/program.ts @@ -6,7 +6,7 @@ import { ShaderCode } from '../shader-code' import { Context } from './context'; -import { getUniformSetters, UniformDefs, UniformValues } from './uniform'; +import { getUniformUpdaters, UniformDefs, UniformValues } from './uniform'; import {AttributeDefs, AttributeBuffers } from './buffer'; import { TextureId, TextureDefs, TextureUniformDefs, Textures } from './texture'; import { createReferenceCache, ReferenceCache } from 'mol-util/reference-cache'; @@ -70,10 +70,10 @@ export function createProgram(ctx: Context, props: ProgramProps): Program { fragShaderRef.value.attach(program) gl.linkProgram(program) - const uniformSetters = getUniformSetters(ctx, program, uniformDefs) + const uniformUpdaters = getUniformUpdaters(ctx, program, uniformDefs) const attributeLocations = getAttributeLocations(ctx, program, attributeDefs) const textureUniformDefs = getTextureUniformDefs(textureDefs) - const textureUniformSetters = getUniformSetters(ctx, program, textureUniformDefs) + const textureUniformUpdaters = getUniformUpdaters(ctx, program, textureUniformDefs) let destroyed = false @@ -81,12 +81,14 @@ export function createProgram(ctx: Context, props: ProgramProps): Program { id: getNextProgramId(), use: () => { + Object.keys(uniformDefs).forEach(k => uniformUpdaters[k].clear()) + Object.keys(textureUniformDefs).forEach(k => textureUniformUpdaters[k].clear()) gl.useProgram(program) }, setUniforms: (uniformValues: UniformValues) => { Object.keys(uniformValues).forEach(k => { - const value = uniformValues[k] - if (value !== undefined) uniformSetters[k](value) + const uv = uniformValues[k] + if (uv !== undefined) uniformUpdaters[k].set(uv.ref.value, uv.ref.version) }) }, bindAttributes: (attribueBuffers: AttributeBuffers) => { @@ -98,7 +100,7 @@ export function createProgram(ctx: Context, props: ProgramProps): Program { bindTextures: (textures: Textures) => { Object.keys(textures).forEach((k, i) => { textures[k].bind(i as TextureId) - textureUniformSetters[k](i) + textureUniformUpdaters[k].set(i, i) }) }, diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts index 82868a3899a152bb2f475220695bbc815f58e6ce..5cadef952f3c7de463276d919b688612655a2381 100644 --- a/src/mol-gl/webgl/render-item.ts +++ b/src/mol-gl/webgl/render-item.ts @@ -10,6 +10,7 @@ import { TextureDefs, TextureValues, createTextures } from './texture'; import { Context } from './context'; import { ShaderCode } from '../shader-code'; import { Program } from './program'; +import { ValueCell } from 'mol-util'; export type DrawMode = 'points' | 'lines' | 'line-strip' | 'line-loop' | 'triangles' | 'triangle-strip' | 'triangle-fan' @@ -43,8 +44,8 @@ export type RenderItemState = { textureValues: TextureValues elements?: Uint32Array - drawCount: number - instanceCount: number + drawCount: ValueCell<number> + instanceCount: ValueCell<number> } export interface RenderItem { @@ -52,8 +53,7 @@ export interface RenderItem { readonly programId: number readonly program: Program - update: (state: RenderItemState) => void - + update: () => void draw: () => void destroy: () => void } @@ -90,7 +90,9 @@ export function createRenderItem(ctx: Context, props: RenderItemProps, state: Re oesVertexArrayObject.bindVertexArrayOES(null!) } - let { drawCount, instanceCount } = state + let drawCount = state.drawCount.ref + let instanceCount = state.instanceCount.ref + let destroyed = false return { @@ -108,18 +110,32 @@ export function createRenderItem(ctx: Context, props: RenderItemProps, state: Re } program.bindTextures(textures) if (elementsBuffer) { - angleInstancedArrays.drawElementsInstancedANGLE(drawMode, drawCount, elementsBuffer._dataType, 0, instanceCount); + angleInstancedArrays.drawElementsInstancedANGLE(drawMode, drawCount.value, elementsBuffer._dataType, 0, instanceCount.value); } else { - angleInstancedArrays.drawArraysInstancedANGLE(drawMode, 0, drawCount, instanceCount) + angleInstancedArrays.drawArraysInstancedANGLE(drawMode, 0, drawCount.value, instanceCount.value) } }, - update: (state: RenderItemState) => { - // TODO - const { attributeValues } = state - Object.keys(attributeValues).forEach(k => { - const value = attributeValues[k] - if (value !== undefined) attributeBuffers[k].updateData(value) - }) + update: () => { + if (state.drawCount.ref.version !== drawCount.version) { + console.log('drawCount version changed') + drawCount = state.drawCount.ref + } + if (state.instanceCount.ref.version !== instanceCount.version) { + console.log('instanceCount version changed') + instanceCount = state.instanceCount.ref + } + + // const { attributeValues } = state + // Object.keys(attributeValues).forEach(k => { + // const value = attributeValues[k] + // if (value === undefined) return + // const buffer = attributeBuffers[k] + // if (buffer.length >= value.length) { + // attributeBuffers[k].updateData(value) + // } else { + + // } + // }) }, destroy: () => { if (destroyed) return diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts index 6f86b433e3034686c99a5fbd281ae4eb9ffb5ff0..2f4deb411e1bb8c9ca6d5dc2f0462244ff3cfd5d 100644 --- a/src/mol-gl/webgl/texture.ts +++ b/src/mol-gl/webgl/texture.ts @@ -71,7 +71,7 @@ export function createTexture(ctx: Context): Texture { export function createTextures(ctx: Context, props: TextureDefs, state: TextureValues) { const textures: Textures = {} - Object.keys(props).forEach(k => { + Object.keys(props).forEach((k, i) => { const texture = createTexture(ctx) texture.load(state[k]) textures[k] = texture diff --git a/src/mol-gl/webgl/uniform.ts b/src/mol-gl/webgl/uniform.ts index 73b6d2d3808f1eb5b1a8a39a8ac3d8d341b71555..bc3a4c019d2288bbf50f089f654a0bff2b62f3f7 100644 --- a/src/mol-gl/webgl/uniform.ts +++ b/src/mol-gl/webgl/uniform.ts @@ -7,6 +7,7 @@ import { Mat3, Mat4, Vec2, Vec3, Vec4 } from 'mol-math/linear-algebra' import { Context } from './context'; import { TextureImage } from '../renderable/util'; +import { ValueCell } from 'mol-util'; export type UniformKindValue = { 'f': number @@ -20,10 +21,14 @@ export type UniformKindValue = { } export type UniformKind = keyof UniformKindValue export type UniformType = number | Vec2 | Vec3 | Vec4 | Mat3 | Mat4 | TextureImage +export interface UniformUpdater { + set: (value: UniformType, version: number) => void, + clear: () => void +} export type UniformDefs = { [k: string]: UniformKind } -export type UniformValues = { [k: string]: UniformType } -export type UniformSetters = { [k: string]: (value: UniformType) => void } +export type UniformValues = { [k: string]: ValueCell<UniformType> } +export type UniformUpdaters = { [k: string]: UniformUpdater } export function createUniformSetter(ctx: Context, program: WebGLProgram, name: string, kind: UniformKind): (value: any) => void { const { gl } = ctx @@ -42,10 +47,22 @@ export function createUniformSetter(ctx: Context, program: WebGLProgram, name: s } } -export function getUniformSetters(ctx: Context, program: WebGLProgram, uniforms: UniformDefs) { - const setters: UniformSetters = {} +export function getUniformUpdaters(ctx: Context, program: WebGLProgram, uniforms: UniformDefs) { + const updaters: UniformUpdaters = {} Object.keys(uniforms).forEach(k => { - setters[k] = createUniformSetter(ctx, program, k, uniforms[k]) + const setter = createUniformSetter(ctx, program, k, uniforms[k]) + let _version = -1 + updaters[k] = { + set: (value, version) => { + if (_version !== version) { + setter(value) + _version = version + } + }, + clear: () => { + _version = -1 + } + } }) - return setters + return updaters } \ No newline at end of file diff --git a/src/mol-view/state/transform.ts b/src/mol-view/state/transform.ts index 1009263491692e195d9000bae5746faada62324f..322cba3ebd7f958655dbe3349f684bab6a45bb1d 100644 --- a/src/mol-view/state/transform.ts +++ b/src/mol-view/state/transform.ts @@ -80,7 +80,6 @@ export const ModelToStructure: ModelToStructure = StateTransform.create('model', } else { structure = Structure.ofModel(model) } - console.log('center', structure.boundary.sphere.center) return StructureEntity.ofStructure(ctx, structure) }) @@ -98,7 +97,6 @@ export const StructureToSpacefill: StructureToSpacefill = StateTransform.create( await spacefillRepr.create(structureEntity.value, props).run(ctx.log) ctx.viewer.add(spacefillRepr) ctx.viewer.requestDraw() - console.log(ctx.viewer.stats, props) // ctx.viewer.input.drag.subscribe(async () => { // console.log('drag') // console.time('spacefill update') @@ -119,7 +117,7 @@ export const SpacefillUpdate: SpacefillUpdate = StateTransform.create('spacefill ctx.viewer.add(spacefillRepr) ctx.viewer.update() ctx.viewer.requestDraw() - console.log(ctx.viewer.stats, props) + // console.log(ctx.viewer.stats, props) return NullEntity }) diff --git a/src/mol-view/viewer.ts b/src/mol-view/viewer.ts index c39a142a748b1b478023ffb7287cbe6941eabb88..3b5055e7b133aa48ae7884f5c3747860755246be 100644 --- a/src/mol-view/viewer.ts +++ b/src/mol-view/viewer.ts @@ -133,6 +133,7 @@ namespace Viewer { if (oldRO) { SetUtils.difference(newRO, oldRO).forEach(o => renderer.add(o)) SetUtils.difference(oldRO, newRO).forEach(o => renderer.remove(o)) + renderer.update() } else { repr.renderObjects.forEach(o => renderer.add(o)) }