Skip to content
Snippets Groups Projects
Commit db640554 authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, isosurface renderable

parent 4a39fac4
Branches
Tags
No related merge requests found
...@@ -21,6 +21,7 @@ import { TransformData } from './transform-data'; ...@@ -21,6 +21,7 @@ import { TransformData } from './transform-data';
import { Theme } from 'mol-theme/theme'; import { Theme } from 'mol-theme/theme';
import { RenderObjectValuesType } from 'mol-gl/render-object'; import { RenderObjectValuesType } from 'mol-gl/render-object';
import { ValueOf } from 'mol-util/type-helpers'; import { ValueOf } from 'mol-util/type-helpers';
import { Isosurface } from './isosurface/isosurface';
export type GeometryKindType = { export type GeometryKindType = {
'mesh': Mesh, 'mesh': Mesh,
...@@ -29,6 +30,7 @@ export type GeometryKindType = { ...@@ -29,6 +30,7 @@ export type GeometryKindType = {
'text': Text, 'text': Text,
'lines': Lines, 'lines': Lines,
'direct-volume': DirectVolume, 'direct-volume': DirectVolume,
'isosurface': Isosurface,
} }
export type GeometryKindParams = { export type GeometryKindParams = {
'mesh': Mesh.Params, 'mesh': Mesh.Params,
...@@ -37,6 +39,7 @@ export type GeometryKindParams = { ...@@ -37,6 +39,7 @@ export type GeometryKindParams = {
'text': Text.Params, 'text': Text.Params,
'lines': Lines.Params, 'lines': Lines.Params,
'direct-volume': DirectVolume.Params, 'direct-volume': DirectVolume.Params,
'isosurface': Isosurface.Params,
} }
export type GeometryKind = keyof GeometryKindType export type GeometryKind = keyof GeometryKindType
export type Geometry = ValueOf<GeometryKindType> export type Geometry = ValueOf<GeometryKindType>
...@@ -63,6 +66,7 @@ export namespace Geometry { ...@@ -63,6 +66,7 @@ export namespace Geometry {
case 'text': return geometry.charCount * 2 * 3 case 'text': return geometry.charCount * 2 * 3
case 'lines': return geometry.lineCount * 2 * 3 case 'lines': return geometry.lineCount * 2 * 3
case 'direct-volume': return 12 * 3 case 'direct-volume': return 12 * 3
case 'isosurface': return geometry.vertexCount.ref.value * 3
} }
} }
...@@ -76,6 +80,8 @@ export namespace Geometry { ...@@ -76,6 +80,8 @@ export namespace Geometry {
return getDrawCount(geometry) === 0 ? 0 : (arrayMax(geometry.groupBuffer.ref.value) + 1) return getDrawCount(geometry) === 0 ? 0 : (arrayMax(geometry.groupBuffer.ref.value) + 1)
case 'direct-volume': case 'direct-volume':
return 1 return 1
case 'isosurface':
return geometry.groupCount.ref.value
} }
} }
...@@ -88,6 +94,7 @@ export namespace Geometry { ...@@ -88,6 +94,7 @@ export namespace Geometry {
case 'text': return Text.Utils as any case 'text': return Text.Utils as any
case 'lines': return Lines.Utils as any case 'lines': return Lines.Utils as any
case 'direct-volume': return DirectVolume.Utils as any case 'direct-volume': return DirectVolume.Utils as any
case 'isosurface': return Isosurface.Utils as any
} }
throw new Error('unknown geometry kind') throw new Error('unknown geometry kind')
} }
......
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ValueCell } from 'mol-util'
import { Sphere3D } from 'mol-math/geometry'
import { ParamDefinition as PD } from 'mol-util/param-definition';
import { LocationIterator } from 'mol-geo/util/location-iterator';
import { TransformData } from '../transform-data';
import { createColors } from '../color-data';
import { createMarkers } from '../marker-data';
import { GeometryUtils } from '../geometry';
import { Theme } from 'mol-theme/theme';
import { Color } from 'mol-util/color';
import { BaseGeometry } from '../base';
import { createEmptyOverpaint } from '../overpaint-data';
import { createEmptyTransparency } from '../transparency-data';
import { IsosurfaceValues } from 'mol-gl/renderable/isosurface';
import { calculateTransformBoundingSphere } from 'mol-gl/renderable/util';
import { Texture } from 'mol-gl/webgl/texture';
import { Vec2 } from 'mol-math/linear-algebra';
import { fillSerial } from 'mol-util/array';
export interface Isosurface {
readonly kind: 'isosurface',
/** Number of vertices in the isosurface */
readonly vertexCount: ValueCell<number>,
/** Number of groups in the isosurface */
readonly groupCount: ValueCell<number>,
readonly vertexTexture: ValueCell<Texture>,
readonly vertexTextureDim: ValueCell<Vec2>,
/** Normal buffer as array of xyz values for each vertex wrapped in a value cell */
readonly normalBuffer: ValueCell<Float32Array>,
/** Group buffer as array of group ids for each vertex wrapped in a value cell */
readonly groupBuffer: ValueCell<Float32Array>,
readonly boundingSphere: ValueCell<Sphere3D>,
}
export namespace Isosurface {
export function create(vertexCount: number, groupCount: number, vertexTexture: Texture, normalBuffer: Float32Array, groupBuffer: Float32Array, boundingSphere: Sphere3D, isosurface?: Isosurface): Isosurface {
const { width, height } = vertexTexture
if (isosurface) {
ValueCell.update(isosurface.vertexCount, vertexCount)
ValueCell.update(isosurface.groupCount, groupCount)
ValueCell.update(isosurface.vertexTexture, vertexTexture)
ValueCell.update(isosurface.vertexTextureDim, Vec2.set(isosurface.vertexTextureDim.ref.value, width, height))
ValueCell.update(isosurface.normalBuffer, normalBuffer)
ValueCell.update(isosurface.groupBuffer, groupBuffer)
ValueCell.update(isosurface.boundingSphere, boundingSphere)
return isosurface
} else {
return {
kind: 'isosurface',
vertexCount: ValueCell.create(vertexCount),
groupCount: ValueCell.create(groupCount),
vertexTexture: ValueCell.create(vertexTexture),
vertexTextureDim: ValueCell.create(Vec2.create(width, height)),
normalBuffer: ValueCell.create(normalBuffer),
groupBuffer: ValueCell.create(groupBuffer),
boundingSphere: ValueCell.create(boundingSphere),
}
}
}
export function createEmpty(isosurface?: Isosurface): Isosurface {
return {} as Isosurface // TODO
}
export const Params = {
...BaseGeometry.Params,
doubleSided: PD.Boolean(false),
flipSided: PD.Boolean(false),
flatShaded: PD.Boolean(false),
}
export type Params = typeof Params
export const Utils: GeometryUtils<Isosurface, Params> = {
Params,
createEmpty,
createValues,
createValuesSimple,
updateValues,
updateBoundingSphere,
createRenderableState: BaseGeometry.createRenderableState,
updateRenderableState: BaseGeometry.updateRenderableState
}
function createValues(isosurface: Isosurface, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): IsosurfaceValues {
const { instanceCount, groupCount } = locationIt
const color = createColors(locationIt, theme.color)
const marker = createMarkers(instanceCount * groupCount)
const overpaint = createEmptyOverpaint()
const transparency = createEmptyTransparency()
const counts = { drawCount: isosurface.vertexCount.ref.value, groupCount, instanceCount }
const transformBoundingSphere = calculateTransformBoundingSphere(isosurface.boundingSphere.ref.value, transform.aTransform.ref.value, transform.instanceCount.ref.value)
return {
tPosition: isosurface.vertexTexture,
uPositionTexDim: isosurface.vertexTextureDim,
aIndex: ValueCell.create(fillSerial(new Float32Array(isosurface.vertexCount.ref.value))),
aNormal: isosurface.normalBuffer,
aGroup: isosurface.groupBuffer,
boundingSphere: ValueCell.create(transformBoundingSphere),
invariantBoundingSphere: isosurface.boundingSphere,
...color,
...marker,
...overpaint,
...transparency,
...transform,
...BaseGeometry.createValues(props, counts),
dDoubleSided: ValueCell.create(props.doubleSided),
dFlatShaded: ValueCell.create(props.flatShaded),
dFlipSided: ValueCell.create(props.flipSided),
dPositionTexture: ValueCell.create(true),
}
}
function createValuesSimple(isosurface: Isosurface, props: Partial<PD.Values<Params>>, colorValue: Color, sizeValue: number, transform?: TransformData) {
const s = BaseGeometry.createSimple(colorValue, sizeValue, transform)
const p = { ...PD.getDefaultValues(Params), ...props }
return createValues(isosurface, s.transform, s.locationIterator, s.theme, p)
}
function updateValues(values: IsosurfaceValues, props: PD.Values<Params>) {
if (Color.fromNormalizedArray(values.uHighlightColor.ref.value, 0) !== props.highlightColor) {
ValueCell.update(values.uHighlightColor, Color.toArrayNormalized(props.highlightColor, values.uHighlightColor.ref.value, 0))
}
if (Color.fromNormalizedArray(values.uSelectColor.ref.value, 0) !== props.selectColor) {
ValueCell.update(values.uSelectColor, Color.toArrayNormalized(props.selectColor, values.uSelectColor.ref.value, 0))
}
ValueCell.updateIfChanged(values.alpha, props.alpha) // `uAlpha` is set in renderable.render
ValueCell.updateIfChanged(values.dUseFog, props.useFog)
ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided)
ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded)
ValueCell.updateIfChanged(values.dFlipSided, props.flipSided)
}
function updateBoundingSphere(values: IsosurfaceValues, isosurface: Isosurface) {
const invariantBoundingSphere = isosurface.boundingSphere.ref.value
const boundingSphere = calculateTransformBoundingSphere(invariantBoundingSphere, values.aTransform.ref.value, values.instanceCount.ref.value)
if (!Sphere3D.equals(boundingSphere, values.boundingSphere.ref.value)) {
ValueCell.update(values.boundingSphere, boundingSphere)
}
if (!Sphere3D.equals(invariantBoundingSphere, values.invariantBoundingSphere.ref.value)) {
ValueCell.update(values.invariantBoundingSphere, invariantBoundingSphere)
}
}
}
\ No newline at end of file
...@@ -14,6 +14,7 @@ import { PointsValues, PointsRenderable } from './renderable/points'; ...@@ -14,6 +14,7 @@ import { PointsValues, PointsRenderable } from './renderable/points';
import { LinesValues, LinesRenderable } from './renderable/lines'; import { LinesValues, LinesRenderable } from './renderable/lines';
import { SpheresValues, SpheresRenderable } from './renderable/spheres'; import { SpheresValues, SpheresRenderable } from './renderable/spheres';
import { TextValues, TextRenderable } from './renderable/text'; import { TextValues, TextRenderable } from './renderable/text';
import { IsosurfaceValues, IsosurfaceRenderable } from './renderable/isosurface';
const getNextId = idFactory(0, 0x7FFFFFFF) const getNextId = idFactory(0, 0x7FFFFFFF)
...@@ -26,10 +27,11 @@ export interface SpheresRenderObject extends BaseRenderObject { type: 'spheres', ...@@ -26,10 +27,11 @@ export interface SpheresRenderObject extends BaseRenderObject { type: 'spheres',
export interface TextRenderObject extends BaseRenderObject { type: 'text', values: TextValues } export interface TextRenderObject extends BaseRenderObject { type: 'text', values: TextValues }
export interface LinesRenderObject extends BaseRenderObject { type: 'lines', values: LinesValues } export interface LinesRenderObject extends BaseRenderObject { type: 'lines', values: LinesValues }
export interface DirectVolumeRenderObject extends BaseRenderObject { type: 'direct-volume', values: DirectVolumeValues } export interface DirectVolumeRenderObject extends BaseRenderObject { type: 'direct-volume', values: DirectVolumeValues }
export interface IsosurfaceRenderObject extends BaseRenderObject { type: 'isosurface', values: IsosurfaceValues }
// //
export type GraphicsRenderObject = MeshRenderObject | PointsRenderObject | SpheresRenderObject | TextRenderObject | LinesRenderObject | DirectVolumeRenderObject export type GraphicsRenderObject = MeshRenderObject | PointsRenderObject | SpheresRenderObject | TextRenderObject | LinesRenderObject | DirectVolumeRenderObject | IsosurfaceRenderObject
export type RenderObjectKindType = { export type RenderObjectKindType = {
'mesh': MeshRenderObject 'mesh': MeshRenderObject
...@@ -38,6 +40,7 @@ export type RenderObjectKindType = { ...@@ -38,6 +40,7 @@ export type RenderObjectKindType = {
'text': TextRenderObject 'text': TextRenderObject
'lines': LinesRenderObject 'lines': LinesRenderObject
'direct-volume': DirectVolumeRenderObject 'direct-volume': DirectVolumeRenderObject
'isosurface': IsosurfaceRenderObject
} }
export type RenderObjectValuesType = { export type RenderObjectValuesType = {
'mesh': MeshValues 'mesh': MeshValues
...@@ -46,6 +49,7 @@ export type RenderObjectValuesType = { ...@@ -46,6 +49,7 @@ export type RenderObjectValuesType = {
'text': TextValues 'text': TextValues
'lines': LinesValues 'lines': LinesValues
'direct-volume': DirectVolumeValues 'direct-volume': DirectVolumeValues
'isosurface': IsosurfaceValues
} }
export type RenderObjectType = keyof RenderObjectKindType export type RenderObjectType = keyof RenderObjectKindType
...@@ -63,5 +67,6 @@ export function createRenderable(ctx: WebGLContext, o: GraphicsRenderObject): Re ...@@ -63,5 +67,6 @@ export function createRenderable(ctx: WebGLContext, o: GraphicsRenderObject): Re
case 'text': return TextRenderable(ctx, o.id, o.values, o.state, o.materialId) case 'text': return TextRenderable(ctx, o.id, o.values, o.state, o.materialId)
case 'lines': return LinesRenderable(ctx, o.id, o.values, o.state, o.materialId) case 'lines': return LinesRenderable(ctx, o.id, o.values, o.state, o.materialId)
case 'direct-volume': return DirectVolumeRenderable(ctx, o.id, o.values, o.state, o.materialId) case 'direct-volume': return DirectVolumeRenderable(ctx, o.id, o.values, o.state, o.materialId)
case 'isosurface': return IsosurfaceRenderable(ctx, o.id, o.values, o.state, o.materialId)
} }
} }
\ No newline at end of file
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Renderable, RenderableState, createRenderable } from '../renderable'
import { WebGLContext } from '../webgl/context';
import { createGraphicsRenderItem } from '../webgl/render-item';
import { GlobalUniformSchema, BaseSchema, AttributeSpec, DefineSpec, Values, InternalSchema, InternalValues, UniformSpec, TextureSpec } from './schema';
import { MeshShaderCode } from '../shader-code';
import { ValueCell } from 'mol-util';
export const IsosurfaceSchema = {
...BaseSchema,
aIndex: AttributeSpec('float32', 1, 0),
aNormal: AttributeSpec('float32', 3, 0),
uPositionTexDim: UniformSpec('v2'),
tPosition: TextureSpec('texture', 'rgba', 'float', 'nearest'),
dFlatShaded: DefineSpec('boolean'),
dDoubleSided: DefineSpec('boolean'),
dFlipSided: DefineSpec('boolean'),
dPositionTexture: DefineSpec('boolean'),
}
export type IsosurfaceSchema = typeof IsosurfaceSchema
export type IsosurfaceValues = Values<IsosurfaceSchema>
export function IsosurfaceRenderable(ctx: WebGLContext, id: number, values: IsosurfaceValues, state: RenderableState, materialId: number): Renderable<IsosurfaceValues> {
const schema = { ...GlobalUniformSchema, ...InternalSchema, ...IsosurfaceSchema }
const internalValues: InternalValues = {
uObjectId: ValueCell.create(id),
uPickable: ValueCell.create(state.pickable ? 1 : 0)
}
const shaderCode = MeshShaderCode
const renderItem = createGraphicsRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues }, materialId)
return createRenderable(renderItem, values, state)
}
\ No newline at end of file
mat4 modelView = uView * uModel * aTransform; mat4 modelView = uView * uModel * aTransform;
vec4 mvPosition = modelView * vec4(aPosition, 1.0); #ifdef dPositionTexture
vec3 position = readFromTexture(tPosition, aIndex, uPositionTexDim).xyz;
#else
vec3 position = aPosition;
#endif
vec4 mvPosition = modelView * vec4(position, 1.0);
vViewPosition = mvPosition.xyz; vViewPosition = mvPosition.xyz;
gl_Position = uProjection * mvPosition; gl_Position = uProjection * mvPosition;
\ No newline at end of file
/** /**
* 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> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -10,7 +10,13 @@ precision highp int; ...@@ -10,7 +10,13 @@ precision highp int;
#pragma glslify: import('./chunks/common-vert-params.glsl') #pragma glslify: import('./chunks/common-vert-params.glsl')
#pragma glslify: import('./chunks/color-vert-params.glsl') #pragma glslify: import('./chunks/color-vert-params.glsl')
attribute vec3 aPosition; #ifdef dPositionTexture
attribute float aIndex;
uniform vec2 uPositionTexDim;
uniform sampler2D tPosition;
#else
attribute vec3 aPosition;
#endif
attribute mat4 aTransform; attribute mat4 aTransform;
attribute float aInstance; attribute float aInstance;
attribute float aGroup; attribute float aGroup;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment