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

wip, point rendering

parent 28beb5ab
Branches
Tags
No related merge requests found
......@@ -11,6 +11,7 @@ import { ColorThemeProps, ColorThemeName, ColorThemeNames, ColorTheme } from 'mo
import { Color } from 'mol-util/color';
import { Progress } from 'mol-task';
import { VisualQuality, VisualQualityNames } from 'mol-geo/geometry/geometry';
import { SizeThemeProps } from 'mol-view/theme/size';
export interface StructureRepresentationComponentProps {
viewer: Viewer
......@@ -23,43 +24,43 @@ export interface StructureRepresentationComponentState {
alpha: number
quality: VisualQuality
colorTheme: ColorThemeProps
sizeTheme: SizeThemeProps
depthMask: boolean
flatShaded?: boolean
resolutionFactor?: number
radiusOffset?: number
smoothness?: number
pointSizeAttenuation?: boolean
pointFilledCircle?: boolean
pointEdgeBleach?: number
}
export class StructureRepresentationComponent extends React.Component<StructureRepresentationComponentProps, StructureRepresentationComponentState> {
state = {
label: this.props.representation.label,
visible: this.props.representation.props.visible,
alpha: this.props.representation.props.alpha,
quality: this.props.representation.props.quality,
colorTheme: this.props.representation.props.colorTheme,
state = this.stateFromRepresentation(this.props.representation)
flatShaded: (this.props.representation.props as any).flatShaded,
resolutionFactor: (this.props.representation.props as any).resolutionFactor,
radiusOffset: (this.props.representation.props as any).radiusOffset,
smoothness: (this.props.representation.props as any).smoothness,
}
componentWillMount() {
const repr = this.props.representation
this.setState({
...this.state,
private stateFromRepresentation(repr: StructureRepresentation<StructureProps>) {
return {
label: repr.label,
visible: repr.props.visible,
alpha: repr.props.alpha,
quality: repr.props.quality,
colorTheme: repr.props.colorTheme,
sizeTheme: repr.props.sizeTheme,
depthMask: repr.props.depthMask,
flatShaded: (repr.props as any).flatShaded,
resolutionFactor: (repr.props as any).resolutionFactor,
radiusOffset: (repr.props as any).radiusOffset,
smoothness: (repr.props as any).smoothness,
})
pointSizeAttenuation: (repr.props as any).pointSizeAttenuation,
pointFilledCircle: (repr.props as any).pointFilledCircle,
pointEdgeBleach: (repr.props as any).pointEdgeBleach,
}
}
componentWillMount() {
this.setState(this.stateFromRepresentation(this.props.representation))
}
async update(state: Partial<StructureRepresentationComponentState>) {
......@@ -70,11 +71,16 @@ export class StructureRepresentationComponent extends React.Component<StructureR
if (state.quality !== undefined) props.quality = state.quality
if (state.alpha !== undefined) props.alpha = state.alpha
if (state.colorTheme !== undefined) props.colorTheme = state.colorTheme
if (state.sizeTheme !== undefined) props.sizeTheme = state.sizeTheme
if (state.depthMask !== undefined) props.depthMask = state.depthMask
if (state.flatShaded !== undefined) (props as any).flatShaded = state.flatShaded
if (state.resolutionFactor !== undefined) (props as any).resolutionFactor = state.resolutionFactor
if (state.radiusOffset !== undefined) (props as any).radiusOffset = state.radiusOffset
if (state.smoothness !== undefined) (props as any).smoothness = state.smoothness
if (state.pointSizeAttenuation !== undefined) (props as any).pointSizeAttenuation = state.pointSizeAttenuation
if (state.pointFilledCircle !== undefined) (props as any).pointFilledCircle = state.pointFilledCircle
if (state.pointEdgeBleach !== undefined) (props as any).pointEdgeBleach = state.pointEdgeBleach
await repr.createOrUpdate(props).run(
progress => console.log(Progress.format(progress))
......@@ -83,39 +89,13 @@ export class StructureRepresentationComponent extends React.Component<StructureR
this.props.viewer.draw(true)
console.log(this.props.viewer.stats)
console.log(
'drawCount',
repr.renderObjects[0].values.drawCount.ref.version,
repr.renderObjects[0].values.drawCount.ref.value,
'dColorType',
repr.renderObjects[0].values.dColorType.ref.version,
repr.renderObjects[0].values.dColorType.ref.value
)
const newState = {
...this.state,
visible: repr.props.visible,
quality: repr.props.quality,
alpha: repr.props.alpha,
colorTheme: repr.props.colorTheme,
flatShaded: (repr.props as any).flatShaded,
resolutionFactor: (repr.props as any).resolutionFactor,
radiusOffset: (repr.props as any).radiusOffset,
isoValue: (repr.props as any).isoValue,
}
this.setState(newState)
this.setState(this.stateFromRepresentation(repr))
}
render() {
const { label, visible, quality, alpha, colorTheme } = this.state
const { label, visible, quality, alpha, colorTheme, depthMask } = this.state
const ct = ColorTheme(colorTheme)
if (ct.legend && ct.legend.kind === 'scale-legend') {
// console.log(`linear-gradient(to right, ${ct.legend.colors.map(c => Color.toStyle(c)).join(', ')})`)
}
return <div>
<div>
<h4>{label}</h4>
......@@ -127,6 +107,12 @@ export class StructureRepresentationComponent extends React.Component<StructureR
{visible ? 'Hide' : 'Show'}
</button>
</div>
<div>
<span>Depth Mask </span>
<button onClick={(e) => this.update({ depthMask: !depthMask }) }>
{depthMask ? 'Deactivate' : 'Activate'}
</button>
</div>
{ this.state.flatShaded !== undefined ? <div>
<span>Flat Shaded </span>
<button onClick={(e) => this.update({ flatShaded: !this.state.flatShaded }) }>
......@@ -183,6 +169,42 @@ export class StructureRepresentationComponent extends React.Component<StructureR
>
</input>
</div> : '' }
{ this.state.pointSizeAttenuation !== undefined ? <div>
<span>Size Attenuation </span>
<button onClick={(e) => this.update({ pointSizeAttenuation: !this.state.pointSizeAttenuation }) }>
{this.state.pointSizeAttenuation ? 'Deactivate' : 'Activate'}
</button>
</div> : '' }
{ this.state.pointFilledCircle !== undefined ? <div>
<span>Filled Circle </span>
<button onClick={(e) => this.update({ pointFilledCircle: !this.state.pointFilledCircle }) }>
{this.state.pointFilledCircle ? 'Deactivate' : 'Activate'}
</button>
</div> : '' }
{ this.state.pointEdgeBleach !== undefined ? <div>
<span>Edge Bleach </span>
<input type='range'
defaultValue={this.state.pointEdgeBleach.toString()}
min='0'
max='1'
step='0.05'
onInput={(e) => this.update({ pointEdgeBleach: parseFloat(e.currentTarget.value) })}
>
</input>
</div> : '' }
{ this.state.sizeTheme !== undefined && this.state.sizeTheme.name === 'uniform' ? <div>
<span>Uniform Size </span>
<input type='range'
defaultValue={this.state.sizeTheme.value!.toString()}
min='0'
max='10'
step='0.1'
onInput={(e) => this.update({
sizeTheme: { name: 'uniform', value: parseFloat(e.currentTarget.value) }
})}
>
</input>
</div> : '' }
<div>
<span>Color Theme </span>
<select value={colorTheme.name} onChange={(e) => this.update({ colorTheme: { name: e.target.value as ColorThemeName } }) }>
......
......@@ -55,6 +55,8 @@ export namespace Point {
export const DefaultProps = {
...Geometry.DefaultProps,
pointSizeAttenuation: false,
pointFilledCircle: false,
pointEdgeBleach: 0.2,
sizeTheme: { name: 'uniform', value: 1 } as SizeThemeProps,
}
export type Props = typeof DefaultProps
......@@ -77,11 +79,15 @@ export namespace Point {
...Geometry.createValues(props, counts),
dPointSizeAttenuation: ValueCell.create(props.pointSizeAttenuation),
dPointFilledCircle: ValueCell.create(props.pointFilledCircle),
uPointEdgeBleach: ValueCell.create(props.pointEdgeBleach),
}
}
export function updateValues(values: PointValues, props: Props) {
Geometry.updateValues(values, props)
ValueCell.updateIfChanged(values.dPointSizeAttenuation, props.pointSizeAttenuation)
ValueCell.updateIfChanged(values.dPointFilledCircle, props.pointFilledCircle)
ValueCell.updateIfChanged(values.uPointEdgeBleach, props.pointEdgeBleach)
}
}
\ No newline at end of file
......@@ -20,6 +20,7 @@ import { Interval } from 'mol-data/int';
import { Point } from '../../geometry/point/point';
import { updateRenderableState } from '../../geometry/geometry';
import { createColors } from '../../geometry/color-data';
import { createSizes } from '../../geometry/size-data';
export type StructureGroup = { structure: Structure, group: Unit.SymmetryGroup }
......@@ -245,7 +246,7 @@ export function UnitsPointVisual<P extends UnitsPointProps>(builder: UnitsPointV
if (currentGroup.units.length !== locationIt.instanceCount) updateState.updateTransform = true
if (!deepEqual(newProps.sizeTheme, currentProps.sizeTheme)) updateState.createGeometry = true
if (!deepEqual(newProps.sizeTheme, currentProps.sizeTheme)) updateState.updateSize = true
if (!deepEqual(newProps.colorTheme, currentProps.colorTheme)) updateState.updateColor = true
if (!deepEqual(newProps.unitKinds, currentProps.unitKinds)) updateState.createGeometry = true
......@@ -267,6 +268,10 @@ export function UnitsPointVisual<P extends UnitsPointProps>(builder: UnitsPointV
updateState.updateColor = true
}
if (updateState.updateSize) {
await createSizes(ctx, locationIt, newProps.sizeTheme, renderObject.values)
}
if (updateState.updateColor) {
await createColors(ctx, locationIt, newProps.colorTheme, renderObject.values)
}
......
......@@ -73,6 +73,8 @@ function createPoints() {
instanceCount: ValueCell.create(1),
dPointSizeAttenuation: ValueCell.create(true),
dPointFilledCircle: ValueCell.create(false),
uPointEdgeBleach: ValueCell.create(0.5),
dUseFog: ValueCell.create(true),
}
const state: RenderableState = {
......
......@@ -19,6 +19,7 @@ export interface Renderable<T extends RenderableValues & BaseValues> {
readonly values: T
readonly state: RenderableState
readonly boundingSphere: Sphere3D
readonly opaque: boolean
render: (variant: RenderVariant) => void
getProgram: (variant: RenderVariant) => Program
......@@ -37,6 +38,7 @@ export function createRenderable<T extends Values<RenderableSchema> & BaseValues
boundingSphere = calculateBoundingSphereFromValues(values)
return boundingSphere
},
get opaque () { return values.uAlpha.ref.value === 1 },
render: (variant: RenderVariant) => renderItem.render(variant),
getProgram: (variant: RenderVariant) => renderItem.getProgram(variant),
......
......@@ -27,8 +27,8 @@ export function MeshRenderable(ctx: Context, id: number, values: MeshValues, sta
const internalValues = {
uObjectId: ValueCell.create(id)
}
const schaderCode = MeshShaderCode
const renderItem = createRenderItem(ctx, 'triangles', schaderCode, schema, { ...values, ...internalValues })
const shaderCode = MeshShaderCode
const renderItem = createRenderItem(ctx, 'triangles', shaderCode, schema, { ...values, ...internalValues })
return createRenderable(renderItem, values, state)
}
\ No newline at end of file
......@@ -19,6 +19,8 @@ export const PointSchema = {
tSize: TextureSpec('alpha', 'ubyte'),
dSizeType: DefineSpec('string', ['uniform', 'attribute']),
dPointSizeAttenuation: DefineSpec('boolean'),
dPointFilledCircle: DefineSpec('boolean'),
uPointEdgeBleach: UniformSpec('f'),
}
export type PointSchema = typeof PointSchema
export type PointValues = Values<PointSchema>
......@@ -28,8 +30,14 @@ export function PointRenderable(ctx: Context, id: number, values: PointValues, s
const internalValues = {
uObjectId: ValueCell.create(id)
}
const schaderCode = PointShaderCode
const renderItem = createRenderItem(ctx, 'points', schaderCode, schema, { ...values, ...internalValues })
const shaderCode = PointShaderCode
const renderItem = createRenderItem(ctx, 'points', shaderCode, schema, { ...values, ...internalValues })
const renderable = createRenderable(renderItem, values, state);
return createRenderable(renderItem, values, state)
const isOpaque = Object.getOwnPropertyDescriptor(renderable, 'opaque')!.get as () => boolean
Object.defineProperty(renderable, 'opaque', {
get: () => isOpaque() && !values.dPointFilledCircle.ref.value && values.uPointEdgeBleach.ref.value === 0
});
return renderable
}
\ No newline at end of file
......@@ -90,12 +90,12 @@ namespace Scene {
},
eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
renderableMap.forEach((r, o) => {
if (o.values.uAlpha.ref.value === 1) callbackFn(r, o)
if (r.opaque) callbackFn(r, o)
})
},
eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
renderableMap.forEach((r, o) => {
if (o.values.uAlpha.ref.value < 1) callbackFn(r, o)
if (!r.opaque) callbackFn(r, o)
})
},
get count() {
......
......@@ -10,11 +10,29 @@ precision highp int;
#pragma glslify: import('./chunks/common-frag-params.glsl')
#pragma glslify: import('./chunks/color-frag-params.glsl')
#ifdef dPointFilledCircle
uniform float uPointEdgeBleach;
#endif
const vec2 center = vec2(0.5);
const float radius = 0.5;
void main(){
#pragma glslify: import('./chunks/assign-material-color.glsl')
#if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
gl_FragColor = material;
#else
gl_FragColor = material;
#ifdef dPointFilledCircle
float dist = distance(gl_PointCoord, center);
float alpha = 1.0 - smoothstep(radius - uPointEdgeBleach * 2.0, radius, dist);
gl_FragColor.a *= alpha;
if (gl_FragColor.a < 0.1) discard;
#endif
#pragma glslify: import('./chunks/apply-marker-color.glsl')
#pragma glslify: import('./chunks/apply-fog.glsl')
#endif
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment