Compare commits

...

52 Commits

Author SHA1 Message Date
Alexander Rose
fa2b8542bf 2.0.0-dev.2 2021-02-18 21:20:14 -08:00
Alexander Rose
901522f500 added atom-id and entity-id color theme 2021-02-18 21:16:46 -08:00
dsehnal
62b63c1aa5 apply magic to solve GPU MC rendering issue 2021-02-18 19:05:07 +01:00
Alexander Rose
24b36f41da 2.0.0-dev.1 2021-02-15 22:09:05 -08:00
Alexander Rose
c9c890782c try re-use boundingSphere in element visuals
- if it has not changed much
2021-02-15 21:38:13 -08:00
Alexander Rose
f2c539ebd8 psf parser, support lammps "full" style 2021-02-15 18:04:38 -08:00
dsehnal
feb922ca91 Merge branch 'gpu' 2021-02-14 20:13:16 +01:00
dsehnal
25127bb84b Merge branch 'master' of https://github.com/molstar/molstar 2021-02-14 20:13:12 +01:00
dsehnal
8fb01d2157 Merge remote-tracking branch 'origin' into gpu 2021-02-14 20:11:11 +01:00
dsehnal
c09357ea75 updateImmediate for modelIndex 2021-02-14 20:00:37 +01:00
dsehnal
9f2513dae0 fix examples 2021-02-14 19:38:58 +01:00
dsehnal
11a52c0390 add missing TrajectoryInfo 2021-02-14 19:34:32 +01:00
dsehnal
e955dc7e94 exportable trajectory animation 2021-02-14 19:26:06 +01:00
Alexander Rose
c8107272f6 2.0.0-dev.0 2021-02-13 23:11:05 -08:00
Alexander Rose
fb08fe7545 remove extra files 2021-02-13 23:06:17 -08:00
Alexander Rose
b6f054ea28 Merge pull request #130 from molstar/lint-dep
Lint dep
2021-02-13 13:24:34 -08:00
Alexander Rose
dc7e85133c moved DefaultPluginSpec to spec.ts 2021-02-13 13:04:53 -08:00
Alexander Rose
90cddf4e41 allow named tuples
- beter use downlevel-dts for backwards compatibility
2021-02-13 13:00:11 -08:00
Alexander Rose
2cddbb72a6 fix tests, remove more deps from mat4, quat 2021-02-13 12:29:45 -08:00
Alexander Rose
a16faaac4e avoid some static dependencies
- those can lead to errors due to circular dependencies
- making them runtime dependencies fixes this
2021-02-13 12:06:07 -08:00
Alexander Rose
6c5224f33e new linting rules
- no default exports
- no named tuples
2021-02-13 11:36:21 -08:00
Alexander Rose
77d013b775 webgl, ensure active attribute with divisor 0
- workaround for FF <85
- needed for `texture-mesh` geometry
2021-02-13 11:30:13 -08:00
Alexander Rose
02a466e8b9 only update repr visibility when changed
- avoids superfluous scene rendering, e.g., when animating
2021-02-13 11:27:44 -08:00
Alexander Rose
3cb65cbe3d reduce ssao quality defaults a bit
- less texture fetches
2021-02-13 11:24:07 -08:00
Alexander Rose
fe8838542c 1.3.0 2021-02-07 13:29:46 -08:00
Alexander Rose
78b5c9aac4 Merge pull request #129 from molstar/gpu
Gpu acceleration for isosurface & gaussian-surface
2021-02-07 13:25:22 -08:00
Alexander Rose
021fa7b79b clearer param names for using gpu/impostors 2021-02-07 13:23:36 -08:00
Alexander Rose
0443589b09 allow gaussian volume without blendMinMax 2021-02-07 13:18:24 -08:00
Alexander Rose
415288de9f tweak quality settings
- lower resolution
2021-02-07 12:52:10 -08:00
Alexander Rose
ecbafb086a fix mc example 2021-02-06 12:46:25 -08:00
Alexander Rose
e5dae6c0dd increased default quality for larger structures
- rational is that larger structures can take a bit longer to create
2021-02-06 12:45:00 -08:00
Alexander Rose
16f4524bdb improved gpu support for representations
- enabled in volume isosurface & structure gaussian surface
- only if suitable (check memory requirements and resolution)
- falls back to cpu code
2021-02-06 12:43:24 -08:00
Alexander Rose
6b33021f43 fix webgl stats on render-item disposal 2021-02-06 12:30:12 -08:00
Alexander Rose
fdf37100c2 improved gpu-mc
- lower memory usage
- support for 2^32 vertices in webgl2
- fix rounding issue when creating volume texture
2021-02-06 12:28:52 -08:00
Alexander Rose
e28674d0dc model format improvements
- add a source format to the mmcif format
- add pdb format
- allow undefined in typeguard .is helpers
2021-02-03 19:36:01 -08:00
Alexander Rose
fb7456286a fix label_seq_id assignment when undefined column 2021-02-03 19:32:20 -08:00
Alexander Rose
9d240f8928 allow views of undefined columns 2021-02-03 19:30:14 -08:00
David Sehnal
48ef5efb21 Merge pull request #127 from molstar/pp-res
lower resolution ssao
2021-02-01 12:59:53 +01:00
Alexander Rose
52b2e7c144 lower res ssao 2021-01-31 13:22:22 -08:00
Alexander Rose
f2d1d60f6b fix cellpack & unit creation issues
- cellpack generate color theme can be applied to 1 model trajectories
- don't clone supplied props in Unit.create
- fix cellpack structure building to share unit.props
2021-01-31 12:06:40 -08:00
dsehnal
5a176a378a 1.2.15 2021-01-31 18:32:08 +01:00
dsehnal
60151c2c24 fix getUnitsSortedByVolume 2021-01-31 18:30:13 +01:00
dsehnal
a5db6350a2 only normalize Canvas3D props when loading from a saved state 2021-01-31 18:01:42 +01:00
dsehnal
0618eb18ba 1.2.14 2021-01-31 17:10:17 +01:00
Alexander Rose
bffdff6aad gaussian surface visual improvements
- add structure.unitsSortedByVolume
- increase gaussian smoothness in coarse presets
- use slice area instead of volume to ensure reasonable resolution
- use largest units (by volume) for reasonable resolution calculation
2021-01-30 22:55:29 -08:00
Alexander Rose
7753a6ec56 renderable schema cleanup
- use base schema in direct-volume schema
2021-01-30 12:57:19 -08:00
Alexander Rose
b8aafa1d78 mol-gl improvements
- int textures (webgl2)
- read into Int32Array (webgl2)
- fix ctx.parameters.maxDrawingBuffers (webgl1)
- support setting frag out type (webgl2)
2021-01-30 12:42:48 -08:00
Alexander Rose
672875187b add renderable.state.disposed flag
- set when disposing render-objects
- don't render disposed objects (can be temporarily still in a scene)
2021-01-30 12:39:33 -08:00
Alexander Rose
547d60d573 fix texture-mesh vertex count 2021-01-30 12:33:59 -08:00
Alexander Rose
99471d2a7b add xray shading edge fallof parameter 2021-01-30 12:32:20 -08:00
Alexander Rose
45d249b71a log renderItemId in debug mode 2021-01-30 11:23:46 -08:00
Alexander Rose
1382edd81c improved trackball rotate on wide canvases 2021-01-30 11:23:15 -08:00
388 changed files with 2076 additions and 1466 deletions

View File

