diff --git a/src/mol-geo/representation/structure/units-visual.ts b/src/mol-geo/representation/structure/units-visual.ts index 785b9f9794e8d6582301256a0dd71dfb7c90dcca..353404ea7f7cca159122fc3810b2ffa0c4789054 100644 --- a/src/mol-geo/representation/structure/units-visual.ts +++ b/src/mol-geo/representation/structure/units-visual.ts @@ -551,7 +551,7 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde currentConformationId = Unit.conformationId(unit) directVolume = includesUnitKind(currentProps.unitKinds, unit) ? await createGeometry(ctx, unit, currentStructure, currentProps, directVolume) - : (webgl.isWebGL2 ? + : (webgl.isWebGL2 ? DirectVolume2d.createEmpty(directVolume as DirectVolume2d) : DirectVolume3d.createEmpty(directVolume as DirectVolume3d)) @@ -600,7 +600,7 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde if (updateState.createGeometry) { directVolume = includesUnitKind(newProps.unitKinds, unit) ? await createGeometry(ctx, unit, currentStructure, newProps, directVolume) - : (webgl.isWebGL2 ? + : (webgl.isWebGL2 ? DirectVolume2d.createEmpty(directVolume as DirectVolume2d) : DirectVolume3d.createEmpty(directVolume as DirectVolume3d)) updateState.updateColor = true diff --git a/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts b/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts index 7a582361c3f08f5c9a9a0ca7deb47f53922eca59..932cdad4e138e4a19f03360ecd814e456179ee92 100644 --- a/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts +++ b/src/mol-geo/representation/structure/visual/gaussian-density-volume.ts @@ -46,7 +46,10 @@ export function GaussianDensityVolumeVisual(): UnitsVisual<GaussianDensityVolume setUpdateState: (state: VisualUpdateState, newProps: GaussianDensityVolumeProps, currentProps: GaussianDensityVolumeProps) => { if (newProps.resolution !== currentProps.resolution) state.createGeometry = true if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true - if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true + if (newProps.smoothness !== currentProps.smoothness) { + state.createGeometry = true + newProps.isoValueAbsolute = Math.exp(-newProps.smoothness) + } if (newProps.useGpu !== currentProps.useGpu) state.createGeometry = true if (newProps.ignoreCache !== currentProps.ignoreCache) state.createGeometry = true } diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 4138d480b10c3659bac37f8db8d93cff876843dc..356ad888e9bb07ecd801d3c5a066805b24daf08a 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/src/mol-gl/renderable/direct-volume.ts @@ -34,15 +34,15 @@ export const DirectVolumeBaseSchema = { export type DirectVolumeBaseSchema = typeof DirectVolumeBaseSchema export type DirectVolumeBaseValues = Values<DirectVolumeBaseSchema> -function getInternalValues(ctx: Context, id: number, version: '100es' | '300es'): InternalValues { +function getInternalValues(ctx: Context, id: number): InternalValues { return { uObjectId: ValueCell.create(id) } } -function DirectVolumeRenderable<T extends DirectVolumeBaseValues, S extends DirectVolumeBaseSchema>(ctx: Context, id: number, values: T, state: RenderableState, schema: S, version: '100es' | '300es'): Renderable<T> { +function DirectVolumeRenderable<T extends DirectVolumeBaseValues, S extends DirectVolumeBaseSchema>(ctx: Context, id: number, values: T, state: RenderableState, schema: S): Renderable<T> { const fullSchema = Object.assign({}, GlobalUniformSchema, InternalSchema, schema) - const internalValues = getInternalValues(ctx, id, version) + const internalValues = getInternalValues(ctx, id) const fullValues = Object.assign({}, values, internalValues) const shaderCode = DirectVolumeShaderCode const renderItem = createRenderItem(ctx, 'triangles', shaderCode, fullSchema, fullValues) @@ -65,7 +65,7 @@ export type DirectVolume2dSchema = typeof DirectVolume2dSchema export type DirectVolume2dValues = Values<DirectVolume2dSchema> export function DirectVolume2dRenderable(ctx: Context, id: number, values: DirectVolume2dValues, state: RenderableState): Renderable<DirectVolume2dValues> { - return DirectVolumeRenderable(ctx, id, values, state, DirectVolume2dSchema, '100es') + return DirectVolumeRenderable(ctx, id, values, state, DirectVolume2dSchema) } // via 3d texture @@ -79,5 +79,5 @@ export type DirectVolume3dSchema = typeof DirectVolume3dSchema export type DirectVolume3dValues = Values<DirectVolume3dSchema> export function DirectVolume3dRenderable(ctx: Context, id: number, values: DirectVolume3dValues, state: RenderableState): Renderable<DirectVolume3dValues> { - return DirectVolumeRenderable(ctx, id, values, state, DirectVolume3dSchema, '300es') + return DirectVolumeRenderable(ctx, id, values, state, DirectVolume3dSchema) } \ No newline at end of file diff --git a/src/mol-gl/shader/direct-volume.frag b/src/mol-gl/shader/direct-volume.frag index 86754cb969f73a4e407312b77f7de68eb57603f0..82e6c5e40257235f6c990e09bd1e2eeeb3efe6c7 100644 --- a/src/mol-gl/shader/direct-volume.frag +++ b/src/mol-gl/shader/direct-volume.frag @@ -69,7 +69,7 @@ const vec3 color = vec3(0.45, 0.55, 0.8); vec4 raymarch(vec3 startLoc, vec3 step, vec3 viewDir) { vec3 scaleVol = vec3(1.0) / uGridDim; vec3 pos = startLoc + scaleVol * 0.5; - float prevValue = -127.0; + float prevValue = -1.0; float value = 0.0; vec4 src = vec4(0.0); vec4 dst = vec4(0.0); diff --git a/src/mol-gl/shader/gaussian-density.frag b/src/mol-gl/shader/gaussian-density.frag index ff0a4837122f88f23af0d3d424614985a1cda0da..547840a30a93c92bcf78951ce0d37925f11b3d56 100644 --- a/src/mol-gl/shader/gaussian-density.frag +++ b/src/mol-gl/shader/gaussian-density.frag @@ -5,7 +5,7 @@ * @author Michael Krone <michael.krone@uni-tuebingen.de> */ -precision mediump float; +precision highp float; varying vec3 position; varying float radius; @@ -31,27 +31,28 @@ uniform float uAlpha; layout(location = 7) out vec4 out7; #endif -float calcDensity(float x, float y, float z) { +float calcDensity(float x, float y, float z, float radiusSq) { vec3 fragPos = vec3(x, y, z) / uGridDim; - float dist = length(fragPos * uBboxSize - position * uBboxSize); - float density = exp(-uAlpha * ((dist * dist) / (radius * radius))); + float dist = distance(fragPos * uBboxSize, position * uBboxSize); + float density = exp(-uAlpha * ((dist * dist) / radiusSq)); return density; } const vec3 color = vec3(1.0, 1.0, 1.0); void main() { + float radiusSq = radius * radius; vec2 v = gl_FragCoord.xy - vec2(uCurrentX, uCurrentY) - 0.5; - gl_FragColor = vec4(color, calcDensity(v.x, v.y, uCurrentSlice)); + out_FragColor = vec4(color, calcDensity(v.x, v.y, uCurrentSlice, radiusSq)); #if dDrawBuffers >= 4 - out1 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 1.0)); - out2 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 2.0)); - out3 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 3.0)); + out1 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 1.0, radiusSq)); + out2 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 2.0, radiusSq)); + out3 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 3.0, radiusSq)); #endif #if dDrawBuffers >= 8 - out4 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 4.0)); - out5 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 5.0)); - out6 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 6.0)); - out7 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 7.0)); + out4 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 4.0, radiusSq)); + out5 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 5.0, radiusSq)); + out6 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 6.0, radiusSq)); + out7 = vec4(color, calcDensity(v.x, v.y, uCurrentSlice + 7.0, radiusSq)); #endif } \ No newline at end of file diff --git a/src/mol-gl/shader/gaussian-density.vert b/src/mol-gl/shader/gaussian-density.vert index 2bbc651750d6a67283d8a8ea0126ed4a867bc1d0..217f0085a8a5d87aa2f6341e87f49bf122f54861 100644 --- a/src/mol-gl/shader/gaussian-density.vert +++ b/src/mol-gl/shader/gaussian-density.vert @@ -5,7 +5,7 @@ * @author Michael Krone <michael.krone@uni-tuebingen.de> */ -precision mediump float; +precision highp float; attribute vec3 aPosition; attribute float aRadius; diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts index 69bb48dfeae42cebc786d20bdcd9eef2c646b467..e51497592f8d242be50a2ab3b594afdbac5229c5 100644 --- a/src/mol-gl/webgl/texture.ts +++ b/src/mol-gl/webgl/texture.ts @@ -37,7 +37,7 @@ export function getTarget(ctx: Context, kind: TextureKind): number { case 'image-float32': return gl.TEXTURE_2D case 'texture2d': return gl.TEXTURE_2D } - if(isWebGL2(gl)) { + if (isWebGL2(gl)) { switch (kind) { case 'volume-uint8': return gl.TEXTURE_3D case 'volume-float32': return gl.TEXTURE_3D @@ -198,6 +198,7 @@ export function createTexture(ctx: Context, kind: TextureKind, _format: TextureF // unpack alignment of 1 since we use textures only for data gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0); if (target === gl.TEXTURE_2D) { const { array, width: _width, height: _height } = data as TextureImage<any> width = _width, height = _height; diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts index bd86f88b7d799b268255a66f3910b77e180974f7..170170fc0204e5d8d72f4d775d305f8846125fcd 100644 --- a/src/mol-math/geometry/gaussian-density/gpu.ts +++ b/src/mol-math/geometry/gaussian-density/gpu.ts @@ -25,11 +25,9 @@ export async function GaussianDensityGPU(ctx: RuntimeContext, position: Position const { transform, texture, gridDimension } = await GaussianDensityTexture(ctx, webgl, position, box, radius, props) - console.time('gpu gaussian density read') const field = webgl.maxDrawBuffers > 0 ? fieldFromTexture3d(webgl, texture, gridDimension) : fieldFromTexture2d(webgl, texture, gridDimension) - console.timeEnd('gpu gaussian density read') const idData = field.space.create() const idField = Tensor.create(field.space, idData) @@ -38,9 +36,11 @@ export async function GaussianDensityGPU(ctx: RuntimeContext, position: Position } export async function GaussianDensityTexture(ctx: RuntimeContext, webgl: Context, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, oldTexture?: Texture): Promise<DensityTextureData> { + console.time(`GaussianDensityTexture, ${webgl.maxDrawBuffers > 0 ? 'multi' : 'single'}`) const { texture, scale, bbox, dim } = webgl.maxDrawBuffers > 0 ? await GaussianDensityMultiDrawBuffer(ctx, webgl, position, box, radius, props, oldTexture) : await GaussianDensitySingleDrawBuffer(ctx, webgl, position, box, radius, props, oldTexture) + console.timeEnd(`GaussianDensityTexture, ${webgl.maxDrawBuffers > 0 ? 'multi' : 'single'}`) const transform = Mat4.identity() Mat4.fromScaling(transform, scale) @@ -283,12 +283,13 @@ function setRenderingDefaults(gl: GLRenderingContext) { gl.frontFace(gl.CCW) gl.cullFace(gl.BACK) - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + gl.blendFunc(gl.ONE, gl.ONE) gl.blendEquation(gl.FUNC_ADD) gl.enable(gl.BLEND) } function fieldFromTexture2d(ctx: Context, texture: Texture, dim: Vec3) { + console.time('fieldFromTexture2d') const { gl } = ctx const [ dx, dy, dz ] = dim const { width, height } = texture @@ -316,7 +317,7 @@ function fieldFromTexture2d(ctx: Context, texture: Texture, dim: Vec3) { } for (let iy = 0; iy < dy; ++iy) { for (let ix = 0; ix < dx; ++ix) { - data[idx] = image[4 * (tmpCol * dx + (iy + tmpRow) * width + ix)] / 255 + data[idx] = image[4 * (tmpCol * dx + (iy + tmpRow) * width + ix) + 3] / 255 idx++ } } @@ -324,11 +325,13 @@ function fieldFromTexture2d(ctx: Context, texture: Texture, dim: Vec3) { } framebuffer.destroy() + console.timeEnd('fieldFromTexture2d') return field } function fieldFromTexture3d(ctx: Context, texture: Texture, dim: Vec3) { + console.time('fieldFromTexture3d') const { gl } = ctx const { width, height, depth } = texture @@ -347,13 +350,14 @@ function fieldFromTexture3d(ctx: Context, texture: Texture, dim: Vec3) { gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, slice) for (let iy = 0; iy < height; ++iy) { for (let ix = 0; ix < width; ++ix) { - data[j] = slice[4 * (iy * width + ix)] / 255 + data[j] = slice[4 * (iy * width + ix) + 3] / 255 ++j } } } framebuffer.destroy() + console.timeEnd('fieldFromTexture3d') return field } \ No newline at end of file