From d7ba4d88f719b588491be9b32e4f0862cebb49ae Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Thu, 4 Apr 2019 14:35:07 -0700 Subject: [PATCH] wip, gaussian unit surface texture-mesh --- src/mol-geo/geometry/geometry.ts | 2 +- .../compute/histogram-pyramid/reduction.ts | 2 +- .../compute/marching-cubes/isosurface.ts | 6 +- .../shader/marching-cubes/isosurface.frag | 4 +- src/mol-repr/structure/representation.ts | 4 + .../representation/molecular-surface.ts | 9 ++- src/mol-repr/structure/units-visual.ts | 22 +++++- .../structure/visual/gaussian-surface-mesh.ts | 79 ++++++++++++++++--- .../structure/visual/util/gaussian.ts | 11 ++- 9 files changed, 114 insertions(+), 25 deletions(-) diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index 98393c607..3497025ba 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ diff --git a/src/mol-gl/compute/histogram-pyramid/reduction.ts b/src/mol-gl/compute/histogram-pyramid/reduction.ts index 5515dcb19..5a9fb03a1 100644 --- a/src/mol-gl/compute/histogram-pyramid/reduction.ts +++ b/src/mol-gl/compute/histogram-pyramid/reduction.ts @@ -12,7 +12,7 @@ import { Texture, createTexture } from 'mol-gl/webgl/texture'; import { ShaderCode } from 'mol-gl/shader-code'; import { ValueCell } from 'mol-util'; import { GLRenderingContext } from 'mol-gl/webgl/compat'; -import { printTexture, QuadSchema, QuadValues } from '../util'; +import { QuadSchema, QuadValues } from '../util'; import { Vec2 } from 'mol-math/linear-algebra'; import { getHistopyramidSum } from './sum'; diff --git a/src/mol-gl/compute/marching-cubes/isosurface.ts b/src/mol-gl/compute/marching-cubes/isosurface.ts index dcc4f3d3e..8f3310497 100644 --- a/src/mol-gl/compute/marching-cubes/isosurface.ts +++ b/src/mol-gl/compute/marching-cubes/isosurface.ts @@ -13,7 +13,7 @@ import { ShaderCode } from 'mol-gl/shader-code'; import { ValueCell } from 'mol-util'; import { GLRenderingContext } from 'mol-gl/webgl/compat'; import { Vec3, Vec2, Mat4 } from 'mol-math/linear-algebra'; -import { QuadSchema, QuadValues, readTexture } from '../util'; +import { QuadSchema, QuadValues } from '../util'; import { HistogramPyramid } from '../histogram-pyramid/reduction'; import { getTriIndices } from './tables'; @@ -138,8 +138,8 @@ export function createIsosurfaceBuffers(ctx: WebGLContext, activeVoxelsBase: Tex pr.render() gl.disable(gl.SCISSOR_TEST) - const vgt = readTexture(ctx, vertexGroupTexture, pyramidTex.width, height) - console.log('vertexGroupTexture', vgt.array.subarray(0, 4 * count)) + // const vgt = readTexture(ctx, vertexGroupTexture, pyramidTex.width, height) + // console.log('vertexGroupTexture', vgt.array.subarray(0, 4 * count)) // const vt = readTexture(ctx, verticesTex, pyramidTex.width, height) // console.log('vt', vt) diff --git a/src/mol-gl/shader/marching-cubes/isosurface.frag b/src/mol-gl/shader/marching-cubes/isosurface.frag index 23939b15d..c43d1ba67 100644 --- a/src/mol-gl/shader/marching-cubes/isosurface.frag +++ b/src/mol-gl/shader/marching-cubes/isosurface.frag @@ -186,7 +186,7 @@ void main(void) { float t = (uIsoValue - v0) / (v0 - v1); // t = -0.5; - gl_FragColor.xyz = b0 + t * (b0 - b1); + gl_FragColor.xyz = (uGridTransform * vec4(b0 + t * (b0 - b1), 1.0)).xyz; gl_FragColor.w = decodeFloatRGB(d0.rgb); // group id // normals from gradients @@ -201,4 +201,6 @@ void main(void) { v1 - voxel((b1 + c4) / uGridDim).a )); gl_FragData[1].xyz = -normalize((v0 * n0 + v1 * n1) / max(v0 + v1, EPS)); + mat3 normalMatrix = transpose(inverse(mat3(uGridTransform))); + gl_FragData[1].xyz = normalMatrix * gl_FragData[1].xyz; } \ No newline at end of file diff --git a/src/mol-repr/structure/representation.ts b/src/mol-repr/structure/representation.ts index 183cd297c..427ab0c0f 100644 --- a/src/mol-repr/structure/representation.ts +++ b/src/mol-repr/structure/representation.ts @@ -15,6 +15,7 @@ import { Lines } from 'mol-geo/geometry/lines/lines'; import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume'; import { Spheres } from 'mol-geo/geometry/spheres/spheres'; import { StructureUnitTransforms } from 'mol-model/structure/structure/util/unit-transforms'; +import { TextureMesh } from 'mol-geo/geometry/texture-mesh/texture-mesh'; export interface StructureRepresentationState extends Representation.State { unitTransforms: StructureUnitTransforms | null @@ -56,6 +57,9 @@ export type StructureLinesParams = typeof StructureLinesParams export const StructureDirectVolumeParams = { ...DirectVolume.Params, ...StructureParams } export type StructureDirectVolumeParams = typeof StructureDirectVolumeParams +export const StructureTextureMeshParams = { ...TextureMesh.Params, ...StructureParams } +export type StructureTextureMeshParams = typeof StructureTextureMeshParams + export { ComplexRepresentation } from './complex-representation' export { UnitsRepresentation } from './units-representation' export { ComplexVisual } from './complex-visual' diff --git a/src/mol-repr/structure/representation/molecular-surface.ts b/src/mol-repr/structure/representation/molecular-surface.ts index 4cef6716d..b3c5c7915 100644 --- a/src/mol-repr/structure/representation/molecular-surface.ts +++ b/src/mol-repr/structure/representation/molecular-surface.ts @@ -1,10 +1,10 @@ /** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { GaussianSurfaceVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh'; +import { GaussianSurfaceMeshVisual, GaussianSurfaceTextureMeshVisual, GaussianSurfaceParams } from '../visual/gaussian-surface-mesh'; import { UnitsRepresentation } from '../units-representation'; import { GaussianWireframeVisual, GaussianWireframeParams } from '../visual/gaussian-surface-wireframe'; import { ParamDefinition as PD } from 'mol-util/param-definition'; @@ -14,7 +14,8 @@ import { ThemeRegistryContext } from 'mol-theme/theme'; import { Structure } from 'mol-model/structure'; const MolecularSurfaceVisuals = { - 'gaussian-surface': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceVisual), + 'gaussian-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceMeshVisual), + 'gaussian-surface-texture-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceTextureMeshVisual), 'gaussian-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianWireframeParams>) => UnitsRepresentation('Gaussian wireframe', ctx, getParams, GaussianWireframeVisual), } type MolecularSurfaceVisualName = keyof typeof MolecularSurfaceVisuals @@ -23,7 +24,7 @@ const MolecularSurfaceVisualOptions = Object.keys(MolecularSurfaceVisuals).map(n export const MolecularSurfaceParams = { ...GaussianSurfaceParams, ...GaussianWireframeParams, - visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface'], MolecularSurfaceVisualOptions), + visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface-mesh'], MolecularSurfaceVisualOptions), } export type MolecularSurfaceParams = typeof MolecularSurfaceParams export function getMolecularSurfaceParams(ctx: ThemeRegistryContext, structure: Structure) { diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts index 41b74b4d7..e0b0f76af 100644 --- a/src/mol-repr/structure/units-visual.ts +++ b/src/mol-repr/structure/units-visual.ts @@ -7,7 +7,7 @@ import { Unit, Structure } from 'mol-model/structure'; import { RepresentationProps } from '../representation'; import { Visual, VisualContext } from '../visual'; -import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureSpheresParams } from './representation'; +import { StructureMeshParams, StructurePointsParams, StructureLinesParams, StructureDirectVolumeParams, StructureSpheresParams, StructureTextureMeshParams } from './representation'; import { Loci, isEveryLoci, EmptyLoci } from 'mol-model/loci'; import { GraphicsRenderObject, createRenderObject } from 'mol-gl/render-object'; import { deepEqual, ValueCell } from 'mol-util'; @@ -33,6 +33,7 @@ import { Spheres } from 'mol-geo/geometry/spheres/spheres'; import { createUnitsTransform, includesUnitKind } from './visual/util/common'; import { Overpaint } from 'mol-theme/overpaint'; import { Transparency } from 'mol-theme/transparency'; +import { TextureMesh } from 'mol-geo/geometry/texture-mesh/texture-mesh'; export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup } @@ -328,7 +329,7 @@ export function UnitsLinesVisual<P extends UnitsLinesParams>(builder: UnitsLines export const UnitsDirectVolumeParams = { ...StructureDirectVolumeParams, ...UnitsParams } export type UnitsDirectVolumeParams = typeof UnitsDirectVolumeParams -export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeParams> extends UnitsVisualGeometryBuilder<P, DirectVolume> { } +export interface UnitsDirectVolumeVisualBuilder<P extends UnitsDirectVolumeParams> extends UnitsVisualBuilder<P, DirectVolume> { } export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeParams>(builder: UnitsDirectVolumeVisualBuilder<P>, materialId: number): UnitsVisual<P> { return UnitsVisual<DirectVolume, StructureDirectVolumeParams & UnitsParams>({ @@ -339,4 +340,21 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeParams>(build }, geometryUtils: DirectVolume.Utils }, materialId) +} + +// texture-mesh + +export const UnitsTextureMeshParams = { ...StructureTextureMeshParams, ...UnitsParams } +export type UnitsTextureMeshParams = typeof UnitsTextureMeshParams +export interface UnitsTextureMeshVisualBuilder<P extends UnitsTextureMeshParams> extends UnitsVisualBuilder<P, TextureMesh> { } + +export function UnitsTextureMeshVisual<P extends UnitsTextureMeshParams>(builder: UnitsTextureMeshVisualBuilder<P>, materialId: number): UnitsVisual<P> { + return UnitsVisual<TextureMesh, StructureTextureMeshParams & UnitsParams>({ + ...builder, + setUpdateState: (state: VisualUpdateState, newProps: PD.Values<P>, currentProps: PD.Values<P>, newTheme: Theme, currentTheme: Theme) => { + builder.setUpdateState(state, newProps, currentProps, newTheme, currentTheme) + if (!SizeTheme.areEqual(newTheme.size, currentTheme.size)) state.createGeometry = true + }, + geometryUtils: TextureMesh.Utils + }, materialId) } \ No newline at end of file diff --git a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts index b2622071a..b817423dd 100644 --- a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts +++ b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -7,14 +7,33 @@ import { Unit, Structure } from 'mol-model/structure'; import { UnitsVisual } from '../representation'; import { VisualUpdateState } from '../../util'; -import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual'; +import { UnitsMeshVisual, UnitsMeshParams, UnitsTextureMeshParams, UnitsTextureMeshVisual } from '../units-visual'; import { StructureElementIterator, getElementLoci, eachElement } from './util/element'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm'; import { VisualContext } from 'mol-repr/visual'; import { Theme } from 'mol-theme/theme'; -import { GaussianDensityProps, computeUnitGaussianDensity, GaussianDensityParams } from './util/gaussian'; +import { GaussianDensityProps, computeUnitGaussianDensity, GaussianDensityParams, computeUnitGaussianDensityTexture2d, GaussianDensityTextureProps } from './util/gaussian'; +import { WebGLContext } from 'mol-gl/webgl/context'; +import { TextureMesh } from 'mol-geo/geometry/texture-mesh/texture-mesh'; +import { calcActiveVoxels } from 'mol-gl/compute/marching-cubes/active-voxels'; +import { createHistogramPyramid } from 'mol-gl/compute/histogram-pyramid/reduction'; +import { createIsosurfaceBuffers } from 'mol-gl/compute/marching-cubes/isosurface'; +import { Sphere3D } from 'mol-math/geometry'; + +export const GaussianSurfaceParams = { + ...UnitsMeshParams, + ...UnitsTextureMeshParams, + ...GaussianDensityParams, +} +export type GaussianSurfaceParams = typeof GaussianSurfaceParams + +export function getGaussianSurfaceVisual(webgl?: WebGLContext) { + return webgl && webgl.extensions.drawBuffers ? GaussianSurfaceTextureMeshVisual : GaussianSurfaceMeshVisual +} + +// async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> { const { smoothness } = props @@ -31,16 +50,10 @@ async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structu Mesh.computeNormalsImmediate(surface) Mesh.uniformTriangleGroup(surface) - return surface; + return surface } -export const GaussianSurfaceParams = { - ...UnitsMeshParams, - ...GaussianDensityParams, -} -export type GaussianSurfaceParams = typeof GaussianSurfaceParams - -export function GaussianSurfaceVisual(materialId: number): UnitsVisual<GaussianSurfaceParams> { +export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<GaussianSurfaceParams> { return UnitsMeshVisual<GaussianSurfaceParams>({ defaultProps: PD.getDefaultValues(GaussianSurfaceParams), createGeometry: createGaussianSurfaceMesh, @@ -54,4 +67,48 @@ export function GaussianSurfaceVisual(materialId: number): UnitsVisual<GaussianS if (newProps.useGpu !== currentProps.useGpu) state.createGeometry = true } }, materialId) +} + +// + +async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityTextureProps, textureMesh?: TextureMesh): Promise<TextureMesh> { + if (!ctx.webgl) throw new Error('webgl context required to create gaussian surface texture-mesh') + const isoLevel = Math.exp(-props.smoothness) + + const densityTextureData = await computeUnitGaussianDensityTexture2d(unit, props, ctx.webgl).runInContext(ctx.runtime) + // console.log(densityTextureData) + // console.log('vertexGroupTexture', readTexture(ctx.webgl, densityTextureData.texture)) + // ctx.webgl.waitForGpuCommandsCompleteSync() + + const activeVoxelsTex = calcActiveVoxels(ctx.webgl, densityTextureData.texture, densityTextureData.gridDimension, isoLevel) + // ctx.webgl.waitForGpuCommandsCompleteSync() + + const compacted = createHistogramPyramid(ctx.webgl, activeVoxelsTex) + // ctx.webgl.waitForGpuCommandsCompleteSync() + + const gv = createIsosurfaceBuffers(ctx.webgl, activeVoxelsTex, densityTextureData.texture, compacted, densityTextureData.gridDimension, densityTextureData.transform, isoLevel) + // ctx.webgl.waitForGpuCommandsCompleteSync() + + // const boundingSphere = Sphere3D.zero() + // Sphere3D.addVec3(boundingSphere, boundingSphere, densityTextureData.gridDimension) + const boundingSphere = Sphere3D.fromBox3D(Sphere3D(), densityTextureData.bbox) + const surface = TextureMesh.create(gv.vertexCount, 1, gv.vertexGroupTexture, gv.normalTexture, boundingSphere, textureMesh) + + // ctx.webgl.waitForGpuCommandsCompleteSync() + return surface +} + +export function GaussianSurfaceTextureMeshVisual(materialId: number): UnitsVisual<GaussianSurfaceParams> { + return UnitsTextureMeshVisual<GaussianSurfaceParams>({ + defaultProps: PD.getDefaultValues(GaussianSurfaceParams), + createGeometry: createGaussianSurfaceTextureMesh, + createLocationIterator: StructureElementIterator.fromGroup, + getLoci: getElementLoci, + eachLocation: eachElement, + setUpdateState: (state: VisualUpdateState, newProps: PD.Values<GaussianSurfaceParams>, currentProps: PD.Values<GaussianSurfaceParams>) => { + if (newProps.resolution !== currentProps.resolution) state.createGeometry = true + if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true + if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true + } + }, materialId) } \ No newline at end of file diff --git a/src/mol-repr/structure/visual/util/gaussian.ts b/src/mol-repr/structure/visual/util/gaussian.ts index 9cee5dcdd..d50d95c8f 100644 --- a/src/mol-repr/structure/visual/util/gaussian.ts +++ b/src/mol-repr/structure/visual/util/gaussian.ts @@ -8,7 +8,7 @@ import { Unit, StructureElement, ElementIndex, Structure } from 'mol-model/struc import { GaussianDensity } from 'mol-math/geometry/gaussian-density'; import { Task } from 'mol-task'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { GaussianDensityTexture } from 'mol-math/geometry/gaussian-density/gpu'; +import { GaussianDensityTexture, GaussianDensityTexture2d } from 'mol-math/geometry/gaussian-density/gpu'; import { Texture } from 'mol-gl/webgl/texture'; import { WebGLContext } from 'mol-gl/webgl/context'; import { PhysicalSizeTheme } from 'mol-theme/size/physical'; @@ -68,13 +68,20 @@ export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityPro }); } -export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) { +export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityTextureProps, webgl: WebGLContext, texture?: Texture) { const { position, radius } = getUnitConformationAndRadius(unit) return Task.create('Gaussian Density', async ctx => { return await GaussianDensityTexture(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture); }); } +export function computeUnitGaussianDensityTexture2d(unit: Unit, props: GaussianDensityTextureProps, webgl: WebGLContext, texture?: Texture) { + const { position, radius } = getUnitConformationAndRadius(unit) + return Task.create('Gaussian Density', async ctx => { + return await GaussianDensityTexture2d(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture); + }); +} + // function getStructureConformationAndRadius(structure: Structure) { -- GitLab