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

wip, point & size

parent 9a7a35bb
No related branches found
No related tags found
No related merge requests found
Showing
with 196 additions and 30 deletions
......@@ -20,7 +20,7 @@ import { Run } from 'mol-task'
import { Symmetry } from 'mol-model/structure'
// import mcubes from './utils/mcubes'
import { getStructuresFromPdbId } from './utils'
import { getStructuresFromPdbId, log } from './utils'
import { StructureRepresentation } from 'mol-geo/representation/structure';
// import Cylinder from 'mol-geo/primitive/cylinder';
......@@ -45,14 +45,14 @@ export default class State {
this.loading.next(true)
const structures = await getStructuresFromPdbId(pdbId)
const struct = await Run(Symmetry.buildAssembly(structures[0], '1'))
const struct = await Run(Symmetry.buildAssembly(structures[0], '1'), log, 100)
const structPointRepr = StructureRepresentation(Point)
await Run(structPointRepr.create(struct))
await Run(structPointRepr.create(struct), log, 100)
structPointRepr.renderObjects.forEach(viewer.add)
// const structSpacefillRepr = StructureRepresentation(Spacefill)
// await Run(structSpacefillRepr.create(struct, { detail: 0 }))
// await Run(structSpacefillRepr.create(struct, { detail: 2 }), log, 100)
// structSpacefillRepr.renderObjects.forEach(viewer.add)
viewer.requestDraw()
......
......@@ -5,15 +5,15 @@
*/
import { ValueCell } from 'mol-util';
import { ColorTexture, createColorTexture } from 'mol-gl/renderable/util';
import { Texture, createColorTexture } from 'mol-gl/renderable/util';
import Color from './color';
import { Mesh } from '../shape/mesh';
export type UniformColor = { type: 'uniform', value: number[] }
export type AttributeColor = { type: 'attribute', value: ValueCell<Float32Array> }
export type InstanceColor = { type: 'instance', value: ValueCell<ColorTexture> }
export type ElementColor = { type: 'element', value: ValueCell<ColorTexture> }
export type ElementInstanceColor = { type: 'element-instance', value: ValueCell<ColorTexture> }
export type InstanceColor = { type: 'instance', value: ValueCell<Texture> }
export type ElementColor = { type: 'element', value: ValueCell<Texture> }
export type ElementInstanceColor = { type: 'element-instance', value: ValueCell<Texture> }
export type ColorData = UniformColor | AttributeColor | InstanceColor | ElementColor | ElementInstanceColor
export interface UniformColorProps {
......
......@@ -9,6 +9,7 @@ import { EquivalenceClasses } from 'mol-data/util';
import { OrderedSet } from 'mol-data/int'
import { Task } from 'mol-task'
import { RenderObject } from 'mol-gl/scene';
// import { Mat4, EPSILON } from 'mol-math/linear-algebra';
export interface RepresentationProps {
......@@ -40,13 +41,22 @@ export function StructureRepresentation<Props>(reprCtor: () => UnitsRepresentati
(a, b) => a.unit.model.id === b.unit.model.id && OrderedSet.areEqual(a.group.elements, b.group.elements)
);
// const uniqueTransformations = EquivalenceClasses<number, { unit: Unit, group: ElementGroup }>(
// ({ unit, group }) => unit.operator.matrix.join(','),
// (a, b) => Mat4.areEqual(a.unit.operator.matrix, b.unit.operator.matrix, EPSILON.Value)
// );
const unitIndices = ElementSet.unitIndices(elements);
for (let i = 0, _i = unitIndices.length; i < _i; i++) {
const unitIndex = unitIndices[i];
const group = ElementSet.groupFromUnitIndex(elements, unitIndex);
uniqueGroups.add(unitIndex, { unit: units[unitIndex], group });
const unit = units[unitIndex]
uniqueGroups.add(unitIndex, { unit, group });
// uniqueTransformations.add(unitIndex, { unit, group });
}
// console.log({ uniqueGroups, uniqueTransformations })
for (let i = 0, _i = uniqueGroups.groups.length; i < _i; i++) {
const groupUnits: Unit[] = []
const group = uniqueGroups.groups[i]
......
......@@ -17,6 +17,8 @@ import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
import { createUniformColor, createInstanceColor } from '../../color/data';
import { fillSerial } from 'mol-gl/renderable/util';
import { ColorScale } from '../../color/scale';
import { createUniformSize } from '../../size/data';
import { vdwSizeData } from '../../size/structure/vdw';
export const DefaultPointProps = {
......@@ -59,18 +61,32 @@ export default function Point(): UnitsRepresentation<PointProps> {
unitCount
})
// const size = createUniformSize({ value: 1 })
const size = vdwSizeData({
units,
elementGroup,
offsetData: {
primitiveCount: elementCount,
offsetCount: elementCount + 1,
offsets: fillSerial(new Uint32Array(elementCount + 1))
}
})
console.log(size)
const points = createPointRenderObject({
objectId: 0,
position: ValueCell.create(ChunkedArray.compact(vertices, true) as Float32Array),
id: ValueCell.create(fillSerial(new Float32Array(unitCount))),
size: ValueCell.create(ChunkedArray.compact(sizes, true) as Float32Array),
size,
color,
transform: ValueCell.create(transformArray),
instanceCount: unitCount,
elementCount,
positionCount: vertices.elementCount
positionCount: vertices.elementCount,
usePointSizeAttenuation: true
})
renderObjects.push(points)
}),
......
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ValueCell } from 'mol-util';
export type UniformSize = { type: 'uniform', value: number }
export type AttributeSize = { type: 'attribute', value: ValueCell<Float32Array> }
export type SizeData = UniformSize | AttributeSize
export interface OffsetData {
primitiveCount: number,
offsetCount: number,
offsets: Uint32Array
}
export interface UniformSizeProps {
value: number
}
/** Creates size uniform */
export function createUniformSize(props: UniformSizeProps): UniformSize {
return { type: 'uniform', value: props.value }
}
export interface AttributeSizeProps {
sizeFn: (elementIdx: number) => number
offsetData: OffsetData
}
/** Creates size attribute with size for each element (i.e. shared across indtances/units) */
export function createAttributeSize(props: AttributeSizeProps): AttributeSize {
const { sizeFn, offsetData } = props
const { primitiveCount, offsetCount, offsets } = offsetData
const sizes = new Float32Array(primitiveCount);
const _offsets = offsets // .ref.value
for (let i = 0, il = offsetCount - 1; i < il; ++i) {
const start = _offsets[i]
const end = _offsets[i + 1]
const size = sizeFn(i)
for (let i = start, il = end; i < il; ++i) {
sizes[i] = size
}
}
return { type: 'attribute', value: ValueCell.create(sizes) }
}
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { SizeData } from './data'
export { SizeData }
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ElementGroup, Unit } from 'mol-model/structure';
import { OffsetData } from '../data';
export interface StructureSizeDataProps {
units: ReadonlyArray<Unit>,
elementGroup: ElementGroup,
offsetData: OffsetData
}
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { OrderedSet } from 'mol-data/int';
import { VdwRadius } from 'mol-model/structure/model/properties/atomic';
import { StructureSizeDataProps } from '.';
import { createAttributeSize } from '../data';
export function vdwSizeData(props: StructureSizeDataProps) {
const { units, elementGroup, offsetData } = props
const { type_symbol } = units[0].model.hierarchy.atoms
return createAttributeSize({
sizeFn: (elementIdx: number) => {
const e = OrderedSet.getAt(elementGroup.elements, elementIdx)
return VdwRadius(type_symbol.value(e))
},
offsetData
})
}
\ No newline at end of file
......@@ -11,6 +11,7 @@ import { Renderable } from '../renderable'
import { createBaseDefines, createBaseUniforms, createBaseAttributes, destroyUniforms, destroyAttributes } from './util'
import { PointShaders, addDefines } from '../shaders'
import { ColorData } from 'mol-geo/color';
import { SizeData } from 'mol-geo/size';
type Point = 'point'
......@@ -19,15 +20,17 @@ namespace Point {
objectId: number
position: ValueCell<Float32Array>
size?: ValueCell<Float32Array>
id: ValueCell<Float32Array>
size: SizeData
color: ColorData
transform: ValueCell<Float32Array>
instanceCount: number
elementCount: number
positionCount: number
positionCount: number,
usePointSizeAttenuation?: boolean
}
export function create(regl: REGL.Regl, props: Data): Renderable {
......@@ -35,6 +38,8 @@ namespace Point {
const uniforms = createBaseUniforms(regl, props)
const attributes = createBaseAttributes(regl, props)
if (props.usePointSizeAttenuation) defines.POINT_SIZE_ATTENUATION = ''
const command = regl({
...addDefines(defines, PointShaders),
uniforms,
......
......@@ -11,6 +11,7 @@ import { Attributes, AttributesData, AttributesBuffers } from '../renderable'
import Attribute from '../attribute'
import { ColorData } from 'mol-geo/color';
import { ShaderDefines } from '../shaders';
import { SizeData } from 'mol-geo/size';
export type ReglUniforms = { [k: string]: REGL.Uniform | REGL.Texture }
export type ReglAttributes = { [k: string]: REGL.AttributeConfig }
......@@ -23,12 +24,12 @@ export function calculateTextureInfo (n: number, itemSize: number) {
return { width, height, length: width * height * itemSize }
}
export interface ColorTexture extends Uint8Array {
export interface Texture extends Uint8Array {
width: number,
height: number
}
export function createColorTexture (n: number): ColorTexture {
export function createColorTexture (n: number): Texture {
const colorTexInfo = calculateTextureInfo(n, 3)
const colorTexture = new Uint8Array(colorTexInfo.length)
return Object.assign(colorTexture, {
......@@ -50,7 +51,7 @@ export function createTransformAttributes (regl: REGL.Regl, transform: ValueCell
}
}
export function createColorUniforms (regl: REGL.Regl, color: ValueCell<ColorTexture>) {
export function createColorUniforms (regl: REGL.Regl, color: ValueCell<Texture>) {
const colorTex = regl.texture({
width: color.ref.value.width,
height: color.ref.value.height,
......@@ -78,6 +79,15 @@ export function getColorDefines(color: ColorData) {
return defines
}
export function getSizeDefines(size: SizeData) {
const defines: ShaderDefines = {}
switch (size.type) {
case 'uniform': defines.UNIFORM_SIZE = ''; break;
case 'attribute': defines.ATTRIBUTE_SIZE = ''; break;
}
return defines
}
export function getBuffers<T extends AttributesData>(attributes: Attributes<T>): AttributesBuffers<T> {
const buffers: AttributesBuffers<any> = {}
for (const k of Object.keys(attributes)) {
......@@ -100,20 +110,24 @@ interface BaseProps {
position: ValueCell<Float32Array>
normal?: ValueCell<Float32Array>
size?: ValueCell<Float32Array>
id: ValueCell<Float32Array>
transform: ValueCell<Float32Array>
size?: SizeData
color: ColorData
}
export function createBaseUniforms(regl: REGL.Regl, props: BaseProps): ReglUniforms {
const { objectId, instanceCount, elementCount, color } = props
const { objectId, instanceCount, elementCount, color, size } = props
const uniforms = { objectId, instanceCount, elementCount }
if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
Object.assign(uniforms, createColorUniforms(regl, color.value))
} else if (color.type === 'uniform') {
Object.assign(uniforms, { color: color.value })
}
if (size && size.type === 'uniform') {
Object.assign(uniforms, { size: size.value })
}
return uniforms
}
......@@ -126,20 +140,23 @@ export function createBaseAttributes(regl: REGL.Regl, props: BaseProps): ReglAtt
elementId: Attribute.create(regl, id, positionCount, { size: 1 }),
...createTransformAttributes(regl, transform, instanceCount)
})
if (color.type === 'attribute') {
attributes.color = Attribute.create(regl, color.value, positionCount, { size: 3 }).buffer
}
if (normal) {
attributes.normal = Attribute.create(regl, normal as any, positionCount, { size: 3 }).buffer
}
if (size) {
attributes.size = Attribute.create(regl, size, positionCount, { size: 1 }).buffer
if (color.type === 'attribute') {
attributes.color = Attribute.create(regl, color.value, positionCount, { size: 3 }).buffer
}
if (size && size.type === 'attribute') {
attributes.size = Attribute.create(regl, size.value, positionCount, { size: 1 }).buffer
}
return attributes
}
export function createBaseDefines(regl: REGL.Regl, props: BaseProps) {
return getColorDefines(props.color)
export function createBaseDefines(regl: REGL.Regl, props: BaseProps): ShaderDefines {
return {
...getColorDefines(props.color),
...(props.size ? getSizeDefines(props.size) : undefined)
}
}
export function destroyAttributes(attributes: ReglAttributes) {
......
......@@ -39,6 +39,10 @@ const optionalExtensions = [
'EXT_disjoint_timer_query'
]
function getPixelRatio() {
return (typeof window !== 'undefined') ? window.devicePixelRatio : 1
}
namespace Renderer {
export function create(canvas: HTMLCanvasElement, camera: Camera): Renderer {
const regl = glContext.create({ canvas, extensions, optionalExtensions, profile: false })
......@@ -52,10 +56,14 @@ namespace Renderer {
projection: camera.projection,
},
uniforms: {
pixelRatio: getPixelRatio(),
viewportHeight: regl.context('viewportHeight'),
model: regl.context('model' as any),
transform: regl.context('transform' as any),
view: regl.context('view' as any),
projection: regl.context('projection' as any),
'light.position': Vec3.create(0, 0, -100),
'light.color': Vec3.create(1.0, 1.0, 1.0),
'light.ambient': Vec3.create(0.5, 0.5, 0.5),
......
......@@ -9,4 +9,4 @@
uniform sampler2D colorTex;
#endif
#pragma glslify: read_vec3 = require(../utils/read-vec3.glsl)
\ No newline at end of file
#pragma glslify: read_vec3 = require(../utils/read-from-texture.glsl)
\ No newline at end of file
......@@ -12,8 +12,17 @@ uniform int objectId;
uniform int instanceCount;
uniform int elementCount;
uniform float pixelRatio;
uniform float viewportHeight;
#pragma glslify: import('./chunks/color-vert-params.glsl')
#if defined(UNIFORM_SIZE)
uniform float size;
#elif defined(ATTRIBUTE_SIZE)
attribute float size;
#endif
attribute vec3 position;
attribute vec4 transformColumn0, transformColumn1, transformColumn2, transformColumn3;
attribute float instanceId;
......@@ -24,7 +33,13 @@ void main(){
mat4 transform = mat4(transformColumn0, transformColumn1, transformColumn2, transformColumn3);
mat4 modelView = view * model * transform;
vec4 mvPosition = modelView * vec4(position, 1.0);
#ifdef POINT_SIZE_ATTENUATION
gl_PointSize = size * pixelRatio * ((viewportHeight / 2.0) / -mvPosition.z) * 5.0;
#else
gl_PointSize = size * pixelRatio;
#endif
gl_PointSize = 1.0;
gl_Position = projection * modelView * vec4(position, 1.0);
gl_Position = projection * mvPosition;
}
\ No newline at end of file
......@@ -21,7 +21,9 @@ export const MeshShaders = {
}
type ShaderDefine = (
'UNIFORM_COLOR' | 'ATTRIBUTE_COLOR' | 'INSTANCE_COLOR' | 'ELEMENT_COLOR' | 'ELEMENT_INSTANCE_COLOR'
'UNIFORM_COLOR' | 'ATTRIBUTE_COLOR' | 'INSTANCE_COLOR' | 'ELEMENT_COLOR' | 'ELEMENT_INSTANCE_COLOR' |
'UNIFORM_SIZE' | 'ATTRIBUTE_SIZE' |
'POINT_SIZE_ATTENUATION'
)
export type ShaderDefines = {
[k in ShaderDefine]?: number|string
......
......@@ -86,7 +86,7 @@ namespace Viewer {
get stats() {
return renderer.stats
}
},
dispose: () => {
input.dispose()
controls.dispose()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment