mirror of
https://github.com/molstar/molstar.git
synced 2026-06-06 22:54:22 +08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5871e9025 | ||
|
|
f26911b358 | ||
|
|
3a595b80b5 | ||
|
|
45760ddd41 | ||
|
|
447d068bf1 | ||
|
|
7e1642a4a3 | ||
|
|
7781267e78 | ||
|
|
f824fdcfed | ||
|
|
79dd441967 | ||
|
|
9dcf9c0785 | ||
|
|
83569462c6 | ||
|
|
947e169c3a | ||
|
|
e6b36c52d1 | ||
|
|
7fed3b84fa | ||
|
|
cbc941f193 | ||
|
|
a7ef0fb85f | ||
|
|
d10c36eaf5 | ||
|
|
e4c3a66753 |
11
CHANGELOG.md
11
CHANGELOG.md
@@ -6,6 +6,17 @@ Note that since we don't clearly distinguish between a public and private interf
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v3.8.2] - 2022-05-22
|
||||
|
||||
- Fix ``Scene.opacityAverage`` not taking xray shaded into account
|
||||
|
||||
## [v3.8.1] - 2022-05-14
|
||||
|
||||
- Fix issues with marking camera/handle helper (#433)
|
||||
- Fix issues with array uniforms when running with headless-gl
|
||||
- Fix Polymer Chain Instance coloring
|
||||
- Improve performance of scene marker/opacity average calculation
|
||||
|
||||
## [v3.8.0] - 2022-04-30
|
||||
|
||||
- Add support for outlines around transparent objects
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* DZ has C1 instead of N1 (e.g. 6I4N)
|
||||
* DP has N5 instead of C5 and C7 instead of N7 (e.g. 6I4N)
|
||||
* Beta & Gamma peptides (e.g. 1GAC, 6PQF)
|
||||
* Helices of D-amino acids (e.g. 7QDI)
|
||||
* Mixed (heterogeneous) all-atom/trace-only RNA model (1JGQ)
|
||||
* Polymers with residues with missing trace atoms (e.g. 2QFJ)
|
||||
* Modified RNA bases (1y26, 5L4O)
|
||||
|
||||
4369
package-lock.json
generated
4369
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
40
package.json
40
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "molstar",
|
||||
"version": "3.8.0",
|
||||
"version": "3.8.2",
|
||||
"description": "A comprehensive macromolecular library.",
|
||||
"homepage": "https://github.com/molstar/molstar#readme",
|
||||
"repository": {
|
||||
@@ -94,42 +94,42 @@
|
||||
"@graphql-codegen/add": "^3.1.1",
|
||||
"@graphql-codegen/cli": "^2.6.2",
|
||||
"@graphql-codegen/time": "^3.1.1",
|
||||
"@graphql-codegen/typescript": "^2.4.8",
|
||||
"@graphql-codegen/typescript": "^2.4.11",
|
||||
"@graphql-codegen/typescript-graphql-files-modules": "^2.1.1",
|
||||
"@graphql-codegen/typescript-graphql-request": "^4.4.5",
|
||||
"@graphql-codegen/typescript-operations": "^2.3.5",
|
||||
"@graphql-codegen/typescript-graphql-request": "^4.4.8",
|
||||
"@graphql-codegen/typescript-operations": "^2.4.0",
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/gl": "^4.1.0",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "^18.0.8",
|
||||
"@types/react-dom": "^18.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
||||
"@typescript-eslint/parser": "^5.21.0",
|
||||
"@types/jest": "^27.5.1",
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react-dom": "^18.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.25.0",
|
||||
"@typescript-eslint/parser": "^5.25.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"concurrently": "^7.1.0",
|
||||
"concurrently": "^7.2.0",
|
||||
"cpx2": "^4.2.0",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint": "^8.16.0",
|
||||
"extra-watch-webpack-plugin": "^1.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"graphql": "^16.4.0",
|
||||
"graphql": "^16.5.0",
|
||||
"http-server": "^14.1.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest": "^28.1.0",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"sass": "^1.51.0",
|
||||
"sass-loader": "^12.6.0",
|
||||
"sass": "^1.52.1",
|
||||
"sass-loader": "^13.0.0",
|
||||
"simple-git": "^3.7.1",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"ts-jest": "^27.1.4",
|
||||
"ts-jest": "^28.0.2",
|
||||
"typescript": "^4.6.4",
|
||||
"webpack": "^5.72.0",
|
||||
"webpack": "^5.72.1",
|
||||
"webpack-cli": "^4.9.2"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -137,7 +137,7 @@
|
||||
"@types/benchmark": "^2.1.1",
|
||||
"@types/compression": "1.7.2",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/node": "^16.11.32",
|
||||
"@types/node": "^16.11.36",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
"@types/swagger-ui-dist": "3.30.1",
|
||||
"argparse": "^2.0.1",
|
||||
@@ -146,11 +146,11 @@
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.1",
|
||||
"h264-mp4-encoder": "^1.0.12",
|
||||
"immer": "^9.0.12",
|
||||
"immer": "^9.0.14",
|
||||
"immutable": "^4.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"rxjs": "^7.5.5",
|
||||
"swagger-ui-dist": "^4.10.3",
|
||||
"swagger-ui-dist": "^4.11.1",
|
||||
"tslib": "^2.4.0",
|
||||
"util.promisify": "^1.1.1",
|
||||
"xhr2": "^0.2.1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
* @author David Sehnal <david.sehnal@gmail.com>
|
||||
@@ -372,12 +372,12 @@ namespace Canvas3D {
|
||||
const { repr, loci } = reprLoci;
|
||||
let changed = false;
|
||||
if (repr) {
|
||||
changed = repr.mark(loci, action);
|
||||
changed = repr.mark(loci, action) || changed;
|
||||
} else {
|
||||
changed = helper.handle.mark(loci, action);
|
||||
changed = helper.camera.mark(loci, action) || changed;
|
||||
reprRenderObjects.forEach((_, _repr) => { changed = _repr.mark(loci, action) || changed; });
|
||||
}
|
||||
changed = helper.handle.mark(loci, action) || changed;
|
||||
changed = helper.camera.mark(loci, action) || changed;
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ import { WebGLContext } from '../../mol-gl/webgl/context';
|
||||
import { GraphicsRenderVariantsBlended } from '../../mol-gl/webgl/render-item';
|
||||
import { Sphere3D } from '../../mol-math/geometry';
|
||||
import { Mat4, Vec3 } from '../../mol-math/linear-algebra';
|
||||
import { DataLoci, EmptyLoci, Loci } from '../../mol-model/loci';
|
||||
import { DataLoci, EmptyLoci, isEveryLoci, Loci } from '../../mol-model/loci';
|
||||
import { Shape } from '../../mol-model/shape';
|
||||
import { Visual } from '../../mol-repr/visual';
|
||||
import { ColorNames } from '../../mol-util/color/names';
|
||||
@@ -113,8 +113,10 @@ export class CameraHelper {
|
||||
|
||||
mark(loci: Loci, action: MarkerAction) {
|
||||
if (!MarkerActions.is(MarkerActions.Highlighting, action)) return false;
|
||||
if (!isCameraAxesLoci(loci)) return false;
|
||||
if (loci.data !== this) return false;
|
||||
if (!isEveryLoci(loci)) {
|
||||
if (!isCameraAxesLoci(loci)) return false;
|
||||
if (loci.data !== this) return false;
|
||||
}
|
||||
return Visual.mark(this.renderObject, loci, action, this.eachGroup);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -20,7 +20,7 @@ import produce from 'immer';
|
||||
import { Shape } from '../../mol-model/shape';
|
||||
import { PickingId } from '../../mol-geo/geometry/picking';
|
||||
import { Camera } from '../camera';
|
||||
import { DataLoci, EmptyLoci, Loci } from '../../mol-model/loci';
|
||||
import { DataLoci, EmptyLoci, isEveryLoci, Loci } from '../../mol-model/loci';
|
||||
import { MarkerAction, MarkerActions } from '../../mol-util/marker-action';
|
||||
import { Visual } from '../../mol-repr/visual';
|
||||
import { Interval } from '../../mol-data/int';
|
||||
@@ -121,8 +121,10 @@ export class HandleHelper {
|
||||
|
||||
mark(loci: Loci, action: MarkerAction) {
|
||||
if (!MarkerActions.is(MarkerActions.Highlighting, action)) return false;
|
||||
if (!isHandleLoci(loci)) return false;
|
||||
if (loci.data !== this) return false;
|
||||
if (!isEveryLoci(loci)) {
|
||||
if (!isHandleLoci(loci)) return false;
|
||||
if (loci.data !== this) return false;
|
||||
}
|
||||
return Visual.mark(this.renderObject, loci, action, this.eachGroup);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,15 +38,13 @@ export class DrawPass {
|
||||
private readonly drawTarget: RenderTarget;
|
||||
|
||||
readonly colorTarget: RenderTarget;
|
||||
readonly depthTexture: Texture;
|
||||
readonly depthTexturePrimitives: Texture;
|
||||
readonly depthTextureTransparent: Texture;
|
||||
readonly depthTextureOpaque: Texture;
|
||||
|
||||
readonly packedDepth: boolean;
|
||||
|
||||
private depthTarget: RenderTarget;
|
||||
private depthTargetPrimitives: RenderTarget | null;
|
||||
private depthTargetVolumes: RenderTarget | null;
|
||||
private depthTextureVolumes: Texture;
|
||||
private depthTargetTransparent: RenderTarget;
|
||||
private depthTargetOpaque: RenderTarget | null;
|
||||
|
||||
private copyFboTarget: CopyRenderable;
|
||||
private copyFboPostprocessing: CopyRenderable;
|
||||
@@ -68,17 +66,14 @@ export class DrawPass {
|
||||
this.colorTarget = webgl.createRenderTarget(width, height, true, 'uint8', 'linear');
|
||||
this.packedDepth = !extensions.depthTexture;
|
||||
|
||||
this.depthTarget = webgl.createRenderTarget(width, height);
|
||||
this.depthTexture = this.depthTarget.texture;
|
||||
this.depthTargetTransparent = webgl.createRenderTarget(width, height);
|
||||
this.depthTextureTransparent = this.depthTargetTransparent.texture;
|
||||
|
||||
this.depthTargetPrimitives = this.packedDepth ? webgl.createRenderTarget(width, height) : null;
|
||||
this.depthTargetVolumes = this.packedDepth ? webgl.createRenderTarget(width, height) : null;
|
||||
this.depthTargetOpaque = this.packedDepth ? webgl.createRenderTarget(width, height) : null;
|
||||
|
||||
this.depthTexturePrimitives = this.depthTargetPrimitives ? this.depthTargetPrimitives.texture : resources.texture('image-depth', 'depth', isWebGL2 ? 'float' : 'ushort', 'nearest');
|
||||
this.depthTextureVolumes = this.depthTargetVolumes ? this.depthTargetVolumes.texture : resources.texture('image-depth', 'depth', isWebGL2 ? 'float' : 'ushort', 'nearest');
|
||||
this.depthTextureOpaque = this.depthTargetOpaque ? this.depthTargetOpaque.texture : resources.texture('image-depth', 'depth', isWebGL2 ? 'float' : 'ushort', 'nearest');
|
||||
if (!this.packedDepth) {
|
||||
this.depthTexturePrimitives.define(width, height);
|
||||
this.depthTextureVolumes.define(width, height);
|
||||
this.depthTextureOpaque.define(width, height);
|
||||
}
|
||||
|
||||
this.wboit = enableWboit ? new WboitPass(webgl, width, height) : undefined;
|
||||
@@ -100,18 +95,12 @@ export class DrawPass {
|
||||
|
||||
if (width !== w || height !== h) {
|
||||
this.colorTarget.setSize(width, height);
|
||||
this.depthTarget.setSize(width, height);
|
||||
this.depthTargetTransparent.setSize(width, height);
|
||||
|
||||
if (this.depthTargetPrimitives) {
|
||||
this.depthTargetPrimitives.setSize(width, height);
|
||||
if (this.depthTargetOpaque) {
|
||||
this.depthTargetOpaque.setSize(width, height);
|
||||
} else {
|
||||
this.depthTexturePrimitives.define(width, height);
|
||||
}
|
||||
|
||||
if (this.depthTargetVolumes) {
|
||||
this.depthTargetVolumes.setSize(width, height);
|
||||
} else {
|
||||
this.depthTextureVolumes.define(width, height);
|
||||
this.depthTextureOpaque.define(width, height);
|
||||
}
|
||||
|
||||
ValueCell.update(this.copyFboTarget.values.uTexSize, Vec2.set(this.copyFboTarget.values.uTexSize.ref.value, width, height));
|
||||
@@ -134,17 +123,17 @@ export class DrawPass {
|
||||
renderer.clear(true);
|
||||
|
||||
// render opaque primitives
|
||||
this.depthTexturePrimitives.attachFramebuffer(this.colorTarget.framebuffer, 'depth');
|
||||
this.depthTextureOpaque.attachFramebuffer(this.colorTarget.framebuffer, 'depth');
|
||||
this.colorTarget.bind();
|
||||
renderer.clearDepth();
|
||||
renderer.renderWboitOpaque(scene.primitives, camera, null);
|
||||
|
||||
if (PostprocessingPass.isEnabled(postprocessingProps)) {
|
||||
if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
|
||||
this.depthTarget.bind();
|
||||
this.depthTargetTransparent.bind();
|
||||
renderer.clearDepth(true);
|
||||
if (scene.getOpacityAverage() < 1) {
|
||||
renderer.renderDepthTransparent(scene.primitives, camera, this.depthTexturePrimitives);
|
||||
if (scene.opacityAverage < 1) {
|
||||
renderer.renderDepthTransparent(scene.primitives, camera, this.depthTextureOpaque);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,17 +141,19 @@ export class DrawPass {
|
||||
}
|
||||
|
||||
// render transparent primitives and volumes
|
||||
this.wboit.bind();
|
||||
renderer.renderWboitTransparent(scene.primitives, camera, this.depthTexturePrimitives);
|
||||
renderer.renderWboitTransparent(scene.volumes, camera, this.depthTexturePrimitives);
|
||||
if (scene.opacityAverage < 1 || scene.volumes.renderables.length > 0) {
|
||||
this.wboit.bind();
|
||||
renderer.renderWboitTransparent(scene.primitives, camera, this.depthTextureOpaque);
|
||||
renderer.renderWboitTransparent(scene.volumes, camera, this.depthTextureOpaque);
|
||||
|
||||
// evaluate wboit
|
||||
if (PostprocessingPass.isEnabled(postprocessingProps)) {
|
||||
this.postprocessing.target.bind();
|
||||
} else {
|
||||
this.colorTarget.bind();
|
||||
// evaluate wboit
|
||||
if (PostprocessingPass.isEnabled(postprocessingProps)) {
|
||||
this.postprocessing.target.bind();
|
||||
} else {
|
||||
this.colorTarget.bind();
|
||||
}
|
||||
this.wboit.render();
|
||||
}
|
||||
this.wboit.render();
|
||||
}
|
||||
|
||||
private _renderBlended(renderer: Renderer, camera: ICamera, scene: Scene, toDrawingBuffer: boolean, transparentBackground: boolean, postprocessingProps: PostprocessingProps) {
|
||||
@@ -171,7 +162,7 @@ export class DrawPass {
|
||||
} else {
|
||||
this.colorTarget.bind();
|
||||
if (!this.packedDepth) {
|
||||
this.depthTexturePrimitives.attachFramebuffer(this.colorTarget.framebuffer, 'depth');
|
||||
this.depthTextureOpaque.attachFramebuffer(this.colorTarget.framebuffer, 'depth');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +172,8 @@ export class DrawPass {
|
||||
if (!toDrawingBuffer) {
|
||||
// do a depth pass if not rendering to drawing buffer and
|
||||
// extensions.depthTexture is unsupported (i.e. depthTarget is set)
|
||||
if (this.depthTargetPrimitives) {
|
||||
this.depthTargetPrimitives.bind();
|
||||
if (this.depthTargetOpaque) {
|
||||
this.depthTargetOpaque.bind();
|
||||
renderer.clearDepth(true);
|
||||
renderer.renderDepthOpaque(scene.primitives, camera, null);
|
||||
this.colorTarget.bind();
|
||||
@@ -190,29 +181,29 @@ export class DrawPass {
|
||||
|
||||
if (PostprocessingPass.isEnabled(postprocessingProps)) {
|
||||
if (!this.packedDepth) {
|
||||
this.depthTexturePrimitives.detachFramebuffer(this.postprocessing.target.framebuffer, 'depth');
|
||||
this.depthTextureOpaque.detachFramebuffer(this.postprocessing.target.framebuffer, 'depth');
|
||||
} else {
|
||||
this.colorTarget.depthRenderbuffer?.detachFramebuffer(this.postprocessing.target.framebuffer);
|
||||
}
|
||||
|
||||
if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
|
||||
this.depthTarget.bind();
|
||||
this.depthTargetTransparent.bind();
|
||||
renderer.clearDepth(true);
|
||||
if (scene.getOpacityAverage() < 1) {
|
||||
renderer.renderDepthTransparent(scene.primitives, camera, this.depthTexturePrimitives);
|
||||
if (scene.opacityAverage < 1) {
|
||||
renderer.renderDepthTransparent(scene.primitives, camera, this.depthTextureOpaque);
|
||||
}
|
||||
}
|
||||
|
||||
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps);
|
||||
|
||||
if (!this.packedDepth) {
|
||||
this.depthTexturePrimitives.attachFramebuffer(this.postprocessing.target.framebuffer, 'depth');
|
||||
this.depthTextureOpaque.attachFramebuffer(this.postprocessing.target.framebuffer, 'depth');
|
||||
} else {
|
||||
this.colorTarget.depthRenderbuffer?.attachFramebuffer(this.postprocessing.target.framebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
renderer.renderBlendedVolume(scene.volumes, camera, this.depthTexturePrimitives);
|
||||
renderer.renderBlendedVolume(scene.volumes, camera, this.depthTextureOpaque);
|
||||
}
|
||||
|
||||
renderer.renderBlendedTransparent(scene.primitives, camera, null);
|
||||
@@ -248,10 +239,9 @@ export class DrawPass {
|
||||
}
|
||||
|
||||
if (markingEnabled) {
|
||||
const markerAverage = scene.getMarkerAverage();
|
||||
if (markerAverage > 0) {
|
||||
if (scene.markerAverage > 0) {
|
||||
const markingDepthTest = props.marking.ghostEdgeStrength < 1;
|
||||
if (markingDepthTest && markerAverage !== 1) {
|
||||
if (markingDepthTest && scene.markerAverage !== 1) {
|
||||
this.marking.depthTarget.bind();
|
||||
renderer.clear(false, true);
|
||||
renderer.renderMarkingDepth(scene.primitives, camera, null);
|
||||
|
||||
@@ -64,12 +64,10 @@ export class PickPass {
|
||||
}
|
||||
|
||||
private renderVariant(renderer: Renderer, camera: ICamera, scene: Scene, helper: Helper, variant: 'pick' | 'depth', pickType: number) {
|
||||
const depth = this.drawPass.depthTexturePrimitives;
|
||||
renderer.clear(false);
|
||||
|
||||
renderer.update(camera);
|
||||
renderer.renderPick(scene.primitives, camera, variant, null, pickType);
|
||||
renderer.renderPick(scene.volumes, camera, variant, depth, pickType);
|
||||
renderer.renderPick(helper.handle.scene, camera, variant, null, pickType);
|
||||
|
||||
if (helper.camera.isEnabled) {
|
||||
|
||||
@@ -318,7 +318,7 @@ export class PostprocessingPass {
|
||||
}
|
||||
|
||||
constructor(private webgl: WebGLContext, private drawPass: DrawPass) {
|
||||
const { colorTarget, depthTexture: depthTextureTransparent, depthTexturePrimitives: depthTextureOpaque } = drawPass;
|
||||
const { colorTarget, depthTextureTransparent, depthTextureOpaque } = drawPass;
|
||||
const width = colorTarget.getWidth();
|
||||
const height = colorTarget.getHeight();
|
||||
|
||||
@@ -471,7 +471,7 @@ export class PostprocessingPass {
|
||||
this.ssaoDepthBlurProxyTexture.define(sw, sh);
|
||||
|
||||
if (this.ssaoScale === 1) {
|
||||
ValueCell.update(this.ssaoRenderable.values.tDepth, this.drawPass.depthTexture);
|
||||
ValueCell.update(this.ssaoRenderable.values.tDepth, this.drawPass.depthTextureTransparent);
|
||||
} else {
|
||||
ValueCell.update(this.ssaoRenderable.values.tDepth, this.downsampledDepthTarget.texture);
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ function _createColors(locationIt: LocationIterator, positionIt: LocationIterato
|
||||
case 'uniform': return createUniformColor(locationIt, colorTheme.color, colorData);
|
||||
case 'instance':
|
||||
return locationIt.nonInstanceable
|
||||
? createInstanceColor(locationIt, colorTheme.color, colorData)
|
||||
: createGroupColor(locationIt, colorTheme.color, colorData);
|
||||
? createGroupColor(locationIt, colorTheme.color, colorData)
|
||||
: createInstanceColor(locationIt, colorTheme.color, colorData);
|
||||
case 'group': return createGroupColor(locationIt, colorTheme.color, colorData);
|
||||
case 'groupInstance': return createGroupInstanceColor(locationIt, colorTheme.color, colorData);
|
||||
case 'vertex': return createVertexColor(positionIt, colorTheme.color, colorData);
|
||||
|
||||
@@ -80,8 +80,8 @@ interface Scene extends Object3D {
|
||||
has: (o: GraphicsRenderObject) => boolean
|
||||
clear: () => void
|
||||
forEach: (callbackFn: (value: GraphicsRenderable, key: GraphicsRenderObject) => void) => void
|
||||
getMarkerAverage: () => number
|
||||
getOpacityAverage: () => number
|
||||
readonly markerAverage: number
|
||||
readonly opacityAverage: number
|
||||
}
|
||||
|
||||
namespace Scene {
|
||||
@@ -101,6 +101,9 @@ namespace Scene {
|
||||
let boundingSphereDirty = true;
|
||||
let boundingSphereVisibleDirty = true;
|
||||
|
||||
let markerAverage = 0;
|
||||
let opacityAverage = 0;
|
||||
|
||||
const object3d = Object3D.create();
|
||||
const { view, position, direction, up } = object3d;
|
||||
|
||||
@@ -157,6 +160,7 @@ namespace Scene {
|
||||
}
|
||||
|
||||
renderables.sort(renderableSort);
|
||||
opacityAverage = calculateOpacityAverage();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -178,12 +182,42 @@ namespace Scene {
|
||||
const newVisibleHash = computeVisibleHash();
|
||||
if (newVisibleHash !== visibleHash) {
|
||||
boundingSphereVisibleDirty = true;
|
||||
opacityAverage = calculateOpacityAverage();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function calculateMarkerAverage() {
|
||||
if (primitives.length === 0) return 0;
|
||||
let count = 0;
|
||||
let markerAverage = 0;
|
||||
for (let i = 0, il = primitives.length; i < il; ++i) {
|
||||
if (!primitives[i].state.visible) continue;
|
||||
markerAverage += primitives[i].values.markerAverage.ref.value;
|
||||
count += 1;
|
||||
}
|
||||
return count > 0 ? markerAverage / count : 0;
|
||||
}
|
||||
|
||||
function calculateOpacityAverage() {
|
||||
if (primitives.length === 0) return 0;
|
||||
let count = 0;
|
||||
let opacityAverage = 0;
|
||||
for (let i = 0, il = primitives.length; i < il; ++i) {
|
||||
const p = primitives[i];
|
||||
if (!p.state.visible) continue;
|
||||
// TODO: simplify, handle in renderable.state???
|
||||
// uAlpha is updated in "render" so we need to recompute it here
|
||||
const alpha = clamp(p.values.alpha.ref.value * p.state.alphaFactor, 0, 1);
|
||||
const xray = p.values.dXrayShaded?.ref.value ? 0.5 : 1;
|
||||
opacityAverage += (1 - p.values.transparencyAverage.ref.value) * alpha * xray;
|
||||
count += 1;
|
||||
}
|
||||
return count > 0 ? opacityAverage / count : 0;
|
||||
}
|
||||
|
||||
return {
|
||||
view, position, direction, up,
|
||||
|
||||
@@ -209,6 +243,8 @@ namespace Scene {
|
||||
} else {
|
||||
syncVisibility();
|
||||
}
|
||||
markerAverage = calculateMarkerAverage();
|
||||
opacityAverage = calculateOpacityAverage();
|
||||
},
|
||||
add: (o: GraphicsRenderObject) => commitQueue.add(o),
|
||||
remove: (o: GraphicsRenderObject) => commitQueue.remove(o),
|
||||
@@ -247,37 +283,11 @@ namespace Scene {
|
||||
}
|
||||
return boundingSphereVisible;
|
||||
},
|
||||
getMarkerAverage() {
|
||||
if (primitives.length === 0 && volumes.length === 0) return 0;
|
||||
let count = 0;
|
||||
let markerAverage = 0;
|
||||
for (let i = 0, il = primitives.length; i < il; ++i) {
|
||||
if (!primitives[i].state.visible) continue;
|
||||
markerAverage += primitives[i].values.markerAverage.ref.value;
|
||||
count += 1;
|
||||
}
|
||||
for (let i = 0, il = volumes.length; i < il; ++i) {
|
||||
if (!volumes[i].state.visible) continue;
|
||||
markerAverage += volumes[i].values.markerAverage.ref.value;
|
||||
count += 1;
|
||||
}
|
||||
return count > 0 ? markerAverage / count : 0;
|
||||
get markerAverage() {
|
||||
return markerAverage;
|
||||
},
|
||||
getOpacityAverage() {
|
||||
if (primitives.length === 0) return 0;
|
||||
let count = 0;
|
||||
let opacityAverage = 0;
|
||||
for (let i = 0, il = primitives.length; i < il; ++i) {
|
||||
const p = primitives[i];
|
||||
if (!p.state.visible) continue;
|
||||
|
||||
// TODO: simplify, handle in renderable.state???
|
||||
// uAlpha is updated in "render" so we need to recompute it here
|
||||
const alpha = clamp(p.values.alpha.ref.value * p.state.alphaFactor, 0, 1);
|
||||
opacityAverage += (1 - p.values.transparencyAverage.ref.value) * alpha;
|
||||
count += 1;
|
||||
}
|
||||
return count > 0 ? opacityAverage / count : 0;
|
||||
get opacityAverage() {
|
||||
return opacityAverage;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { ShaderCode, DefineValues, addShaderDefines } from '../shader-code';
|
||||
import { WebGLState } from './state';
|
||||
import { WebGLExtensions } from './extensions';
|
||||
import { getUniformSetters, UniformsList, getUniformType, UniformSetters } from './uniform';
|
||||
import { getUniformSetters, UniformsList, getUniformType, UniformSetters, isArrayUniform } from './uniform';
|
||||
import { AttributeBuffers, getAttribType } from './buffer';
|
||||
import { TextureId, Textures } from './texture';
|
||||
import { idFactory } from '../../mol-util/id-factory';
|
||||
@@ -41,7 +41,14 @@ function getLocations(gl: GLRenderingContext, program: WebGLProgram, schema: Ren
|
||||
// unused attributes will result in a `-1` location which is usually fine
|
||||
// if (loc === -1) console.info(`Could not get attribute location for '${k}'`);
|
||||
locations[k] = loc;
|
||||
} else if (spec.type === 'uniform' || spec.type === 'texture') {
|
||||
} else if (spec.type === 'uniform') {
|
||||
let loc = gl.getUniformLocation(program, k);
|
||||
// headless-gl requires a '[0]' suffix for array uniforms (https://github.com/stackgl/headless-gl/issues/170)
|
||||
if (loc === null && isArrayUniform(spec.kind)) loc = gl.getUniformLocation(program, k + '[0]');
|
||||
// unused uniforms will result in a `null` location which is usually fine
|
||||
// if (loc === null) console.info(`Could not get uniform location for '${k}'`);
|
||||
locations[k] = loc as number;
|
||||
} else if (spec.type === 'texture') {
|
||||
const loc = gl.getUniformLocation(program, k);
|
||||
// unused uniforms will result in a `null` location which is usually fine
|
||||
// if (loc === null) console.info(`Could not get uniform location for '${k}'`);
|
||||
|
||||
@@ -42,6 +42,10 @@ export function getUniformType(gl: GLRenderingContext, kind: UniformKind) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isArrayUniform(kind: UniformKind) {
|
||||
return kind.endsWith('[]');
|
||||
}
|
||||
|
||||
export type UniformSetter = (gl: GLRenderingContext, location: number, value: any) => void
|
||||
export type UniformSetters = { [k: string]: UniformSetter }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user