diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index 616c6b8b920a4b37c326837d7f3eb2080ba91b18..0e351df9be98e967c356ba89f564dddd94dea14d 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -29,16 +29,19 @@ import { Camera } from './camera'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { BoundingSphereHelper } from './helper/bounding-sphere-helper'; -export const Canvas3DParams: PD.Params = { +export const Canvas3DParams = { // TODO: FPS cap? // maxFps: PD.Numeric(30), - cameraPosition: PD.Vec3(Vec3.create(0, 0, 50)), // TODO or should it be in a seperate 'state' property? - 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.' }), - backgroundColor: PD.Color(Color(0x000000)), cameraMode: PD.Select('perspective', [['perspective', 'Perspective'], ['orthographic', 'Orthographic']]), - showBoundingSpheres: PD.Boolean(true, { description: 'Show bounding spheres of render objects.' }), + backgroundColor: PD.Color(Color(0x000000)), + clipNear: PD.Numeric(1, { min: 1, max: 100, step: 1 }), + clipFar: PD.Numeric(100, { min: 1, max: 100, step: 1 }), + fogNear: PD.Numeric(50, { min: 1, max: 100, step: 1 }), + fogFar: PD.Numeric(100, { min: 1, max: 100, step: 1 }), + 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.' }), + showBoundingSpheres: PD.Boolean(false, { description: 'Show bounding spheres of render objects.' }), // debug: PD.Group({ - // showBoundingSpheres: PD.Boolean(true, { description: 'Show bounding spheres of render objects.' }), + // showBoundingSpheres: PD.Boolean(false, { description: 'Show bounding spheres of render objects.' }), // }) } export type Canvas3DParams = typeof Canvas3DParams @@ -96,7 +99,7 @@ namespace Canvas3D { const camera = new Camera({ near: 0.1, far: 10000, - position: Vec3.clone(p.cameraPosition), + position: Vec3.create(0, 0, 10), mode: p.cameraMode }) @@ -158,38 +161,33 @@ namespace Canvas3D { } } - // let nearPlaneDelta = 0 - // function computeNearDistance() { - // const focusRadius = scene.boundingSphere.radius - // let dist = Vec3.distance(controls.target, camera.position) - // if (dist > focusRadius) return dist - focusRadius - // return 0 - // } - - function render(variant: RenderVariant, force: boolean) { - if (isPicking) return false - // const p = scene.boundingSphere.center - // console.log(p[0], p[1], p[2]) - // Vec3.set(controls.target, p[0], p[1], p[2]) + let currentNear = -1, currentFar = -1, currentFogNear = -1, currentFogFar = -1 + function setClipping() { + const cDist = Vec3.distance(camera.state.position, camera.state.target) + const bRadius = Math.max(10, scene.boundingSphere.radius) - // TODO update near/far - // const focusRadius = scene.boundingSphere.radius - // const targetDistance = Vec3.distance(controls.target, camera.position) - // console.log(targetDistance, controls.target, camera.position) - // let near = computeNearDistance() + nearPlaneDelta - // camera.near = Math.max(0.01, Math.min(near, targetDistance - 0.5)) + const nearFactor = (50 - p.clipNear) / 50 + const farFactor = -(50 - p.clipFar) / 50 + const near = cDist - (bRadius * nearFactor) + const far = cDist + (bRadius * farFactor) - // let fogNear = targetDistance - camera.near + 1 * focusRadius - nearPlaneDelta; - // let fogFar = targetDistance - camera.near + 2 * focusRadius - nearPlaneDelta; + const fogNearFactor = (50 - p.fogNear) / 50 + const fogFarFactor = -(50 - p.fogFar) / 50 + const fogNear = cDist - (bRadius * fogNearFactor) + const fogFar = cDist + (bRadius * fogFarFactor) - // // console.log(fogNear, fogFar); - // camera.fogNear = Math.max(fogNear, 0.1); - // camera.fogFar = Math.max(fogFar, 0.2); + if (near !== currentNear || far !== currentFar || fogNear !== currentFogNear || fogFar !== currentFogFar) { + camera.setState({ near, far, fogNear, fogFar }) + currentNear = near, currentFar = far, currentFogNear = fogNear, currentFogFar = fogFar + } + } - // console.log(camera.fogNear, camera.fogFar, targetDistance) + function render(variant: RenderVariant, force: boolean) { + if (isPicking) return false let didRender = false controls.update() + setClipping() const cameraChanged = camera.updateMatrices(); if (force || cameraChanged) { @@ -334,6 +332,7 @@ namespace Canvas3D { reprCount.next(reprRenderObjects.size) boundingSphereHelper.update() scene.update() + requestDraw(true) } }, update: () => scene.update(), @@ -375,6 +374,12 @@ namespace Canvas3D { if (props.backgroundColor !== undefined && props.backgroundColor !== renderer.props.clearColor) { renderer.setClearColor(props.backgroundColor) } + + if (props.clipNear !== undefined) p.clipNear = props.clipNear + if (props.clipFar !== undefined) p.clipFar = props.clipFar + if (props.fogNear !== undefined) p.fogNear = props.fogNear + if (props.fogFar !== undefined) p.fogFar = props.fogFar + if (props.pickingAlphaThreshold !== undefined && props.pickingAlphaThreshold !== renderer.props.pickingAlphaThreshold) { renderer.setPickingAlphaThreshold(props.pickingAlphaThreshold) } @@ -386,9 +391,12 @@ namespace Canvas3D { get props() { return { - cameraPosition: Vec3.clone(camera.position), cameraMode: camera.state.mode, backgroundColor: renderer.props.clearColor, + clipNear: p.clipNear, + clipFar: p.clipFar, + fogNear: p.fogNear, + fogFar: p.fogFar, pickingAlphaThreshold: renderer.props.pickingAlphaThreshold, showBoundingSpheres: boundingSphereHelper.visible } diff --git a/src/mol-canvas3d/helper/bounding-sphere-helper.ts b/src/mol-canvas3d/helper/bounding-sphere-helper.ts index 2b7d436163bfc667393fefee0d54f69b0f2288f3..b3fbe849e241cb242e2f2bce4104626b945ebbe3 100644 --- a/src/mol-canvas3d/helper/bounding-sphere-helper.ts +++ b/src/mol-canvas3d/helper/bounding-sphere-helper.ts @@ -19,7 +19,7 @@ export class BoundingSphereHelper { constructor(private scene: Scene, visible: boolean) { const builder = MeshBuilder.create(1024, 512) this.mesh = builder.getMesh() - const values = Mesh.createValuesSimple(this.mesh, { alpha: 0.1 }) + const values = Mesh.createValuesSimple(this.mesh, { alpha: 0.1, doubleSided: false }) this.renderObject = createMeshRenderObject(values, { visible, pickable: false }) scene.add(this.renderObject) } diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index 7612971c9e9bfefc131ccdbb96b469e5443be470..eee463dc14c00e604f72104a60cf03db947ca103 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -62,7 +62,7 @@ export namespace Geometry { export const Params = { alpha: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }, { label: 'Opacity' }), - useFog: PD.Boolean(false), + useFog: PD.Boolean(true), highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)), selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)), diff --git a/src/mol-geo/geometry/mesh/mesh.ts b/src/mol-geo/geometry/mesh/mesh.ts index d3c44ab60da06e52cdb463a40b5ff7b38850a3bb..6d4b450d479f5acff8c5a717ba0ee71603c3a8e7 100644 --- a/src/mol-geo/geometry/mesh/mesh.ts +++ b/src/mol-geo/geometry/mesh/mesh.ts @@ -343,7 +343,7 @@ export namespace Mesh { export const Params = { ...Geometry.Params, - doubleSided: PD.Boolean(false), + doubleSided: PD.Boolean(true), flipSided: PD.Boolean(false), flatShaded: PD.Boolean(false), } diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index aee976db3e33be8abc9e4b4a9a5c9866590a8ab3..039ef5be8604b599269f7276ee7f6f7581c7c2b7 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -68,6 +68,7 @@ namespace Renderer { clearColor = color const [ r, g, b ] = Color.toRgbNormalized(color) gl.clearColor(r, g, b, 1.0) + Vec3.set(fogColor, r, g, b) } setClearColor(clearColor) @@ -94,12 +95,12 @@ namespace Renderer { uViewportHeight: ValueCell.create(viewport.height), uViewport: ValueCell.create(viewportVec4), - uLightColor: ValueCell.create(Vec3.clone(lightColor)), - uLightAmbient: ValueCell.create(Vec3.clone(lightAmbient)), + uLightColor: ValueCell.create(lightColor), + uLightAmbient: ValueCell.create(lightAmbient), - uFogNear: ValueCell.create(camera.state.near), - uFogFar: ValueCell.create(camera.state.far / 50), - uFogColor: ValueCell.create(Vec3.clone(fogColor)), + uFogNear: ValueCell.create(camera.state.fogNear), + uFogFar: ValueCell.create(camera.state.fogFar), + uFogColor: ValueCell.create(fogColor), uPickingAlphaThreshold: ValueCell.create(pickingAlphaThreshold), } diff --git a/src/mol-gl/shader/chunks/apply-fog.glsl b/src/mol-gl/shader/chunks/apply-fog.glsl index 0dcfbd63f071203c4e9f75c94fe7c25c352c5a55..a0f273ebcd15d6bac4a04295b2cfbbc9545b45a4 100644 --- a/src/mol-gl/shader/chunks/apply-fog.glsl +++ b/src/mol-gl/shader/chunks/apply-fog.glsl @@ -3,4 +3,8 @@ // float depth = gl_FragCoord.z / gl_FragCoord.w; float fogFactor = smoothstep(uFogNear, uFogFar, depth); gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogFactor); + float alpha = (1.0 - fogFactor) * gl_FragColor.a; + if (alpha < 0.01) + discard; + gl_FragColor = vec4( gl_FragColor.rgb, alpha ); #endif \ No newline at end of file