@@ -31,7 +31,14 @@
"no-unsafe-finally": "warn",
"no-var": "error",
"spaced-comment": "error",
"semi": "warn"
"semi": "warn",
"no-restricted-syntax": [
"error",
{
"selector": "ExportDefaultDeclaration",
"message": "Default exports are not allowed"
}
]
},
"overrides": [
{

4
package-lock.json generated
View File

@@ -1,11 +1,11 @@
{
"name": "molstar",
"version": "1.2.13",
"version": "2.0.0-dev.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.2.13",
"version": "1.2.15",
"license": "MIT",
"dependencies": {
"@types/argparse": "^1.0.38",

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "1.2.13",
"version": "2.0.0-dev.2",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {

View File

@@ -6,7 +6,8 @@
*/
import '../../mol-util/polyfill';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import './index.html';
import { PluginContext } from '../../mol-plugin/context';
import { PluginCommands } from '../../mol-plugin/commands';
@@ -69,9 +70,10 @@ class Viewer {
viewportShowSelectionMode: false,
viewportShowAnimation: false,
} };
const defaultSpec = DefaultPluginSpec();
const spec: PluginSpec = {
actions: [...DefaultPluginSpec.actions],
actions: [...defaultSpec.actions],
behaviors: [
PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci, { mark: false }),
PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider),
@@ -81,8 +83,8 @@ class Viewer {
PluginSpec.Behavior(PluginBehaviors.CustomProps.Interactions),
PluginSpec.Behavior(PluginBehaviors.CustomProps.SecondaryStructure),
],
animations: [...DefaultPluginSpec.animations || []],
customParamEditors: DefaultPluginSpec.customParamEditors,
animations: [...defaultSpec.animations || []],
customParamEditors: defaultSpec.customParamEditors,
layout: {
initial: {
isExpanded: o.layoutIsExpanded,
@@ -90,14 +92,14 @@ class Viewer {
controlsDisplay: o.layoutControlsDisplay,
},
controls: {
...DefaultPluginSpec.layout && DefaultPluginSpec.layout.controls,
...defaultSpec.layout && defaultSpec.layout.controls,
top: o.layoutShowSequence ? undefined : 'none',
bottom: o.layoutShowLog ? undefined : 'none',
left: o.layoutShowLeftPanel ? undefined : 'none',
}
},
components: {
...DefaultPluginSpec.components,
...defaultSpec.components,
remoteState: o.layoutShowRemoteState ? 'default' : 'none',
viewport: {
view: ViewportComponent

View File

@@ -6,7 +6,8 @@
*/
import '../../mol-util/polyfill';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import './index.html';
import './embedded.html';
import './favicon.ico';
@@ -89,15 +90,16 @@ export class Viewer {
constructor(elementOrId: string | HTMLElement, options: Partial<ViewerOptions> = {}) {
const o = { ...DefaultViewerOptions, ...options };
const defaultSpec = DefaultPluginSpec();
const spec: PluginSpec = {
actions: [...DefaultPluginSpec.actions],
actions: [...defaultSpec.actions],
behaviors: [
...DefaultPluginSpec.behaviors,
...defaultSpec.behaviors,
...o.extensions.map(e => Extensions[e]),
],
animations: [...DefaultPluginSpec.animations || []],
customParamEditors: DefaultPluginSpec.customParamEditors,
animations: [...defaultSpec.animations || []],
customParamEditors: defaultSpec.customParamEditors,
customFormats: o?.customFormats,
layout: {
initial: {
@@ -106,14 +108,14 @@ export class Viewer {
controlsDisplay: o.layoutControlsDisplay,
},
controls: {
...DefaultPluginSpec.layout && DefaultPluginSpec.layout.controls,
...defaultSpec.layout && defaultSpec.layout.controls,
top: o.layoutShowSequence ? undefined : 'none',
bottom: o.layoutShowLog ? undefined : 'none',
left: o.layoutShowLeftPanel ? undefined : 'none',
}
},
components: {
...DefaultPluginSpec.components,
...defaultSpec.components,
remoteState: o.layoutShowRemoteState ? 'default' : 'none',
},
config: [

View File

@@ -70,7 +70,7 @@ function classify(name: string, field: CifField): CifWriter.Field {
}
}
export default function convert(path: string, asText = false, hints?: EncodingStrategyHint[], filter?: string) {
export function convert(path: string, asText = false, hints?: EncodingStrategyHint[], filter?: string) {
return Task.create<Uint8Array>('BinaryCIF', async ctx => {
const encodingProvider: BinaryEncodingProvider = hints
? CifWriter.createEncodingProviderFromJsonConfig(hints)

View File

@@ -10,7 +10,7 @@ import * as argparse from 'argparse';
import * as util from 'util';
import * as fs from 'fs';
import * as zlib from 'zlib';
import convert from './converter';
import { convert } from './converter';
require('util.promisify').shim();

View File

@@ -12,7 +12,7 @@ import fetch from 'node-fetch';
import { parseCsv } from '../../mol-io/reader/csv/parser';
import { CifFrame, CifBlock } from '../../mol-io/reader/cif';
import parseText from '../../mol-io/reader/cif/text/parser';
import { parseCifText } from '../../mol-io/reader/cif/text/parser';
import { generateSchema } from './util/cif-dic';
import { generate } from './util/generate';
import { Filter, Database } from './util/schema';
@@ -28,19 +28,19 @@ function getDicNamespace(block: CifBlock) {
async function runGenerateSchemaMmcif(name: string, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
await ensureMmcifDicAvailable();
const mmcifDic = await parseText(fs.readFileSync(MMCIF_DIC_PATH, 'utf8')).run();
const mmcifDic = await parseCifText(fs.readFileSync(MMCIF_DIC_PATH, 'utf8')).run();
if (mmcifDic.isError) throw mmcifDic;
await ensureIhmDicAvailable();
const ihmDic = await parseText(fs.readFileSync(IHM_DIC_PATH, 'utf8')).run();
const ihmDic = await parseCifText(fs.readFileSync(IHM_DIC_PATH, 'utf8')).run();
if (ihmDic.isError) throw ihmDic;
await ensureCarbBranchDicAvailable();
const carbBranchDic = await parseText(fs.readFileSync(CARB_BRANCH_DIC_PATH, 'utf8')).run();
const carbBranchDic = await parseCifText(fs.readFileSync(CARB_BRANCH_DIC_PATH, 'utf8')).run();
if (carbBranchDic.isError) throw carbBranchDic;
await ensureCarbCompDicAvailable();
const carbCompDic = await parseText(fs.readFileSync(CARB_COMP_DIC_PATH, 'utf8')).run();
const carbCompDic = await parseCifText(fs.readFileSync(CARB_COMP_DIC_PATH, 'utf8')).run();
if (carbCompDic.isError) throw carbCompDic;
const mmcifDicVersion = getDicVersion(mmcifDic.result.blocks[0]);
@@ -56,7 +56,7 @@ async function runGenerateSchemaMmcif(name: string, fieldNamesPath: string, type
async function runGenerateSchemaCifCore(name: string, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
await ensureCifCoreDicAvailable();
const cifCoreDic = await parseText(fs.readFileSync(CIF_CORE_DIC_PATH, 'utf8')).run();
const cifCoreDic = await parseCifText(fs.readFileSync(CIF_CORE_DIC_PATH, 'utf8')).run();
if (cifCoreDic.isError) throw cifCoreDic;
const cifCoreDicVersion = getDicVersion(cifCoreDic.result.blocks[0]);
@@ -80,7 +80,7 @@ async function resolveImports(frames: CifFrame[], baseDir: string): Promise<Map<
if (!file) continue;
if (imports.has(file)) continue;
const dic = await parseText(fs.readFileSync(path.join(baseDir, file), 'utf8')).run();
const dic = await parseCifText(fs.readFileSync(path.join(baseDir, file), 'utf8')).run();
if (dic.isError) throw dic;
imports.set(file, [...dic.result.blocks[0].saveFrames]);
@@ -92,7 +92,7 @@ async function resolveImports(frames: CifFrame[], baseDir: string): Promise<Map<
}
async function runGenerateSchemaDic(name: string, dicPath: string, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
const dic = await parseText(fs.readFileSync(dicPath, 'utf8')).run();
const dic = await parseCifText(fs.readFileSync(dicPath, 'utf8')).run();
if (dic.isError) throw dic;
const dicVersion = getDicVersion(dic.result.blocks[0]);

View File

@@ -6,7 +6,8 @@
import { SphericalBasisOrder } from '../../extensions/alpha-orbitals/spherical-functions';
import { BasisAndOrbitals, CreateOrbitalDensityVolume, CreateOrbitalRepresentation3D, CreateOrbitalVolume, StaticBasisAndOrbitals } from '../../extensions/alpha-orbitals/transforms';
import { createPluginAsync, DefaultPluginSpec } from '../../mol-plugin';
import { createPluginAsync } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { PluginStateObject } from '../../mol-plugin-state/objects';
import { PluginConfig } from '../../mol-plugin/config';
import { PluginContext } from '../../mol-plugin/context';
@@ -53,7 +54,7 @@ export class AlphaOrbitalsExample {
async init(target: string | HTMLElement) {
this.plugin = await createPluginAsync(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
...DefaultPluginSpec(),
layout: {
initial: {
isExpanded: false,

View File

@@ -86,7 +86,7 @@
// adjust this number to make the animation faster or slower
// requires to "restart" the animation if changed
BasicMolStarWrapper.animate.modelIndex.maxFPS = 30;
BasicMolStarWrapper.animate.modelIndex.targetFps = 30;
addControl('Play To End', () => BasicMolStarWrapper.animate.modelIndex.onceForward());
addControl('Play To Start', () => BasicMolStarWrapper.animate.modelIndex.onceBackward());

View File

@@ -6,7 +6,8 @@
import { EmptyLoci } from '../../mol-model/loci';
import { StructureSelection } from '../../mol-model/structure';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { PluginCommands } from '../../mol-plugin/commands';
@@ -28,7 +29,7 @@ class BasicWrapper {
init(target: string | HTMLElement) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
...DefaultPluginSpec(),
layout: {
initial: {
isExpanded: false,
@@ -82,13 +83,17 @@ class BasicWrapper {
if (!this.plugin.canvas3d.props.trackball.spin) PluginCommands.Camera.Reset(this.plugin, {});
}
private animateModelIndexTargetFps() {
return Math.max(1, this.animate.modelIndex.targetFps | 0);
}
animate = {
modelIndex: {
maxFPS: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'loop', params: {} } }); },
targetFps: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'loop', params: {} } }); },
stop: () => this.plugin.managers.animation.stop()
}
}

View File

@@ -10,7 +10,7 @@ import { superpose } from '../../mol-model/structure/structure/util/superpositio
import { PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { PluginContext } from '../../mol-plugin/context';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import Expression from '../../mol-script/language/expression';
import { Expression } from '../../mol-script/language/expression';
import { compile } from '../../mol-script/runtime/query/compiler';
import { StateObjectRef } from '../../mol-state';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';

View File

@@ -9,7 +9,7 @@ import { CifWriter } from '../../mol-io/writer/cif';
import * as S from './schemas';
// import { getCategoryInstanceProvider } from './utils'
export default function create(allData: any) {
export function createMapping(allData: any) {
const mols = Object.keys(allData);
const enc = CifWriter.createEncoder();
enc.startDataBlock(mols[0]);

View File

@@ -6,7 +6,7 @@
import express from 'express';
import fetch from 'node-fetch';
import createMapping from './mapping';
import { createMapping } from './mapping';
async function getMappings(id: string) {
const data = await fetch(`https://www.ebi.ac.uk/pdbe/api/mappings/${id}`);

View File

@@ -5,7 +5,7 @@
*/
import fetch from 'node-fetch';
import createMapping from './mapping';
import { createMapping } from './mapping';
(async function () {
const data = await fetch('https://www.ebi.ac.uk/pdbe/api/mappings/1tqn?pretty=true');

View File

@@ -5,7 +5,8 @@
*/
import { Canvas3DProps } from '../../mol-canvas3d/canvas3d';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginContext } from '../../mol-plugin/context';
@@ -67,7 +68,7 @@ class LightingDemo {
init(target: string | HTMLElement) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
...DefaultPluginSpec(),
layout: {
initial: {
isExpanded: false,

View File

@@ -147,7 +147,7 @@
// adjust this number to make the animation faster or slower
// requires to "restart" the animation if changed
PluginWrapper.animate.modelIndex.maxFPS = 30;
PluginWrapper.animate.modelIndex.targetFps = 30;
addControl('Play To End', () => PluginWrapper.animate.modelIndex.onceForward());
addControl('Play To Start', () => PluginWrapper.animate.modelIndex.onceBackward());

View File

@@ -6,7 +6,8 @@
import * as ReactDOM from 'react-dom';
import { Canvas3DProps, DefaultCanvas3DParams } from '../../mol-canvas3d/canvas3d';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
import { PluginStateObject, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
@@ -46,7 +47,7 @@ class MolStarProteopediaWrapper {
customColorList?: number[]
}) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
...DefaultPluginSpec(),
animations: [
AnimateModelIndex
],
@@ -271,13 +272,17 @@ class MolStarProteopediaWrapper {
resetPosition: () => PluginCommands.Camera.Reset(this.plugin, { })
}
private animateModelIndexTargetFps() {
return Math.max(1, this.animate.modelIndex.targetFps | 0);
}
animate = {
modelIndex: {
maxFPS: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'loop', params: {} } }); },
targetFps: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'loop', params: {} } }); },
stop: () => this.plugin.managers.animation.stop()
}
}

View File

@@ -54,13 +54,13 @@ export function computeANVIL(structure: Structure, props: ANVILProps) {
});
}
const l = StructureElement.Location.create(void 0);
const centroidHelper = new CentroidHelper();
function initialize(structure: Structure, props: ANVILProps): ANVILContext {
const l = StructureElement.Location.create(structure);
const { label_atom_id, x, y, z } = StructureProperties.atom;
const elementCount = structure.polymerResidueCount;
centroidHelper.reset();
l.structure = structure;
let offsets = new Int32Array(elementCount);
let exposed = new Array<boolean>(elementCount);
@@ -328,6 +328,7 @@ namespace HphobHphil {
const testPoint = Vec3();
export function filtered(ctx: ANVILContext, label_comp_id: StructureElement.Property<string>, filter?: (test: Vec3) => boolean): HphobHphil {
const { offsets, exposed, structure } = ctx;
const l = StructureElement.Location.create(structure);
const { x, y, z } = StructureProperties.atom;
let hphob = 0;
let hphil = 0;

View File

@@ -15,7 +15,7 @@ import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/ac
import { Vec3 } from '../../mol-math/linear-algebra';
import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base';
import { CustomPropSymbol } from '../../mol-script/language/symbol';
import Type from '../../mol-script/language/type';
import { Type } from '../../mol-script/language/type';
export const MembraneOrientationParams = {
...ANVILParams

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -88,7 +88,6 @@ export const CellPackGenerateColorThemeProvider: ColorTheme.Provider<CellPackGen
isApplicable: (ctx: ThemeDataContext) => {
return (
!!ctx.structure && ctx.structure.elementCount > 0 &&
Model.TrajectoryInfo.get(ctx.structure.models[0]).size > 1 &&
!!CellPackInfoProvider.get(ctx.structure).value
);
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -396,21 +396,25 @@ export function createStructureFromCellPack(plugin: PluginContext, packing: Cell
}
if (ctx.shouldUpdate) await ctx.update(`${name} - units`);
const builder = Structure.Builder({ label: name });
const units: Unit[] = [];
let offsetInvariantId = 0;
let offsetChainGroupId = 0;
for (const s of structures) {
if (ctx.shouldUpdate) await ctx.update(`${s.label}`);
let maxInvariantId = 0;
let maxChainGroupId = 0;
for (const u of s.units) {
const invariantId = u.invariantId + offsetInvariantId;
const chainGroupId = u.chainGroupId + offsetChainGroupId;
if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId;
builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, Unit.Trait.None, invariantId);
units.push(Unit.create(units.length, invariantId, chainGroupId, u.traits, u.kind, u.model, u.conformation.operator, u.elements, u.props));
}
offsetInvariantId += maxInvariantId + 1;
offsetChainGroupId += maxChainGroupId + 1;
}
if (ctx.shouldUpdate) await ctx.update(`${name} - structure`);
const structure = builder.getStructure();
const structure = new Structure(units);
for( let i = 0, il = structure.models.length; i < il; ++i) {
Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i });
}

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import msgpackDecode from '../../mol-io/common/msgpack/decode';
import { decodeMsgPack } from '../../mol-io/common/msgpack/decode';
import { PluginContext } from '../../mol-plugin/context';
import { Task } from '../../mol-task';
import { inflate } from '../../mol-util/zip/zip';
@@ -41,7 +41,7 @@ export async function getG3dHeader(ctx: PluginContext, urlOrData: string | Uint8
for (; last >= 0; last--) {
if (data[last] !== 0) break;
}
const header = msgpackDecode(data.slice(0, last + 1));
const header = decodeMsgPack(data.slice(0, last + 1));
return header;
}
@@ -53,7 +53,7 @@ export async function getG3dDataBlock(ctx: PluginContext, header: G3dHeader, url
return {
header,
resolution,
data: msgpackDecode(unzipped)
data: decodeMsgPack(unzipped)
};
}

View File

@@ -16,7 +16,7 @@ import { MoleculeType } from '../../mol-model/structure/model/types';
import { LociLabelProvider } from '../../mol-plugin-state/manager/loci-label';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { CustomPropSymbol } from '../../mol-script/language/symbol';
import Type from '../../mol-script/language/type';
import { Type } from '../../mol-script/language/type';
import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base';
import { RuntimeContext, Task } from '../../mol-task';
import { objectForEach } from '../../mol-util/object';

View File

@@ -13,7 +13,7 @@ import { Model, ResidueIndex, Unit, IndexedCustomProperty } from '../../../mol-m
import { residueIdFields } from '../../../mol-model/structure/export/categories/atom_site';
import { StructureElement, CifExportContext, Structure } from '../../../mol-model/structure/structure';
import { CustomPropSymbol } from '../../../mol-script/language/symbol';
import Type from '../../../mol-script/language/type';
import { Type } from '../../../mol-script/language/type';
import { QuerySymbolRuntime } from '../../../mol-script/runtime/query/compiler';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { arraySetAdd } from '../../../mol-util/array';

View File

@@ -5,7 +5,7 @@
*/
import { AssemblySymmetryQuery, AssemblySymmetryQueryVariables } from '../graphql/types';
import query from '../graphql/symmetry.gql';
import { symmetry_gql } from '../graphql/symmetry.gql';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { Structure, Model, StructureSelection, QueryContext } from '../../../mol-model/structure';
@@ -66,7 +66,7 @@ export namespace AssemblySymmetry {
assembly_id: structure.units[0].conformation.operator.assembly?.id || '',
entry_id: structure.units[0].model.entryId
};
const result = await client.request(ctx.runtime, query, variables);
const result = await client.request(ctx.runtime, symmetry_gql, variables);
let value: AssemblySymmetryDataValue = [];
if (!result.data.assembly?.rcsb_struct_symmetry) {

View File

@@ -1,4 +1,4 @@
export default /* GraphQL */ `
export const symmetry_gql = /* GraphQL */ `
query AssemblySymmetry($assembly_id: String!, $entry_id: String!) {
assembly(assembly_id: $assembly_id, entry_id: $entry_id) {
rcsb_struct_symmetry {

View File

@@ -19,7 +19,7 @@ import { equalEps } from '../../../mol-math/linear-algebra/3d/common';
import { Vec3 } from '../../../mol-math/linear-algebra';
import { QuerySymbolRuntime } from '../../../mol-script/runtime/query/compiler';
import { CustomPropSymbol } from '../../../mol-script/language/symbol';
import Type from '../../../mol-script/language/type';
import { Type } from '../../../mol-script/language/type';
import { Asset } from '../../../mol-util/assets';
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';

View File

@@ -8,14 +8,14 @@
import { BehaviorSubject, Subscription } from 'rxjs';
import { now } from '../mol-util/now';
import { Vec3, Vec2 } from '../mol-math/linear-algebra';
import InputObserver, { ModifiersKeys, ButtonsType } from '../mol-util/input/input-observer';
import Renderer, { RendererStats, RendererParams } from '../mol-gl/renderer';
import { InputObserver, ModifiersKeys, ButtonsType } from '../mol-util/input/input-observer';
import { Renderer, RendererStats, RendererParams } from '../mol-gl/renderer';
import { GraphicsRenderObject } from '../mol-gl/render-object';
import { TrackballControls, TrackballControlsParams } from './controls/trackball';
import { Viewport } from './camera/util';
import { createContext, WebGLContext, getGLContext } from '../mol-gl/webgl/context';
import { Representation } from '../mol-repr/representation';
import Scene from '../mol-gl/scene';
import { Scene } from '../mol-gl/scene';
import { PickingId } from '../mol-geo/geometry/picking';
import { MarkerAction } from '../mol-util/marker-action';
import { Loci, EmptyLoci, isEmptyLoci } from '../mol-model/loci';
@@ -520,6 +520,7 @@ namespace Canvas3D {
drawCount: r.values.drawCount.ref.value,
instanceCount: r.values.instanceCount.ref.value,
materialId: r.materialId,
renderItemId: r.id,
})));
console.log(webgl.stats);
@@ -692,12 +693,10 @@ namespace Canvas3D {
reprCount,
resized,
setProps: (properties, doNotRequestDraw = false) => {
let props: PartialCanvas3DProps = typeof properties === 'function'
const props: PartialCanvas3DProps = typeof properties === 'function'
? produce(getProps(), properties)
: properties;
props = PD.normalizeParams(Canvas3DParams, props, 'children');
const cameraState: Partial<Camera.Snapshot> = Object.create(null);
if (props.camera && props.camera.mode !== undefined && props.camera.mode !== camera.state.mode) {
cameraState.mode = props.camera.mode;

View File

@@ -10,7 +10,7 @@
import { Quat, Vec2, Vec3, EPSILON } from '../../mol-math/linear-algebra';
import { Viewport } from '../camera/util';
import InputObserver, { DragInput, WheelInput, PinchInput, ButtonsType, ModifiersKeys } from '../../mol-util/input/input-observer';
import { InputObserver, DragInput, WheelInput, PinchInput, ButtonsType, ModifiersKeys } from '../../mol-util/input/input-observer';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Camera } from '../camera';
import { absMax } from '../../mol-math/misc';
@@ -36,8 +36,8 @@ export const DefaultTrackballBindings = {
export const TrackballControlsParams = {
noScroll: PD.Boolean(true, { isHidden: true }),
rotateSpeed: PD.Numeric(3.0, { min: 0.1, max: 10, step: 0.1 }),
zoomSpeed: PD.Numeric(6.0, { min: 0.1, max: 10, step: 0.1 }),
rotateSpeed: PD.Numeric(5.0, { min: 1, max: 10, step: 1 }),
zoomSpeed: PD.Numeric(7.0, { min: 1, max: 15, step: 1 }),
panSpeed: PD.Numeric(1.0, { min: 0.1, max: 5, step: 0.1 }),
spin: PD.Boolean(false, { description: 'Spin the 3D scene around the x-axis in view space' }),
@@ -138,7 +138,8 @@ namespace TrackballControls {
const dy = _rotCurr[1] - _rotPrev[1];
Vec3.set(rotMoveDir, dx, dy, 0);
const angle = Vec3.magnitude(rotMoveDir) * p.rotateSpeed * input.pixelRatio;
const aspectRatio = input.width / input.height;
const angle = Vec3.magnitude(rotMoveDir) * p.rotateSpeed * input.pixelRatio * aspectRatio;
if (angle) {
Vec3.sub(_eye, camera.position, camera.target);

View File

@@ -9,7 +9,7 @@ import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
import { addSphere } from '../../mol-geo/geometry/mesh/builder/sphere';
import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import Scene from '../../mol-gl/scene';
import { Scene } from '../../mol-gl/scene';
import { WebGLContext } from '../../mol-gl/webgl/context';
import { Sphere3D } from '../../mol-math/geometry';
import { Color } from '../../mol-util/color';
@@ -160,5 +160,5 @@ const instanceMaterialId = getNextMaterialId();
function createBoundingSphereRenderObject(mesh: Mesh, color: Color, materialId: number, transform?: TransformData) {
const values = Mesh.Utils.createValuesSimple(mesh, { alpha: 0.1, doubleSided: false }, color, 1, transform);
return createRenderObject('mesh', values, { visible: true, alphaFactor: 1, pickable: false, colorOnly: false, opaque: false, writeDepth: false, noClip: false }, materialId);
return createRenderObject('mesh', values, { disposed: false, visible: true, alphaFactor: 1, pickable: false, colorOnly: false, opaque: false, writeDepth: false, noClip: false }, materialId);
}

View File

@@ -5,7 +5,7 @@
*/
import { WebGLContext } from '../../mol-gl/webgl/context';
import Scene from '../../mol-gl/scene';
import { Scene } from '../../mol-gl/scene';
import { Camera, ICamera } from '../camera';
import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
import { Vec3, Mat4 } from '../../mol-math/linear-algebra';

View File

@@ -5,7 +5,7 @@
*/
import { WebGLContext } from '../../mol-gl/webgl/context';
import Scene from '../../mol-gl/scene';
import { Scene } from '../../mol-gl/scene';
import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
import { Vec3, Mat4, Mat3 } from '../../mol-math/linear-algebra';
import { addSphere } from '../../mol-geo/geometry/mesh/builder/sphere';

View File

@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import Scene from '../../mol-gl/scene';
import { Scene } from '../../mol-gl/scene';
import { WebGLContext } from '../../mol-gl/webgl/context';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { BoundingSphereHelper, DebugHelperParams } from './bounding-sphere-helper';

View File

@@ -7,7 +7,7 @@
import { PickingId } from '../../mol-geo/geometry/picking';
import { Representation } from '../../mol-repr/representation';
import InputObserver, { ModifiersKeys, ButtonsType } from '../../mol-util/input/input-observer';
import { InputObserver, ModifiersKeys, ButtonsType } from '../../mol-util/input/input-observer';
import { RxEventHelper } from '../../mol-util/rx-event-helper';
import { Vec2, Vec3 } from '../../mol-math/linear-algebra';
import { Camera } from '../camera';

View File

@@ -7,8 +7,8 @@
import { WebGLContext } from '../../mol-gl/webgl/context';
import { createNullRenderTarget, RenderTarget } from '../../mol-gl/webgl/render-target';
import Renderer from '../../mol-gl/renderer';
import Scene from '../../mol-gl/scene';
import { Renderer } from '../../mol-gl/renderer';
import { Scene } from '../../mol-gl/scene';
import { Texture } from '../../mol-gl/webgl/texture';
import { Camera, ICamera } from '../camera';
import { QuadSchema, QuadValues } from '../../mol-gl/compute/util';
@@ -20,8 +20,8 @@ import { ValueCell } from '../../mol-util';
import { Vec2 } from '../../mol-math/linear-algebra';
import { Helper } from '../helper/helper';
import quad_vert from '../../mol-gl/shader/quad.vert';
import depthMerge_frag from '../../mol-gl/shader/depth-merge.frag';
import { quad_vert } from '../../mol-gl/shader/quad.vert';
import { depthMerge_frag } from '../../mol-gl/shader/depth-merge.frag';
import { copy_frag } from '../../mol-gl/shader/copy.frag';
import { StereoCamera } from '../camera/stereo';
import { WboitPass } from './wboit';

View File

@@ -14,8 +14,8 @@ import { Texture } from '../../mol-gl/webgl/texture';
import { Vec2 } from '../../mol-math/linear-algebra';
import { ValueCell } from '../../mol-util';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import quad_vert from '../../mol-gl/shader/quad.vert';
import fxaa_frag from '../../mol-gl/shader/fxaa.frag';
import { quad_vert } from '../../mol-gl/shader/quad.vert';
import { fxaa_frag } from '../../mol-gl/shader/fxaa.frag';
import { Viewport } from '../camera/util';
import { RenderTarget } from '../../mol-gl/webgl/render-target';

View File

@@ -6,8 +6,8 @@
import { WebGLContext } from '../../mol-gl/webgl/context';
import { RenderTarget } from '../../mol-gl/webgl/render-target';
import Renderer from '../../mol-gl/renderer';
import Scene from '../../mol-gl/scene';
import { Renderer } from '../../mol-gl/renderer';
import { Scene } from '../../mol-gl/scene';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { DrawPass } from './draw';
import { PostprocessingParams } from './postprocessing';

View File

@@ -18,13 +18,13 @@ import { RenderTarget } from '../../mol-gl/webgl/render-target';
import { Camera } from '../../mol-canvas3d/camera';
import { PostprocessingProps } from './postprocessing';
import { DrawPass } from './draw';
import Renderer from '../../mol-gl/renderer';
import Scene from '../../mol-gl/scene';
import { Renderer } from '../../mol-gl/renderer';
import { Scene } from '../../mol-gl/scene';
import { Helper } from '../helper/helper';
import { StereoCamera } from '../camera/stereo';
import quad_vert from '../../mol-gl/shader/quad.vert';
import compose_frag from '../../mol-gl/shader/compose.frag';
import { quad_vert } from '../../mol-gl/shader/quad.vert';
import { compose_frag } from '../../mol-gl/shader/compose.frag';
const ComposeSchema = {
...QuadSchema,

View File

@@ -5,8 +5,8 @@
*/
import { PickingId } from '../../mol-geo/geometry/picking';
import Renderer from '../../mol-gl/renderer';
import Scene from '../../mol-gl/scene';
import { Renderer } from '../../mol-gl/renderer';
import { Scene } from '../../mol-gl/scene';
import { WebGLContext } from '../../mol-gl/webgl/context';
import { GraphicsRenderVariant } from '../../mol-gl/webgl/render-item';
import { RenderTarget } from '../../mol-gl/webgl/render-target';

View File

@@ -18,11 +18,11 @@ import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { RenderTarget } from '../../mol-gl/webgl/render-target';
import { DrawPass } from './draw';
import { ICamera } from '../../mol-canvas3d/camera';
import quad_vert from '../../mol-gl/shader/quad.vert';
import outlines_frag from '../../mol-gl/shader/outlines.frag';
import ssao_frag from '../../mol-gl/shader/ssao.frag';
import ssao_blur_frag from '../../mol-gl/shader/ssao-blur.frag';
import postprocessing_frag from '../../mol-gl/shader/postprocessing.frag';
import { quad_vert } from '../../mol-gl/shader/quad.vert';
import { outlines_frag } from '../../mol-gl/shader/outlines.frag';
import { ssao_frag } from '../../mol-gl/shader/ssao.frag';
import { ssaoBlur_frag } from '../../mol-gl/shader/ssao-blur.frag';
import { postprocessing_frag } from '../../mol-gl/shader/postprocessing.frag';
import { Framebuffer } from '../../mol-gl/webgl/framebuffer';
import { Color } from '../../mol-util/color';
import { FxaaParams, FxaaPass } from './fxaa';
@@ -143,7 +143,7 @@ function getSsaoBlurRenderable(ctx: WebGLContext, ssaoDepthTexture: Texture, dir
};
const schema = { ...SsaoBlurSchema };
const shaderCode = ShaderCode('ssao_blur', quad_vert, ssao_blur_frag);
const shaderCode = ShaderCode('ssao_blur', quad_vert, ssaoBlur_frag);
const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
return createComputeRenderable(renderItem, values);
@@ -237,10 +237,10 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
export const PostprocessingParams = {
occlusion: PD.MappedStatic('on', {
on: PD.Group({
samples: PD.Numeric(64, {min: 1, max: 256, step: 1}),
samples: PD.Numeric(32, {min: 1, max: 256, step: 1}),
radius: PD.Numeric(5, { min: 0, max: 10, step: 0.1 }, { description: 'Final radius is 2^x.' }),
bias: PD.Numeric(0.8, { min: 0, max: 3, step: 0.1 }),
blurKernelSize: PD.Numeric(20, { min: 1, max: 25, step: 2 }),
blurKernelSize: PD.Numeric(15, { min: 1, max: 25, step: 2 }),
}),
off: PD.Group({})
}, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
@@ -286,7 +286,11 @@ export class PostprocessingPass {
private readonly renderable: PostprocessingRenderable
private scale: number
constructor(private webgl: WebGLContext, drawPass: DrawPass) {
this.scale = 1 / this.webgl.pixelRatio;
const { colorTarget, depthTexture } = drawPass;
const width = colorTarget.getWidth();
const height = colorTarget.getHeight();
@@ -313,12 +317,15 @@ export class PostprocessingPass {
this.ssaoBlurFirstPassFramebuffer = webgl.resources.framebuffer();
this.ssaoBlurSecondPassFramebuffer = webgl.resources.framebuffer();
this.ssaoDepthTexture = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
this.ssaoDepthTexture.define(width, height);
const sw = Math.floor(width * this.scale);
const sh = Math.floor(height * this.scale);
this.ssaoDepthTexture = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'linear');
this.ssaoDepthTexture.define(sw, sh);
this.ssaoDepthTexture.attachFramebuffer(this.ssaoFramebuffer, 'color0');
this.ssaoDepthBlurProxyTexture = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
this.ssaoDepthBlurProxyTexture.define(width, height);
this.ssaoDepthBlurProxyTexture = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'linear');
this.ssaoDepthBlurProxyTexture.define(sw, sh);
this.ssaoDepthBlurProxyTexture.attachFramebuffer(this.ssaoBlurFirstPassFramebuffer, 'color0');
this.ssaoDepthTexture.attachFramebuffer(this.ssaoBlurSecondPassFramebuffer, 'color0');
@@ -326,22 +333,24 @@ export class PostprocessingPass {
this.ssaoRenderable = getSsaoRenderable(webgl, depthTexture);
this.ssaoBlurFirstPassRenderable = getSsaoBlurRenderable(webgl, this.ssaoDepthTexture, 'horizontal');
this.ssaoBlurSecondPassRenderable = getSsaoBlurRenderable(webgl, this.ssaoDepthBlurProxyTexture, 'vertical');
this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTexture, this.outlinesTarget.texture, this.ssaoDepthTexture);
this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTexture, this.outlinesTarget.texture, this.ssaoDepthTexture);
}
setSize(width: number, height: number) {
const [w, h] = this.renderable.values.uTexSize.ref.value;
if (width !== w || height !== h) {
const sw = Math.floor(width * this.scale);
const sh = Math.floor(height * this.scale);
this.target.setSize(width, height);
this.outlinesTarget.setSize(width, height);
this.ssaoDepthTexture.define(width, height);
this.ssaoDepthBlurProxyTexture.define(width, height);
this.ssaoDepthTexture.define(sw, sh);
this.ssaoDepthBlurProxyTexture.define(sw, sh);
ValueCell.update(this.renderable.values.uTexSize, Vec2.set(this.renderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.outlinesRenderable.values.uTexSize, Vec2.set(this.outlinesRenderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.ssaoRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.ssaoBlurFirstPassRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.ssaoBlurSecondPassRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.ssaoRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, sw, sh));
ValueCell.update(this.ssaoBlurFirstPassRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, sw, sh));
ValueCell.update(this.ssaoBlurSecondPassRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, sw, sh));
}
}
@@ -457,6 +466,14 @@ export class PostprocessingPass {
}
if (props.occlusion.name === 'on') {
const { x, y, width, height } = camera.viewport;
const sx = Math.floor(x * this.scale);
const sy = Math.floor(y * this.scale);
const sw = Math.floor(width * this.scale);
const sh = Math.floor(height * this.scale);
this.webgl.gl.viewport(sx, sy, sw, sh);
this.webgl.gl.scissor(sx, sy, sw, sh);
this.ssaoFramebuffer.bind();
this.ssaoRenderable.render();
@@ -465,6 +482,9 @@ export class PostprocessingPass {
this.ssaoBlurSecondPassFramebuffer.bind();
this.ssaoBlurSecondPassRenderable.render();
this.webgl.gl.viewport(x, y, width, height);
this.webgl.gl.scissor(x, y, width, height);
}
if (toDrawingBuffer) {

View File

@@ -13,8 +13,8 @@ import { WebGLContext } from '../../mol-gl/webgl/context';
import { createComputeRenderItem } from '../../mol-gl/webgl/render-item';
import { Texture } from '../../mol-gl/webgl/texture';
import { ValueCell } from '../../mol-util';
import quad_vert from '../../mol-gl/shader/quad.vert';
import evaluate_wboit_frag from '../../mol-gl/shader/evaluate-wboit.frag';
import { quad_vert } from '../../mol-gl/shader/quad.vert';
import { evaluateWboit_frag } from '../../mol-gl/shader/evaluate-wboit.frag';
import { Framebuffer } from '../../mol-gl/webgl/framebuffer';
import { Vec2 } from '../../mol-math/linear-algebra';
import { isDebugMode } from '../../mol-util/debug';
@@ -25,7 +25,7 @@ const EvaluateWboitSchema = {
tWboitB: TextureSpec('texture', 'rgba', 'float', 'nearest'),
uTexSize: UniformSpec('v2'),
};
const EvaluateWboitShaderCode = ShaderCode('evaluate-wboit', quad_vert, evaluate_wboit_frag);
const EvaluateWboitShaderCode = ShaderCode('evaluate-wboit', quad_vert, evaluateWboit_frag);
type EvaluateWboitRenderable = ComputeRenderable<Values<typeof EvaluateWboitSchema>>
function getEvaluateWboitRenderable(ctx: WebGLContext, wboitATexture: Texture, wboitBTexture: Texture): EvaluateWboitRenderable {

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Iterator from '../iterator';
import { Iterator } from '../iterator';
function iteratorToArray<T>(it: Iterator<T>): T[] {
const ret = [];

View File

@@ -5,9 +5,9 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import Database from './db/database';
import Table from './db/table';
import Column from './db/column';
import { Database } from './db/database';
import { Table } from './db/table';
import { Column } from './db/column';
import * as ColumnHelpers from './db/column-helpers';
type DatabaseCollection<T extends Database.Schema> = { [name: string]: Database<T> }

View File

@@ -6,8 +6,8 @@
*/
import * as ColumnHelpers from '../column-helpers';
import Column from '../column';
import Table from '../table';
import { Column } from '../column';
import { Table } from '../table';
describe('column', () => {
const cc = Column.ofConst(10, 2, Column.Schema.int);

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Column from './column';
import { Column } from './column';
export function getArrayBounds(rowCount: number, params?: Column.ToArrayParams<any>) {
const start = params && typeof params.start !== 'undefined' ? Math.max(Math.min(params.start, rowCount - 1), 0) : 0;

View File

@@ -230,7 +230,7 @@ namespace Column {
}
}
export default Column;
export { Column };
function createFirstIndexMapOfColumn<T>(c: Column<T>): Map<T, number> {
const map = new Map<T, number>();
@@ -364,7 +364,7 @@ function isIdentity(map: ArrayLike<number>, rowCount: number) {
}
function columnView<T>(c: Column<T>, map: ArrayLike<number>, checkIdentity: boolean): Column<T> {
if (!c.isDefined || c.rowCount === 0) return c;
if (c.rowCount === 0) return c;
if (checkIdentity && isIdentity(map, c.rowCount)) return c;
if (!!c.__array && typeof c.value(0) === typeof c.__array[0]) return arrayView(c, map);
return viewFull(c, map);

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Table from './table';
import { Table } from './table';
/** A collection of tables */
type Database<Schema extends Database.Schema> = {
@@ -41,4 +41,4 @@ namespace Database {
}
}
export default Database;
export { Database };

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Column from './column';
import { Column } from './column';
import { sortArray } from '../util/sort';
import { StringBuilder } from '../../mol-util';
@@ -280,4 +280,4 @@ namespace Table {
}
}
export default Table;
export { Table };

View File

@@ -6,7 +6,7 @@
import * as DB from './db';
import * as Int from './int';
import Iterator from './iterator';
import { Iterator } from './iterator';
import * as Util from './util';
import * as Generic from './generic';

View File

@@ -4,13 +4,13 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Interval from './int/interval';
import OrderedSet from './int/ordered-set';
import Segmentation from './int/segmentation';
import SortedArray from './int/sorted-array';
import Tuple from './int/tuple';
import LinkedIndex from './int/linked-index';
import IntMap from './int/map';
import Iterator from './iterator';
import { Interval } from './int/interval';
import { OrderedSet } from './int/ordered-set';
import { Segmentation } from './int/segmentation';
import { SortedArray } from './int/sorted-array';
import { IntTuple as Tuple } from './int/tuple';
import { LinkedIndex } from './int/linked-index';
import { IntMap } from './int/map';
import { Iterator } from './iterator';
export { Interval, OrderedSet, Segmentation, SortedArray, Tuple, LinkedIndex, IntMap, Iterator };

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Interval from '../interval';
import { Interval } from '../interval';
describe('interval', () => {
function testI(name: string, a: Interval, b: Interval) {

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import LinkedIndex from '../linked-index';
import { LinkedIndex } from '../linked-index';
describe('linked-index', () => {
it('initial state', () => {

View File

@@ -4,9 +4,9 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import OrderedSet from '../ordered-set';
import Interval from '../interval';
import SortedArray from '../sorted-array';
import { OrderedSet } from '../ordered-set';
import { Interval } from '../interval';
import { SortedArray } from '../sorted-array';
describe('ordered set', () => {
function ordSetToArray(set: OrderedSet) {

View File

@@ -4,9 +4,9 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import OrderedSet from '../ordered-set';
import Interval from '../interval';
import Segmentation from '../segmentation';
import { OrderedSet } from '../ordered-set';
import { Interval } from '../interval';
import { Segmentation } from '../segmentation';
describe('segments', () => {
const data = OrderedSet.ofSortedArray([4, 9, 10, 11, 14, 15, 16]);

View File

@@ -4,8 +4,8 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Interval from '../interval';
import SortedArray from '../sorted-array';
import { Interval } from '../interval';
import { SortedArray } from '../sorted-array';
describe('sortedArray', () => {
function testI(name: string, a: Interval, b: Interval) {

View File

@@ -4,9 +4,9 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import SortedRanges from '../sorted-ranges';
import OrderedSet from '../ordered-set';
import SortedArray from '../sorted-array';
import { SortedRanges } from '../sorted-ranges';
import { OrderedSet } from '../ordered-set';
import { SortedArray } from '../sorted-array';
describe('rangesArray', () => {
function test(name: string, a: any, b: any) {

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import IntTuple from '../tuple';
import { IntTuple } from '../tuple';
describe('int pair', () => {
it('works', () => {

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Tuple from '../tuple';
import { IntTuple as Tuple } from '../tuple';
export const Empty = Tuple.Zero;
export function ofRange(min: number, max: number) { return max < min ? Tuple.create(min, min) : Tuple.create(min, max + 1); }

View File

@@ -4,8 +4,8 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import S from '../sorted-array';
import I from '../interval';
import { SortedArray as S } from '../sorted-array';
import { Interval as I } from '../interval';
type OrderedSetImpl = I | S
type Nums = ArrayLike<number>

View File

@@ -4,11 +4,11 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Iterator from '../../iterator';
import OrderedSet from '../ordered-set';
import Interval from '../interval';
import SortedArray from '../sorted-array';
import Segs from '../segmentation';
import { Iterator } from '../../iterator';
import { OrderedSet } from '../ordered-set';
import { Interval } from '../interval';
import { SortedArray } from '../sorted-array';
import { Segmentation as Segs } from '../segmentation';
interface Segmentation {
/** Segments stored as a sorted array */

View File

@@ -5,7 +5,7 @@
*/
import { sortArray, hash3, hash4, createRangeArray } from '../../util';
import Interval from '../interval';
import { Interval } from '../interval';
type Nums = ArrayLike<number>

View File

@@ -60,4 +60,4 @@ namespace Interval {
/** Interval describing a range [min, max] of values */
interface Interval<T extends number = number> { '@type': 'int-interval' }
export default Interval;
export { Interval };

View File

@@ -55,4 +55,4 @@ class LinkedIndexImpl implements LinkedIndex {
}
}
export default LinkedIndex;
export { LinkedIndex };

View File

@@ -58,4 +58,4 @@ namespace IntMap {
}
}
export default IntMap;
export { IntMap };

View File

@@ -5,8 +5,8 @@
*/
import * as Base from './impl/ordered-set';
import Interval from './interval';
import SortedArray from './sorted-array';
import { Interval } from './interval';
import { SortedArray } from './sorted-array';
namespace OrderedSet {
export const Empty: OrderedSet = Base.Empty as any;
@@ -82,4 +82,4 @@ namespace OrderedSet {
type OrderedSet<T extends number = number> = SortedArray<T> | Interval<T>
export default OrderedSet;
export { OrderedSet };

View File

@@ -4,8 +4,8 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import Interval from './interval';
import OrderedSet from './ordered-set';
import { Interval } from './interval';
import { OrderedSet } from './ordered-set';
import * as Impl from './impl/segmentation';
namespace Segmentation {
@@ -33,4 +33,4 @@ interface Segmentation<T extends number = number, I extends number = number> {
readonly count: number
}
export default Segmentation;
export { Segmentation };

View File

@@ -5,7 +5,7 @@
*/
import * as Impl from './impl/sorted-array';
import Interval from './interval';
import { Interval } from './interval';
namespace SortedArray {
export const Empty: SortedArray = Impl.Empty as any;
@@ -54,4 +54,4 @@ namespace SortedArray {
interface SortedArray<T extends number = number> extends ArrayLike<T> { '@type': 'int-sorted-array' }
export default SortedArray;
export { SortedArray };

View File

@@ -5,7 +5,7 @@
*/
import { Segmentation, OrderedSet, SortedArray, Interval } from '../int';
import _Iterator from '../iterator';
import { Iterator as _Iterator } from '../iterator';
/** Pairs of min and max indices of sorted, non-overlapping ranges */
type SortedRanges<T extends number = number> = SortedArray<T>
@@ -115,4 +115,4 @@ namespace SortedRanges {
}
}
export default SortedRanges;
export { SortedRanges };

View File

@@ -80,4 +80,4 @@ namespace IntTuple {
}
}
export default IntTuple;
export { IntTuple };

View File

@@ -117,4 +117,4 @@ namespace Iterator {
}
}
export default Iterator;
export { Iterator };

View File

@@ -6,7 +6,7 @@
// adpated from https://github.com/dankogai/js-combinatorics, MIT 2013-2016 Dan Kogai
import Iterator from '../iterator';
import { Iterator } from '../iterator';
function P(m: number, n: number) {
let p = 1;

View File

@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import Iterator from '../iterator';
import { Iterator } from '../iterator';
import { OrderedSet, Interval, Segmentation } from '../int';
/** Emits a segment of length one for each element in the interval that is also in the set */

View File

@@ -75,6 +75,7 @@ export namespace BaseGeometry {
export function createRenderableState(props: Partial<PD.Values<Params>> = {}): RenderableState {
const opaque = props.alpha === undefined ? true : props.alpha === 1;
return {
disposed: false,
visible: true,
alphaFactor: 1,
pickable: true,

View File

@@ -89,7 +89,7 @@ export namespace Geometry {
const [x, y, z] = geometry.gridDimension.ref.value;
return x * y * z;
case 'image': return 4;
case 'texture-mesh': return geometry.vertexCount / 3;
case 'texture-mesh': return geometry.vertexCount;
}
}

View File

@@ -21,7 +21,6 @@ import { TextureMeshValues } from '../../../mol-gl/renderable/texture-mesh';
import { calculateTransformBoundingSphere } from '../../../mol-gl/renderable/util';
import { Texture } from '../../../mol-gl/webgl/texture';
import { Vec2, Vec4 } from '../../../mol-math/linear-algebra';
import { fillSerial } from '../../../mol-util/array';
import { createEmptyClipping } from '../clipping-data';
import { NullLocation } from '../../../mol-model/location';
@@ -34,22 +33,22 @@ export interface TextureMesh {
groupCount: number,
readonly geoTextureDim: ValueCell<Vec2>,
/** texture has vertex positions in XYZ and group id in W */
readonly vertexGroupTexture: ValueCell<Texture>,
readonly vertexTexture: ValueCell<Texture>,
readonly groupTexture: ValueCell<Texture>,
readonly normalTexture: ValueCell<Texture>,
readonly boundingSphere: Sphere3D
}
export namespace TextureMesh {
export function create(vertexCount: number, groupCount: number, vertexGroupTexture: Texture, normalTexture: Texture, boundingSphere: Sphere3D, textureMesh?: TextureMesh): TextureMesh {
const width = vertexGroupTexture.getWidth();
const height = vertexGroupTexture.getHeight();
export function create(vertexCount: number, groupCount: number, vertexTexture: Texture, groupTexture: Texture, normalTexture: Texture, boundingSphere: Sphere3D, textureMesh?: TextureMesh): TextureMesh {
const width = vertexTexture.getWidth();
const height = vertexTexture.getHeight();
if (textureMesh) {
textureMesh.vertexCount = vertexCount;
textureMesh.groupCount = groupCount;
ValueCell.update(textureMesh.geoTextureDim, Vec2.set(textureMesh.geoTextureDim.ref.value, width, height));
ValueCell.update(textureMesh.vertexGroupTexture, vertexGroupTexture);
ValueCell.update(textureMesh.vertexTexture, vertexTexture);
ValueCell.update(textureMesh.normalTexture, normalTexture);
Sphere3D.copy(textureMesh.boundingSphere, boundingSphere);
return textureMesh;
@@ -59,7 +58,8 @@ export namespace TextureMesh {
vertexCount,
groupCount,
geoTextureDim: ValueCell.create(Vec2.create(width, height)),
vertexGroupTexture: ValueCell.create(vertexGroupTexture),
vertexTexture: ValueCell.create(vertexTexture),
groupTexture: ValueCell.create(groupTexture),
normalTexture: ValueCell.create(normalTexture),
boundingSphere: Sphere3D.clone(boundingSphere),
};
@@ -102,18 +102,17 @@ export namespace TextureMesh {
const transparency = createEmptyTransparency();
const clipping = createEmptyClipping();
const counts = { drawCount: textureMesh.vertexCount, vertexCount: textureMesh.vertexCount / 3, groupCount, instanceCount };
const counts = { drawCount: textureMesh.vertexCount, vertexCount: textureMesh.vertexCount, groupCount, instanceCount };
const invariantBoundingSphere = Sphere3D.clone(textureMesh.boundingSphere);
const boundingSphere = calculateTransformBoundingSphere(invariantBoundingSphere, transform.aTransform.ref.value, instanceCount);
return {
uGeoTexDim: textureMesh.geoTextureDim,
tPositionGroup: textureMesh.vertexGroupTexture,
tPosition: textureMesh.vertexTexture,
tGroup: textureMesh.groupTexture,
tNormal: textureMesh.normalTexture,
// aGroup is used as a vertex index here and the group id is retirieved from tPositionGroup
aGroup: ValueCell.create(fillSerial(new Float32Array(textureMesh.vertexCount))),
boundingSphere: ValueCell.create(boundingSphere),
invariantBoundingSphere: ValueCell.create(invariantBoundingSphere),
uInvariantBoundingSphere: ValueCell.create(Vec4.ofSphere(invariantBoundingSphere)),
@@ -148,11 +147,6 @@ export namespace TextureMesh {
ValueCell.updateIfChanged(values.dFlipSided, props.flipSided);
ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
if (values.drawCount.ref.value > values.aGroup.ref.value.length) {
// console.log('updating vertex ids in aGroup to handle larger drawCount')
ValueCell.update(values.aGroup, fillSerial(new Float32Array(values.drawCount.ref.value)));
}
}
function updateBoundingSphere(values: TextureMeshValues, textureMesh: TextureMesh) {

View File

@@ -10,14 +10,14 @@ import { Camera } from '../../mol-canvas3d/camera';
import { Vec3, Mat4, Vec4 } from '../../mol-math/linear-algebra';
import { ValueCell } from '../../mol-util';
import Renderer from '../renderer';
import { Renderer } from '../renderer';
import { createValueColor } from '../../mol-geo/geometry/color-data';
import { createValueSize } from '../../mol-geo/geometry/size-data';
import { createContext } from '../webgl/context';
import { RenderableState } from '../renderable';
import { createRenderObject } from '../render-object';
import { PointsValues } from '../renderable/points';
import Scene from '../scene';
import { Scene } from '../scene';
import { createEmptyMarkers } from '../../mol-geo/geometry/marker-data';
import { fillSerial } from '../../mol-util/array';
import { Color } from '../../mol-util/color';
@@ -89,6 +89,7 @@ function createPoints() {
uPointEdgeBleach: ValueCell.create(0.5),
};
const state: RenderableState = {
disposed: false,
visible: true,
alphaFactor: 1,
pickable: true,

View File

@@ -7,8 +7,8 @@
import { RenderableSchema, Values, UnboxedValues, UniformSpec, TextureSpec, DefineSpec, RenderableValues } from '../renderable/schema';
import { WebGLContext } from '../webgl/context';
import { getRegularGrid3dDelta, RegularGrid3d } from '../../mol-math/geometry/common';
import shader_template from '../shader/util/grid3d-template.frag';
import quad_vert from '../shader/quad.vert';
import { grid3dTemplate_frag } from '../shader/util/grid3d-template.frag';
import { quad_vert } from '../shader/quad.vert';
import { ShaderCode } from '../shader-code';
import { UUID, ValueCell } from '../../mol-util';
import { objectForEach } from '../../mol-util/object';
@@ -74,7 +74,7 @@ export function createGrid3dComputeRenderable<S extends RenderableSchema, P, CS>
if (isBound) uniforms.push(`#endif`);
});
const code = shader_template
const code = grid3dTemplate_frag
.replace('{UNIFORMS}', uniforms.join('\n'))
.replace('{UTILS}', spec.utilCode ?? '')
.replace('{MAIN}', spec.mainCode)

View File

@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { createComputeRenderable } from '../../renderable';
import { createComputeRenderable, ComputeRenderable } from '../../renderable';
import { WebGLContext } from '../../webgl/context';
import { createComputeRenderItem } from '../../webgl/render-item';
import { Values, TextureSpec, UniformSpec } from '../../renderable/schema';
@@ -16,43 +16,48 @@ import { Vec2, Vec3 } from '../../../mol-math/linear-algebra';
import { getHistopyramidSum } from './sum';
import { Framebuffer } from '../../../mol-gl/webgl/framebuffer';
import { isPowerOfTwo } from '../../../mol-math/misc';
import quad_vert from '../../../mol-gl/shader/quad.vert';
import reduction_frag from '../../../mol-gl/shader/histogram-pyramid/reduction.frag';
import { quad_vert } from '../../../mol-gl/shader/quad.vert';
import { reduction_frag } from '../../../mol-gl/shader/histogram-pyramid/reduction.frag';
import { isWebGL2 } from '../../webgl/compat';
const HistopyramidReductionSchema = {
...QuadSchema,
tInputLevel: TextureSpec('texture', 'rgba', 'float', 'nearest'),
tPreviousLevel: TextureSpec('texture', 'rgba', 'float', 'nearest'),
uSize: UniformSpec('f'),
uTexSize: UniformSpec('f'),
uFirst: UniformSpec('b'),
};
type HistopyramidReductionValues = Values<typeof HistopyramidReductionSchema>
const HistogramPyramidName = 'histogram-pyramid';
function getHistopyramidReductionRenderable(ctx: WebGLContext, initialTexture: Texture) {
function getHistopyramidReductionRenderable(ctx: WebGLContext, inputLevel: Texture, previousLevel: Texture): ComputeRenderable<HistopyramidReductionValues> {
if (ctx.namedComputeRenderables[HistogramPyramidName]) {
const v = ctx.namedComputeRenderables[HistogramPyramidName].values;
const v = ctx.namedComputeRenderables[HistogramPyramidName].values as HistopyramidReductionValues;
ValueCell.update(v.tPreviousLevel, initialTexture);
ValueCell.update(v.tInputLevel, inputLevel);
ValueCell.update(v.tPreviousLevel, previousLevel);
ctx.namedComputeRenderables[HistogramPyramidName].update();
} else {
ctx.namedComputeRenderables[HistogramPyramidName] = createHistopyramidReductionRenderable(ctx, initialTexture);
ctx.namedComputeRenderables[HistogramPyramidName] = createHistopyramidReductionRenderable(ctx, inputLevel, previousLevel);
}
return ctx.namedComputeRenderables[HistogramPyramidName];
}
function createHistopyramidReductionRenderable(ctx: WebGLContext, initialTexture: Texture) {
const values: Values<typeof HistopyramidReductionSchema> = {
function createHistopyramidReductionRenderable(ctx: WebGLContext, inputLevel: Texture, previousLevel: Texture) {
const values: HistopyramidReductionValues = {
...QuadValues,
tPreviousLevel: ValueCell.create(initialTexture),
tInputLevel: ValueCell.create(inputLevel),
tPreviousLevel: ValueCell.create(previousLevel),
uSize: ValueCell.create(0),
uTexSize: ValueCell.create(0),
uFirst: ValueCell.create(true),
};
const schema = { ...HistopyramidReductionSchema };
const shaderCode = ShaderCode('reduction', quad_vert, reduction_frag);
const shaderCode = ShaderCode('reduction', quad_vert, reduction_frag, {}, { 0: 'ivec4' });
const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
return createComputeRenderable(renderItem, values);
@@ -64,11 +69,13 @@ function getLevelTextureFramebuffer(ctx: WebGLContext, level: number) {
let textureFramebuffer = LevelTexturesFramebuffers[level];
const size = Math.pow(2, level);
if (textureFramebuffer === undefined) {
const texture = getTexture(`level${level}`, ctx, 'image-float32', 'rgba', 'float', 'nearest');
const texture = ctx.isWebGL2
? getTexture(`level${level}`, ctx, 'image-int32', 'alpha', 'int', 'nearest')
: getTexture(`level${level}`, ctx, 'image-uint8', 'rgba', 'ubyte', 'nearest');
texture.define(size, size);
const framebuffer = getFramebuffer(`level${level}`, ctx);
texture.attachFramebuffer(framebuffer, 0);
textureFramebuffer = { texture, framebuffer };
textureFramebuffer.texture.define(size, size);
LevelTexturesFramebuffers[level] = textureFramebuffer;
}
return textureFramebuffer;
@@ -122,20 +129,29 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture,
// This part set the levels
const levels = Math.ceil(Math.log(w) / Math.log(2));
const maxSize = Math.pow(2, levels);
// console.log('levels', levels, 'maxSize', maxSize, 'input', w);
const maxSizeX = Math.pow(2, levels);
const maxSizeY = Math.pow(2, levels - 1);
// console.log('levels', levels, 'maxSize', maxSize, [maxSizeX, maxSizeY], 'input', w);
const pyramidTex = getTexture('pyramid', ctx, 'image-float32', 'rgba', 'float', 'nearest');
pyramidTex.define(maxSize, maxSize);
const pyramidTex = ctx.isWebGL2
? getTexture('pyramid', ctx, 'image-int32', 'alpha', 'int', 'nearest')
: getTexture('pyramid', ctx, 'image-uint8', 'rgba', 'ubyte', 'nearest');
pyramidTex.define(maxSizeX, maxSizeY);
const framebuffer = getFramebuffer('pyramid', ctx);
pyramidTex.attachFramebuffer(framebuffer, 0);
gl.viewport(0, 0, maxSize, maxSize);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, 0, maxSizeX, maxSizeY);
if (isWebGL2(gl)) {
gl.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
} else {
gl.clear(gl.COLOR_BUFFER_BIT);
}
const levelTexturesFramebuffers: TextureFramebuffer[] = [];
for (let i = 0; i < levels; ++i) levelTexturesFramebuffers.push(getLevelTextureFramebuffer(ctx, i));
const renderable = getHistopyramidReductionRenderable(ctx, inputTexture);
const renderable = getHistopyramidReductionRenderable(ctx, inputTexture, levelTexturesFramebuffers[0].texture);
ctx.state.currentRenderItemId = -1;
setRenderingDefaults(ctx);
@@ -146,7 +162,7 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture,
tf.framebuffer.bind();
const size = Math.pow(2, currLevel);
// console.log('size', size, 'draw-level', currLevel, 'read-level', levels - i)
// console.log('size', size, 'draw-level', currLevel, 'read-level', levels - i);
ValueCell.update(renderable.values.uSize, Math.pow(2, i + 1) / maxSize);
ValueCell.update(renderable.values.uTexSize, size);
@@ -158,7 +174,11 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture,
ctx.state.currentRenderItemId = -1;
gl.viewport(0, 0, size, size);
gl.scissor(0, 0, size, size);
gl.clear(gl.COLOR_BUFFER_BIT);
if (isWebGL2(gl)) {
gl.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
} else {
gl.clear(gl.COLOR_BUFFER_BIT);
}
gl.scissor(0, 0, gridTexDim[0], gridTexDim[1]);
renderable.render();
@@ -179,7 +199,7 @@ export function createHistogramPyramid(ctx: WebGLContext, inputTexture: Texture,
const count = Math.max(1, getHistopyramidSum(ctx, levelTexturesFramebuffers[0].texture));
const height = Math.ceil(count / Math.pow(2, levels));
// const scale = Vec2.create(maxSize / inputTexture.width, maxSize / inputTexture.height);
// console.log('height', height, 'finalCount', finalCount, 'scale', scale);
// console.log('height', height, 'finalCount', count, 'scale', scale);
return { pyramidTex, count, height, levels, scale };
}

View File

@@ -1,10 +1,10 @@
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { createComputeRenderable } from '../../renderable';
import { ComputeRenderable, createComputeRenderable } from '../../renderable';
import { WebGLContext } from '../../webgl/context';
import { createComputeRenderItem } from '../../webgl/render-item';
import { Values, TextureSpec } from '../../renderable/schema';
@@ -13,19 +13,21 @@ import { ShaderCode } from '../../../mol-gl/shader-code';
import { ValueCell } from '../../../mol-util';
import { decodeFloatRGB } from '../../../mol-util/float-packing';
import { QuadSchema, QuadValues } from '../util';
import quad_vert from '../../../mol-gl/shader/quad.vert';
import sum_frag from '../../../mol-gl/shader/histogram-pyramid/sum.frag';
import { quad_vert } from '../../../mol-gl/shader/quad.vert';
import { sum_frag } from '../../../mol-gl/shader/histogram-pyramid/sum.frag';
import { isWebGL2 } from '../../webgl/compat';
const HistopyramidSumSchema = {
...QuadSchema,
tTexture: TextureSpec('texture', 'rgba', 'float', 'nearest'),
};
type HistopyramidSumValues = Values<typeof HistopyramidSumSchema>
const HistopyramidSumName = 'histopyramid-sum';
function getHistopyramidSumRenderable(ctx: WebGLContext, texture: Texture) {
function getHistopyramidSumRenderable(ctx: WebGLContext, texture: Texture): ComputeRenderable<HistopyramidSumValues> {
if (ctx.namedComputeRenderables[HistopyramidSumName]) {
const v = ctx.namedComputeRenderables[HistopyramidSumName].values;
const v = ctx.namedComputeRenderables[HistopyramidSumName].values as HistopyramidSumValues;
ValueCell.update(v.tTexture, texture);
@@ -37,13 +39,13 @@ function getHistopyramidSumRenderable(ctx: WebGLContext, texture: Texture) {
}
function createHistopyramidSumRenderable(ctx: WebGLContext, texture: Texture) {
const values: Values<typeof HistopyramidSumSchema> = {
const values: HistopyramidSumValues = {
...QuadValues,
tTexture: ValueCell.create(texture),
};
const schema = { ...HistopyramidSumSchema };
const shaderCode = ShaderCode('sum', quad_vert, sum_frag);
const shaderCode = ShaderCode('sum', quad_vert, sum_frag, {}, { 0: 'ivec4' });
const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
return createComputeRenderable(renderItem, values);
@@ -60,7 +62,9 @@ function setRenderingDefaults(ctx: WebGLContext) {
state.clearColor(0, 0, 0, 0);
}
const sumArray = new Uint8Array(4);
const sumBytes = new Uint8Array(4);
const sumInts = new Int32Array(4);
export function getHistopyramidSum(ctx: WebGLContext, pyramidTopTexture: Texture) {
const { gl, resources } = ctx;
@@ -73,7 +77,9 @@ export function getHistopyramidSum(ctx: WebGLContext, pyramidTopTexture: Texture
const framebuffer = ctx.namedFramebuffers[HistopyramidSumName];
if (!ctx.namedTextures[HistopyramidSumName]) {
ctx.namedTextures[HistopyramidSumName] = resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
ctx.namedTextures[HistopyramidSumName] = isWebGL2(gl)
? resources.texture('image-int32', 'rgba', 'int', 'nearest')
: resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
ctx.namedTextures[HistopyramidSumName].define(1, 1);
}
const sumTexture = ctx.namedTextures[HistopyramidSumName];
@@ -84,8 +90,11 @@ export function getHistopyramidSum(ctx: WebGLContext, pyramidTopTexture: Texture
gl.viewport(0, 0, 1, 1);
renderable.render();
gl.finish();
ctx.readPixels(0, 0, 1, 1, sumArray);
ctx.readPixels(0, 0, 1, 1, isWebGL2(gl) ? sumInts : sumBytes);
ctx.unbindFramebuffer();
return decodeFloatRGB(sumArray[0], sumArray[1], sumArray[2]);
return isWebGL2(gl)
? sumInts[0]
: decodeFloatRGB(sumBytes[0], sumBytes[1], sumBytes[2]);
}

View File

@@ -4,7 +4,7 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { createComputeRenderable } from '../../renderable';
import { ComputeRenderable, createComputeRenderable } from '../../renderable';
import { WebGLContext } from '../../webgl/context';
import { createComputeRenderItem } from '../../webgl/render-item';
import { Values, TextureSpec, UniformSpec } from '../../renderable/schema';
@@ -14,8 +14,8 @@ import { ValueCell } from '../../../mol-util';
import { Vec3, Vec2 } from '../../../mol-math/linear-algebra';
import { QuadSchema, QuadValues } from '../util';
import { getTriCount } from './tables';
import quad_vert from '../../../mol-gl/shader/quad.vert';
import active_voxels_frag from '../../../mol-gl/shader/marching-cubes/active-voxels.frag';
import { quad_vert } from '../../../mol-gl/shader/quad.vert';
import { activeVoxels_frag } from '../../../mol-gl/shader/marching-cubes/active-voxels.frag';
const ActiveVoxelsSchema = {
...QuadSchema,
@@ -29,12 +29,13 @@ const ActiveVoxelsSchema = {
uScale: UniformSpec('v2'),
};
type ActiveVoxelsValues = Values<typeof ActiveVoxelsSchema>
const ActiveVoxelsName = 'active-voxels';
function getActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, isoValue: number, scale: Vec2) {
function getActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, isoValue: number, scale: Vec2): ComputeRenderable<ActiveVoxelsValues> {
if (ctx.namedComputeRenderables[ActiveVoxelsName]) {
const v = ctx.namedComputeRenderables[ActiveVoxelsName].values;
const v = ctx.namedComputeRenderables[ActiveVoxelsName].values as ActiveVoxelsValues;
ValueCell.update(v.uQuadScale, scale);
ValueCell.update(v.tVolumeData, volumeData);
@@ -51,7 +52,7 @@ function getActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gridD
}
function createActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, isoValue: number, scale: Vec2) {
const values: Values<typeof ActiveVoxelsSchema> = {
const values: ActiveVoxelsValues = {
...QuadValues,
tTriCount: ValueCell.create(getTriCount()),
@@ -64,7 +65,7 @@ function createActiveVoxelsRenderable(ctx: WebGLContext, volumeData: Texture, gr
};
const schema = { ...ActiveVoxelsSchema };
const shaderCode = ShaderCode('active-voxels', quad_vert, active_voxels_frag);
const shaderCode = ShaderCode('active-voxels', quad_vert, activeVoxels_frag);
const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
return createComputeRenderable(renderItem, values);

View File

@@ -4,19 +4,22 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { createComputeRenderable } from '../../renderable';
import { ComputeRenderable, createComputeRenderable } from '../../renderable';
import { WebGLContext } from '../../webgl/context';
import { createComputeRenderItem } from '../../webgl/render-item';
import { Values, TextureSpec, UniformSpec } from '../../renderable/schema';
import { Values, TextureSpec, UniformSpec, DefineSpec } from '../../renderable/schema';
import { Texture } from '../../../mol-gl/webgl/texture';
import { ShaderCode } from '../../../mol-gl/shader-code';
import { ValueCell } from '../../../mol-util';
import { Vec3, Vec2, Mat4 } from '../../../mol-math/linear-algebra';
import { QuadSchema, QuadValues } from '../util';
import { HistogramPyramid } from '../histogram-pyramid/reduction';
import { createHistogramPyramid, HistogramPyramid } from '../histogram-pyramid/reduction';
import { getTriIndices } from './tables';
import quad_vert from '../../../mol-gl/shader/quad.vert';
import isosurface_frag from '../../../mol-gl/shader/marching-cubes/isosurface.frag';
import { quad_vert } from '../../../mol-gl/shader/quad.vert';
import { isosurface_frag } from '../../../mol-gl/shader/marching-cubes/isosurface.frag';
import { calcActiveVoxels } from './active-voxels';
import { isWebGL2 } from '../../webgl/compat';
import { Scheduler } from '../../../mol-task';
const IsosurfaceSchema = {
...QuadSchema,
@@ -34,15 +37,17 @@ const IsosurfaceSchema = {
uGridDim: UniformSpec('v3'),
uGridTexDim: UniformSpec('v3'),
uGridTransform: UniformSpec('m4'),
uScale: UniformSpec('v2'),
dPackedGroup: DefineSpec('boolean')
};
type IsosurfaceValues = Values<typeof IsosurfaceSchema>
const IsosurfaceName = 'isosurface';
function getIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Texture, activeVoxelsBase: Texture, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, transform: Mat4, isoValue: number, levels: number, scale: Vec2, count: number, height: number) {
function getIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Texture, activeVoxelsBase: Texture, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, transform: Mat4, isoValue: number, levels: number, scale: Vec2, count: number, packedGroup: boolean): ComputeRenderable<IsosurfaceValues> {
if (ctx.namedComputeRenderables[IsosurfaceName]) {
const v = ctx.namedComputeRenderables[IsosurfaceName].values;
const v = ctx.namedComputeRenderables[IsosurfaceName].values as IsosurfaceValues;
ValueCell.update(v.tActiveVoxelsPyramid, activeVoxelsPyramid);
ValueCell.update(v.tActiveVoxelsBase, activeVoxelsBase);
@@ -58,16 +63,18 @@ function getIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Texture
ValueCell.update(v.uGridTransform, transform);
ValueCell.update(v.uScale, scale);
ValueCell.update(v.dPackedGroup, packedGroup);
ctx.namedComputeRenderables[IsosurfaceName].update();
} else {
ctx.namedComputeRenderables[IsosurfaceName] = createIsosurfaceRenderable(ctx, activeVoxelsPyramid, activeVoxelsBase, volumeData, gridDim, gridTexDim, transform, isoValue, levels, scale, count, height);
ctx.namedComputeRenderables[IsosurfaceName] = createIsosurfaceRenderable(ctx, activeVoxelsPyramid, activeVoxelsBase, volumeData, gridDim, gridTexDim, transform, isoValue, levels, scale, count, packedGroup);
}
return ctx.namedComputeRenderables[IsosurfaceName];
}
function createIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Texture, activeVoxelsBase: Texture, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, transform: Mat4, isoValue: number, levels: number, scale: Vec2, count: number, height: number) {
function createIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Texture, activeVoxelsBase: Texture, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, transform: Mat4, isoValue: number, levels: number, scale: Vec2, count: number, packedGroup: boolean) {
// console.log('uSize', Math.pow(2, levels))
const values: Values<typeof IsosurfaceSchema> = {
const values: IsosurfaceValues = {
...QuadValues,
tTriIndices: ValueCell.create(getTriIndices()),
@@ -84,6 +91,8 @@ function createIsosurfaceRenderable(ctx: WebGLContext, activeVoxelsPyramid: Text
uGridTexDim: ValueCell.create(gridTexDim),
uGridTransform: ValueCell.create(transform),
uScale: ValueCell.create(scale),
dPackedGroup: ValueCell.create(packedGroup)
};
const schema = { ...IsosurfaceSchema };
@@ -104,65 +113,72 @@ function setRenderingDefaults(ctx: WebGLContext) {
state.clearColor(0, 0, 0, 0);
}
export function createIsosurfaceBuffers(ctx: WebGLContext, activeVoxelsBase: Texture, volumeData: Texture, histogramPyramid: HistogramPyramid, gridDim: Vec3, gridTexDim: Vec3, transform: Mat4, isoValue: number, vertexGroupTexture?: Texture, normalTexture?: Texture) {
const { gl, resources } = ctx;
export function createIsosurfaceBuffers(ctx: WebGLContext, activeVoxelsBase: Texture, volumeData: Texture, histogramPyramid: HistogramPyramid, gridDim: Vec3, gridTexDim: Vec3, transform: Mat4, isoValue: number, packedGroup: boolean, vertexTexture?: Texture, groupTexture?: Texture, normalTexture?: Texture) {
const { gl, resources, extensions } = ctx;
const { pyramidTex, height, levels, scale, count } = histogramPyramid;
const width = pyramidTex.getWidth();
// console.log('iso', 'gridDim', gridDim, 'scale', scale, 'gridTexDim', gridTexDim)
// console.log('iso volumeData', volumeData)
// console.log('width', width, 'height', height);
// console.log('iso', 'gridDim', gridDim, 'scale', scale, 'gridTexDim', gridTexDim);
// console.log('iso volumeData', volumeData);
if (!ctx.namedFramebuffers[IsosurfaceName]) {
ctx.namedFramebuffers[IsosurfaceName] = resources.framebuffer();
}
const framebuffer = ctx.namedFramebuffers[IsosurfaceName];
if (!vertexGroupTexture) {
vertexGroupTexture = resources.texture('image-float32', 'rgba', 'float', 'nearest');
}
vertexGroupTexture.define(width, height);
if (isWebGL2(gl)) {
if (!vertexTexture) {
vertexTexture = extensions.colorBufferHalfFloat && extensions.textureHalfFloat
? resources.texture('image-float16', 'rgba', 'fp16', 'nearest')
: resources.texture('image-float32', 'rgba', 'float', 'nearest');
}
if (!normalTexture) {
normalTexture = resources.texture('image-float32', 'rgba', 'float', 'nearest');
if (!groupTexture) {
groupTexture = resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
}
if (!normalTexture) {
normalTexture = extensions.colorBufferHalfFloat && extensions.textureHalfFloat
? resources.texture('image-float16', 'rgba', 'fp16', 'nearest')
: resources.texture('image-float32', 'rgba', 'float', 'nearest');
}
} else {
// in webgl1 drawbuffers must be in the same format for some reason
// this is quite wasteful but good enough for medium size meshes
if (!vertexTexture) {
vertexTexture = resources.texture('image-float32', 'rgba', 'float', 'nearest');
}
if (!groupTexture) {
groupTexture = resources.texture('image-float32', 'rgba', 'float', 'nearest');
}
if (!normalTexture) {
normalTexture = resources.texture('image-float32', 'rgba', 'float', 'nearest');
}
}
vertexTexture.define(width, height);
groupTexture.define(width, height);
normalTexture.define(width, height);
// const infoTex = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
// infoTex.define(pyramidTex.width, pyramidTex.height)
vertexTexture.attachFramebuffer(framebuffer, 0);
groupTexture.attachFramebuffer(framebuffer, 1);
normalTexture.attachFramebuffer(framebuffer, 2);
// const pointTexA = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
// pointTexA.define(pyramidTex.width, pyramidTex.height)
// const pointTexB = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
// pointTexB.define(pyramidTex.width, pyramidTex.height)
// const coordTex = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
// coordTex.define(pyramidTex.width, pyramidTex.height)
// const indexTex = createTexture(ctx, 'image-float32', 'rgba', 'float', 'nearest')
// indexTex.define(pyramidTex.width, pyramidTex.height)
const renderable = getIsosurfaceRenderable(ctx, pyramidTex, activeVoxelsBase, volumeData, gridDim, gridTexDim, transform, isoValue, levels, scale, count, height);
const renderable = getIsosurfaceRenderable(ctx, pyramidTex, activeVoxelsBase, volumeData, gridDim, gridTexDim, transform, isoValue, levels, scale, count, packedGroup);
ctx.state.currentRenderItemId = -1;
vertexGroupTexture.attachFramebuffer(framebuffer, 0);
normalTexture.attachFramebuffer(framebuffer, 1);
// infoTex.attachFramebuffer(framebuffer, 1)
// pointTexA.attachFramebuffer(framebuffer, 2)
// pointTexB.attachFramebuffer(framebuffer, 3)
// coordTex.attachFramebuffer(framebuffer, 4)
// indexTex.attachFramebuffer(framebuffer, 5)
const { drawBuffers } = ctx.extensions;
if (!drawBuffers) throw new Error('need WebGL draw buffers');
framebuffer.bind();
drawBuffers.drawBuffers([
drawBuffers.COLOR_ATTACHMENT0,
drawBuffers.COLOR_ATTACHMENT1,
// drawBuffers.COLOR_ATTACHMENT2,
// drawBuffers.COLOR_ATTACHMENT3,
// drawBuffers.COLOR_ATTACHMENT4,
// drawBuffers.COLOR_ATTACHMENT5
drawBuffers.COLOR_ATTACHMENT2,
]);
setRenderingDefaults(ctx);
@@ -170,47 +186,38 @@ export function createIsosurfaceBuffers(ctx: WebGLContext, activeVoxelsBase: Tex
gl.clear(gl.COLOR_BUFFER_BIT);
renderable.render();
gl.flush();
gl.finish();
// const vgt = readTexture(ctx, vertexGroupTexture, pyramidTex.width, height)
// console.log('vertexGroupTexture', vgt.array.subarray(0, 4 * count))
return { vertexTexture, groupTexture, normalTexture, vertexCount: count };
}
// const vt = readTexture(ctx, verticesTex, pyramidTex.width, height)
// console.log('vt', vt)
// const vertices = new Float32Array(3 * compacted.count)
// for (let i = 0; i < compacted.count; ++i) {
// vertices[i * 3] = vt.array[i * 4]
// vertices[i * 3 + 1] = vt.array[i * 4 + 1]
// vertices[i * 3 + 2] = vt.array[i * 4 + 2]
// }
// console.log('vertices', vertices)
//
// const it = readTexture(ctx, infoTex, pyramidTex.width, height)
// console.log('info', it.array.subarray(0, 4 * compacted.count))
function delay() {
return new Promise(r => Scheduler.setImmediate(r));
}
// const pat = readTexture(ctx, pointTexA, pyramidTex.width, height)
// console.log('point a', pat.array.subarray(0, 4 * compacted.count))
export async function extractIsosurface(ctx: WebGLContext, volumeData: Texture, gridDim: Vec3, gridTexDim: Vec3, gridTexScale: Vec2, transform: Mat4, isoValue: number, packedGroup: boolean, vertexTexture?: Texture, groupTexture?: Texture, normalTexture?: Texture) {
// console.time('calcActiveVoxels');
const activeVoxelsTex = calcActiveVoxels(ctx, volumeData, gridDim, gridTexDim, isoValue, gridTexScale);
// apply advanced magic to solve incomplete buffer rendering issue
await delay();
// const pbt = readTexture(ctx, pointTexB, pyramidTex.width, height)
// console.log('point b', pbt.array.subarray(0, 4 * compacted.count))
// console.time('createHistogramPyramid');
const compacted = createHistogramPyramid(ctx, activeVoxelsTex, gridTexScale, gridTexDim);
// apply advanced magic to solve incomplete buffer rendering issue
await delay();
// const ct = readTexture(ctx, coordTex, pyramidTex.width, height)
// console.log('coord', ct.array.subarray(0, 4 * compacted.count))
// ctx.waitForGpuCommandsCompleteSync();
// console.timeEnd('createHistogramPyramid');
// const idxt = readTexture(ctx, indexTex, pyramidTex.width, height)
// console.log('index', idxt.array.subarray(0, 4 * compacted.count))
// console.time('createIsosurfaceBuffers');
const gv = createIsosurfaceBuffers(ctx, activeVoxelsTex, volumeData, compacted, gridDim, gridTexDim, transform, isoValue, packedGroup, vertexTexture, groupTexture, normalTexture);
// apply advanced magic to solve incomplete buffer rendering issue
await delay();
// const { field, idField } = await fieldFromTexture2d(ctx, volumeData, gridDimensions)
// console.log({ field, idField })
// ctx.waitForGpuCommandsCompleteSync();
// console.timeEnd('createIsosurfaceBuffers');
// const valuesA = new Float32Array(compacted.count)
// const valuesB = new Float32Array(compacted.count)
// for (let i = 0; i < compacted.count; ++i) {
// valuesA[i] = field.space.get(field.data, pat.array[i * 4], pat.array[i * 4 + 1], pat.array[i * 4 + 2])
// valuesB[i] = field.space.get(field.data, pbt.array[i * 4], pbt.array[i * 4 + 1], pbt.array[i * 4 + 2])
// }
// console.log('valuesA', valuesA)
// console.log('valuesB', valuesB)
return { vertexGroupTexture, normalTexture, vertexCount: count };
return gv;
}

View File

@@ -15,6 +15,7 @@ import { Textures } from './webgl/texture';
const getNextRenderableId = idFactory();
export type RenderableState = {
disposed: boolean
visible: boolean
alphaFactor: number
pickable: boolean

View File

@@ -14,6 +14,7 @@ import { ValueCell } from '../../mol-util';
export const CylindersSchema = {
...BaseSchema,
...SizeSchema,
aGroup: AttributeSpec('float32', 1, 0),
aStart: AttributeSpec('float32', 3, 0),
aEnd: AttributeSpec('float32', 3, 0),
aMapping: AttributeSpec('float32', 3, 0),

View File

@@ -7,59 +7,20 @@
import { Renderable, RenderableState, createRenderable } from '../renderable';
import { WebGLContext } from '../webgl/context';
import { createGraphicsRenderItem } from '../webgl/render-item';
import { AttributeSpec, Values, UniformSpec, GlobalUniformSchema, InternalSchema, TextureSpec, ValueSpec, ElementsSpec, DefineSpec, InternalValues, GlobalTextureSchema } from './schema';
import { AttributeSpec, Values, UniformSpec, GlobalUniformSchema, InternalSchema, TextureSpec, ElementsSpec, DefineSpec, InternalValues, GlobalTextureSchema, BaseSchema } from './schema';
import { DirectVolumeShaderCode } from '../shader-code';
import { ValueCell } from '../../mol-util';
export const DirectVolumeSchema = {
uColor: UniformSpec('v3'),
uColorTexDim: UniformSpec('v2'),
tColor: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'groupInstance', 'vertex', 'vertexInstance']),
uMarkerTexDim: UniformSpec('v2'),
tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
uOverpaintTexDim: UniformSpec('v2'),
tOverpaint: TextureSpec('image-uint8', 'rgba', 'ubyte', 'nearest'),
dOverpaint: DefineSpec('boolean'),
uTransparencyTexDim: UniformSpec('v2'),
tTransparency: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
dTransparency: DefineSpec('boolean'),
transparencyAverage: ValueSpec('number'),
dClipObjectCount: DefineSpec('number'),
dClipVariant: DefineSpec('string', ['instance', 'pixel']),
uClippingTexDim: UniformSpec('v2'),
tClipping: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'),
dClipping: DefineSpec('boolean'),
uVertexCount: UniformSpec('i'),
uInstanceCount: UniformSpec('i'),
uGroupCount: UniformSpec('i'),
uInvariantBoundingSphere: UniformSpec('v4'),
aInstance: AttributeSpec('float32', 1, 1),
aTransform: AttributeSpec('float32', 16, 1),
drawCount: ValueSpec('number'),
instanceCount: ValueSpec('number'),
alpha: ValueSpec('number'),
matrix: ValueSpec('m4'),
transform: ValueSpec('float32'),
extraTransform: ValueSpec('float32'),
hasReflection: ValueSpec('boolean'),
boundingSphere: ValueSpec('sphere'),
invariantBoundingSphere: ValueSpec('sphere'),
...BaseSchema,
aPosition: AttributeSpec('float32', 3, 0),
elements: ElementsSpec('uint32'),
uAlpha: UniformSpec('f'),
uColor: UniformSpec('v3'),
uColorTexDim: UniformSpec('v2'),
tColor: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'),
dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'groupInstance', 'vertex', 'vertexInstance']),
uIsoValue: UniformSpec('v2'),
uBboxMin: UniformSpec('v3'),

View File

@@ -15,9 +15,9 @@ import { InterpolationTypeNames } from '../../mol-geo/geometry/image/image';
export const ImageSchema = {
...BaseSchema,
aGroup: AttributeSpec('float32', 1, 0),
aPosition: AttributeSpec('float32', 3, 0),
aUv: AttributeSpec('float32', 2, 0),
elements: ElementsSpec('uint32'),
uImageTexDim: UniformSpec('v2'),

View File

@@ -14,6 +14,7 @@ import { LinesShaderCode } from '../shader-code';
export const LinesSchema = {
...BaseSchema,
...SizeSchema,
aGroup: AttributeSpec('float32', 1, 0),
aMapping: AttributeSpec('float32', 2, 0),
aStart: AttributeSpec('float32', 3, 0),
aEnd: AttributeSpec('float32', 3, 0),

View File

@@ -13,6 +13,7 @@ import { ValueCell } from '../../mol-util';
export const MeshSchema = {
...BaseSchema,
aGroup: AttributeSpec('float32', 1, 0),
aPosition: AttributeSpec('float32', 3, 0),
aNormal: AttributeSpec('float32', 3, 0),
elements: ElementsSpec('uint32'),

View File

@@ -14,6 +14,7 @@ import { ValueCell } from '../../mol-util';
export const PointsSchema = {
...BaseSchema,
...SizeSchema,
aGroup: AttributeSpec('float32', 1, 0),
aPosition: AttributeSpec('float32', 3, 0),
dPointSizeAttenuation: DefineSpec('boolean'),
dPointFilledCircle: DefineSpec('boolean'),

View File

@@ -159,6 +159,8 @@ export const GlobalUniformSchema = {
uHighlightColor: UniformSpec('v3'),
uSelectColor: UniformSpec('v3'),
uXrayEdgeFalloff: UniformSpec('f'),
uRenderWboit: UniformSpec('b'),
} as const;
export type GlobalUniformSchema = typeof GlobalUniformSchema
@@ -240,7 +242,6 @@ export const BaseSchema = {
...ClippingSchema,
aInstance: AttributeSpec('float32', 1, 1),
aGroup: AttributeSpec('float32', 1, 0),
/**
* final per-instance transform calculated for instance `i` as
* `aTransform[i] = matrix * transform[i] * extraTransform[i]`

View File

@@ -14,6 +14,7 @@ import { ValueCell } from '../../mol-util';
export const SpheresSchema = {
...BaseSchema,
...SizeSchema,
aGroup: AttributeSpec('float32', 1, 0),
aPosition: AttributeSpec('float32', 3, 0),
aMapping: AttributeSpec('float32', 2, 0),
elements: ElementsSpec('uint32'),

View File

@@ -14,6 +14,7 @@ import { ValueCell } from '../../mol-util';
export const TextSchema = {
...BaseSchema,
...SizeSchema,
aGroup: AttributeSpec('float32', 1, 0),
aPosition: AttributeSpec('float32', 3, 0),
aMapping: AttributeSpec('float32', 2, 0),
aDepth: AttributeSpec('float32', 1, 0),

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -13,11 +13,10 @@ import { ValueCell } from '../../mol-util';
export const TextureMeshSchema = {
...BaseSchema,
uGeoTexDim: UniformSpec('v2'),
/** texture has vertex positions in XYZ and group id in W */
tPositionGroup: TextureSpec('texture', 'rgba', 'float', 'nearest'),
tNormal: TextureSpec('texture', 'rgba', 'float', 'nearest'),
tPosition: TextureSpec('texture', 'rgb', 'float', 'nearest'),
tGroup: TextureSpec('texture', 'alpha', 'float', 'nearest'),
tNormal: TextureSpec('texture', 'rgb', 'float', 'nearest'),
dFlatShaded: DefineSpec('boolean'),
dDoubleSided: DefineSpec('boolean'),

View File

@@ -17,7 +17,7 @@ export function calculateTextureInfo (n: number, itemSize: number) {
return { width, height, length: width * height * itemSize };
}
export interface TextureImage<T extends Uint8Array | Float32Array> {
export interface TextureImage<T extends Uint8Array | Float32Array | Int32Array> {
readonly array: T
readonly width: number
readonly height: number

View File

@@ -6,7 +6,7 @@
import { Viewport } from '../mol-canvas3d/camera/util';
import { ICamera } from '../mol-canvas3d/camera';
import Scene from './scene';
import { Scene } from './scene';
import { WebGLContext } from './webgl/context';
import { Mat4, Vec3, Vec4, Vec2, Quat } from '../mol-math/linear-algebra';
import { GraphicsRenderable } from './renderable';
@@ -77,6 +77,8 @@ export const RendererParams = {
highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)),
selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)),
xrayEdgeFalloff: PD.Numeric(1, { min: 0.0, max: 3.0, step: 0.1 }),
style: PD.MappedStatic('matte', {
custom: PD.Group({
lightIntensity: PD.Numeric(0.6, { min: 0.0, max: 1.0, step: 0.01 }),
@@ -257,13 +259,15 @@ namespace Renderer {
uHighlightColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.highlightColor)),
uSelectColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.selectColor)),
uXrayEdgeFalloff: ValueCell.create(p.xrayEdgeFalloff),
};
const globalUniformList = Object.entries(globalUniforms);
let globalUniformsNeedUpdate = true;
const renderObject = (r: GraphicsRenderable, variant: GraphicsRenderVariant) => {
if (!r.state.visible || (!r.state.pickable && variant[0] === 'p')) {
if (r.state.disposed || !r.state.visible || (!r.state.pickable && variant[0] === 'p')) {
return;
}
@@ -607,6 +611,11 @@ namespace Renderer {
ValueCell.update(globalUniforms.uSelectColor, Color.toVec3Normalized(globalUniforms.uSelectColor.ref.value, p.selectColor));
}
if (props.xrayEdgeFalloff !== undefined && props.xrayEdgeFalloff !== p.xrayEdgeFalloff) {
p.xrayEdgeFalloff = props.xrayEdgeFalloff;
ValueCell.update(globalUniforms.uXrayEdgeFalloff, p.xrayEdgeFalloff);
}
if (props.style !== undefined) {
p.style = props.style;
Object.assign(style, getStyle(props.style));
@@ -669,4 +678,4 @@ namespace Renderer {
}
}
export default Renderer;
export { Renderer };

View File

@@ -247,4 +247,4 @@ namespace Scene {
}
}
export default Scene;
export { Scene };

View File

@@ -23,46 +23,50 @@ export interface ShaderExtensions {
readonly shaderTextureLod?: ShaderExtensionsValue
}
type FragOutTypes = { [k in number]: 'vec4' | 'ivec4' }
export interface ShaderCode {
readonly id: number
readonly name: string
readonly vert: string
readonly frag: string
readonly extensions: ShaderExtensions
/** Fragment shader output type only applicable for webgl2 */
readonly outTypes: FragOutTypes
}
import apply_fog from './shader/chunks/apply-fog.glsl';
import apply_interior_color from './shader/chunks/apply-interior-color.glsl';
import apply_light_color from './shader/chunks/apply-light-color.glsl';
import apply_marker_color from './shader/chunks/apply-marker-color.glsl';
import assign_clipping_varying from './shader/chunks/assign-clipping-varying.glsl';
import assign_color_varying from './shader/chunks/assign-color-varying.glsl';
import assign_group from './shader/chunks/assign-group.glsl';
import assign_marker_varying from './shader/chunks/assign-marker-varying.glsl';
import assign_material_color from './shader/chunks/assign-material-color.glsl';
import assign_position from './shader/chunks/assign-position.glsl';
import assign_size from './shader/chunks/assign-size.glsl';
import check_picking_alpha from './shader/chunks/check-picking-alpha.glsl';
import clip_instance from './shader/chunks/clip-instance.glsl';
import clip_pixel from './shader/chunks/clip-pixel.glsl';
import color_frag_params from './shader/chunks/color-frag-params.glsl';
import color_vert_params from './shader/chunks/color-vert-params.glsl';
import common_clip from './shader/chunks/common-clip.glsl';
import common_frag_params from './shader/chunks/common-frag-params.glsl';
import common_vert_params from './shader/chunks/common-vert-params.glsl';
import common from './shader/chunks/common.glsl';
import float_to_rgba from './shader/chunks/float-to-rgba.glsl';
import light_frag_params from './shader/chunks/light-frag-params.glsl';
import matrix_scale from './shader/chunks/matrix-scale.glsl';
import normal_frag_params from './shader/chunks/normal-frag-params.glsl';
import read_from_texture from './shader/chunks/read-from-texture.glsl';
import rgba_to_float from './shader/chunks/rgba-to-float.glsl';
import size_vert_params from './shader/chunks/size-vert-params.glsl';
import texture3d_from_1d_trilinear from './shader/chunks/texture3d-from-1d-trilinear.glsl';
import texture3d_from_2d_linear from './shader/chunks/texture3d-from-2d-linear.glsl';
import texture3d_from_2d_nearest from './shader/chunks/texture3d-from-2d-nearest.glsl';
import wboit_params from './shader/chunks/wboit-params.glsl';
import wboit_write from './shader/chunks/wboit-write.glsl';
import { apply_fog } from './shader/chunks/apply-fog.glsl';
import { apply_interior_color } from './shader/chunks/apply-interior-color.glsl';
import { apply_light_color } from './shader/chunks/apply-light-color.glsl';
import { apply_marker_color } from './shader/chunks/apply-marker-color.glsl';
import { assign_clipping_varying } from './shader/chunks/assign-clipping-varying.glsl';
import { assign_color_varying } from './shader/chunks/assign-color-varying.glsl';
import { assign_group } from './shader/chunks/assign-group.glsl';
import { assign_marker_varying } from './shader/chunks/assign-marker-varying.glsl';
import { assign_material_color } from './shader/chunks/assign-material-color.glsl';
import { assign_position } from './shader/chunks/assign-position.glsl';
import { assign_size } from './shader/chunks/assign-size.glsl';
import { check_picking_alpha } from './shader/chunks/check-picking-alpha.glsl';
import { clip_instance } from './shader/chunks/clip-instance.glsl';
import { clip_pixel } from './shader/chunks/clip-pixel.glsl';
import { color_frag_params } from './shader/chunks/color-frag-params.glsl';
import { color_vert_params } from './shader/chunks/color-vert-params.glsl';
import { common_clip } from './shader/chunks/common-clip.glsl';
import { common_frag_params } from './shader/chunks/common-frag-params.glsl';
import { common_vert_params } from './shader/chunks/common-vert-params.glsl';
import { common } from './shader/chunks/common.glsl';
import { float_to_rgba } from './shader/chunks/float-to-rgba.glsl';
import { light_frag_params } from './shader/chunks/light-frag-params.glsl';
import { matrix_scale } from './shader/chunks/matrix-scale.glsl';
import { normal_frag_params } from './shader/chunks/normal-frag-params.glsl';
import { read_from_texture } from './shader/chunks/read-from-texture.glsl';
import { rgba_to_float } from './shader/chunks/rgba-to-float.glsl';
import { size_vert_params } from './shader/chunks/size-vert-params.glsl';
import { texture3d_from_1d_trilinear } from './shader/chunks/texture3d-from-1d-trilinear.glsl';
import { texture3d_from_2d_linear } from './shader/chunks/texture3d-from-2d-linear.glsl';
import { texture3d_from_2d_nearest } from './shader/chunks/texture3d-from-2d-nearest.glsl';
import { wboit_params } from './shader/chunks/wboit-params.glsl';
import { wboit_write } from './shader/chunks/wboit-write.glsl';
const ShaderChunks: { [k: string]: string } = {
apply_fog,
@@ -117,42 +121,42 @@ function addIncludes(text: string) {
.replace(reMultipleLinebreaks, '\n');
}
export function ShaderCode(name: string, vert: string, frag: string, extensions: ShaderExtensions = {}): ShaderCode {
return { id: shaderCodeId(), name, vert: addIncludes(vert), frag: addIncludes(frag), extensions };
export function ShaderCode(name: string, vert: string, frag: string, extensions: ShaderExtensions = {}, outTypes: FragOutTypes = {}): ShaderCode {
return { id: shaderCodeId(), name, vert: addIncludes(vert), frag: addIncludes(frag), extensions, outTypes };
}
// Note: `drawBuffers` need to be 'optional' for wboit
import points_vert from './shader/points.vert';
import points_frag from './shader/points.frag';
import { points_vert } from './shader/points.vert';
import { points_frag } from './shader/points.frag';
export const PointsShaderCode = ShaderCode('points', points_vert, points_frag, { drawBuffers: 'optional' });
import spheres_vert from './shader/spheres.vert';
import spheres_frag from './shader/spheres.frag';
import { spheres_vert } from './shader/spheres.vert';
import { spheres_frag } from './shader/spheres.frag';
export const SpheresShaderCode = ShaderCode('spheres', spheres_vert, spheres_frag, { fragDepth: 'required', drawBuffers: 'optional' });
import cylinders_vert from './shader/cylinders.vert';
import cylinders_frag from './shader/cylinders.frag';
import { cylinders_vert } from './shader/cylinders.vert';
import { cylinders_frag } from './shader/cylinders.frag';
export const CylindersShaderCode = ShaderCode('cylinders', cylinders_vert, cylinders_frag, { fragDepth: 'required', drawBuffers: 'optional' });
import text_vert from './shader/text.vert';
import text_frag from './shader/text.frag';
import { text_vert }from './shader/text.vert';
import { text_frag } from './shader/text.frag';
export const TextShaderCode = ShaderCode('text', text_vert, text_frag, { standardDerivatives: 'required', drawBuffers: 'optional' });
import lines_vert from './shader/lines.vert';
import lines_frag from './shader/lines.frag';
import { lines_vert } from './shader/lines.vert';
import { lines_frag } from './shader/lines.frag';
export const LinesShaderCode = ShaderCode('lines', lines_vert, lines_frag, { drawBuffers: 'optional' });
import mesh_vert from './shader/mesh.vert';
import mesh_frag from './shader/mesh.frag';
import { mesh_vert } from './shader/mesh.vert';
import { mesh_frag } from './shader/mesh.frag';
export const MeshShaderCode = ShaderCode('mesh', mesh_vert, mesh_frag, { standardDerivatives: 'optional', drawBuffers: 'optional' });
import direct_volume_vert from './shader/direct-volume.vert';
import direct_volume_frag from './shader/direct-volume.frag';
export const DirectVolumeShaderCode = ShaderCode('direct-volume', direct_volume_vert, direct_volume_frag, { fragDepth: 'optional', drawBuffers: 'optional' });
import { directVolume_vert } from './shader/direct-volume.vert';
import { directVolume_frag } from './shader/direct-volume.frag';
export const DirectVolumeShaderCode = ShaderCode('direct-volume', directVolume_vert, directVolume_frag, { fragDepth: 'optional', drawBuffers: 'optional' });
import image_vert from './shader/image.vert';
import image_frag from './shader/image.frag';
import { image_vert } from './shader/image.vert';
import { image_frag } from './shader/image.frag';
export const ImageShaderCode = ShaderCode('image', image_vert, image_frag, { drawBuffers: 'optional' });
//
@@ -226,8 +230,6 @@ const glsl300VertPrefix = `#version 300 es
`;
const glsl300FragPrefixCommon = `
layout(location = 0) out highp vec4 out_FragData0;
#define varying in
#define texture2D texture
#define texture2DLodEXT textureLod
@@ -238,8 +240,12 @@ layout(location = 0) out highp vec4 out_FragData0;
#define depthTextureSupport
`;
function getGlsl300FragPrefix(gl: WebGL2RenderingContext, extensions: WebGLExtensions, shaderExtensions: ShaderExtensions) {
const prefix = [ '#version 300 es' ];
function getGlsl300FragPrefix(gl: WebGL2RenderingContext, extensions: WebGLExtensions, shaderExtensions: ShaderExtensions, outTypes: FragOutTypes) {
const prefix = [
'#version 300 es',
`layout(location = 0) out highp ${outTypes[0] || 'vec4'} out_FragData0;`
];
if (shaderExtensions.standardDerivatives) {
prefix.push('#define enabledStandardDerivatives');
}
@@ -250,7 +256,7 @@ function getGlsl300FragPrefix(gl: WebGL2RenderingContext, extensions: WebGLExten
prefix.push('#define requiredDrawBuffers');
const maxDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS) as number;
for (let i = 1, il = maxDrawBuffers; i < il; ++i) {
prefix.push(`layout(location = ${i}) out highp vec4 out_FragData${i};`);
prefix.push(`layout(location = ${i}) out highp ${outTypes[i] || 'vec4'} out_FragData${i};`);
}
}
if (shaderExtensions.shaderTextureLod) {
@@ -268,7 +274,7 @@ export function addShaderDefines(gl: GLRenderingContext, extensions: WebGLExtens
const header = getDefinesCode(defines);
const vertPrefix = isWebGL2(gl) ? glsl300VertPrefix : '';
const fragPrefix = isWebGL2(gl)
? getGlsl300FragPrefix(gl, extensions, shaders.extensions)
? getGlsl300FragPrefix(gl, extensions, shaders.extensions, shaders.outTypes)
: getGlsl100FragPrefix(extensions, shaders.extensions);
const frag = isWebGL2(gl) ? transformGlsl300Frag(shaders.frag) : shaders.frag;
return {
@@ -276,6 +282,7 @@ export function addShaderDefines(gl: GLRenderingContext, extensions: WebGLExtens
name: shaders.name,
vert: `${vertPrefix}${header}${shaders.vert}`,
frag: `${fragPrefix}${header}${frag}`,
extensions: shaders.extensions
extensions: shaders.extensions,
outTypes: shaders.outTypes
};
}

View File

@@ -1,4 +1,4 @@
export default `
export const apply_fog = `
float viewZ = depthToViewZ(uIsOrtho, fragmentDepth, uNear, uFar);
float fogFactor = smoothstep(uFogNear, uFogFar, abs(viewZ));
float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a;

View File

@@ -1,4 +1,4 @@
export default `
export const apply_interior_color = `
if (interior) {
if (uInteriorColorFlag) {
gl_FragColor.rgb = uInteriorColor;

View File

@@ -7,7 +7,7 @@
* which under the MIT License, Copyright © 2010-2019 three.js authors
*/
export default `
export const apply_light_color = `
// inputs
// - vec4 material
// - vec3 vViewPosition
@@ -49,6 +49,6 @@ vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffu
gl_FragColor = vec4(outgoingLight, color.a);
#ifdef dXrayShaded
gl_FragColor.a *= 1.0 - max(0.001, abs(dot(normal, vec3(0, 0, 1))));
gl_FragColor.a *= 1.0 - pow(abs(dot(normal, vec3(0, 0, 1))), uXrayEdgeFalloff);
#endif
`;

Some files were not shown because too many files have changed in this diff Show More