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

gpu gaussian density tweaks

parent 006f6572
No related branches found
No related tags found
No related merge requests found
......@@ -43,7 +43,7 @@ export async function GaussianDensity(ctx: RuntimeContext, position: PositionDat
if (props.useGpu) {
if (!GaussianDensityGPU) throw 'GPU computation not supported on this platform';
if (!webgl) throw 'No WebGL context provided';
return await GaussianDensityGPU(ctx, position, box, radius, props, webgl)
return GaussianDensityGPU(position, box, radius, props, webgl)
} else {
return await GaussianDensityCPU(ctx, position, box, radius, props)
}
......@@ -65,7 +65,7 @@ function _computeGaussianDensityTexture(type: '2d' | '3d', position: PositionDat
if (!GaussianDensityTexture) throw 'GPU computation not supported on this platform';
return Task.create('Gaussian Density', async ctx => {
return type === '2d' ?
await GaussianDensityTexture2d(ctx, webgl, position, box, radius, props, texture) :
await GaussianDensityTexture3d(ctx, webgl, position, box, radius, props, texture);
GaussianDensityTexture2d(webgl, position, box, radius, props, texture) :
GaussianDensityTexture3d(webgl, position, box, radius, props, texture);
});
}
\ No newline at end of file
......@@ -5,7 +5,6 @@
* @author Michael Krone <michael.krone@uni-tuebingen.de>
*/
import { RuntimeContext } from 'mol-task'
import { PositionData, DensityData, DensityTextureData } from '../common'
import { Box3D } from '../../geometry'
import { GaussianDensityGPUProps } from '../gaussian-density'
......@@ -53,30 +52,30 @@ export const GaussianDensityShaderCode = ShaderCode(
/** name for shared framebuffer used for gpu gaussian surface operations */
const FramebufferName = 'gaussian-density'
export async function GaussianDensityGPU(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, webgl: WebGLContext): Promise<DensityData> {
export function GaussianDensityGPU(position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, webgl: WebGLContext): DensityData {
// always use texture2d when the gaussian density needs to be downloaded from the GPU,
// it's faster than texture3d
// console.time('GaussianDensityTexture2d')
const { scale, bbox, texture, dim } = await calcGaussianDensityTexture2d(ctx, webgl, position, box, radius, props)
const { scale, bbox, texture, dim } = calcGaussianDensityTexture2d(webgl, position, box, radius, props)
// webgl.waitForGpuCommandsCompleteSync()
// console.timeEnd('GaussianDensityTexture2d')
const { field, idField } = await fieldFromTexture2d(webgl, texture, dim)
const { field, idField } = fieldFromTexture2d(webgl, texture, dim)
return { field, idField, transform: getTransform(scale, bbox) }
}
export async function GaussianDensityTexture(ctx: RuntimeContext, webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, oldTexture?: Texture): Promise<DensityTextureData> {
export function GaussianDensityTexture(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, oldTexture?: Texture): DensityTextureData {
return webgl.isWebGL2 ?
await GaussianDensityTexture3d(ctx, webgl, position, box, radius, props, oldTexture) :
await GaussianDensityTexture2d(ctx, webgl, position, box, radius, props, oldTexture)
GaussianDensityTexture3d(webgl, position, box, radius, props, oldTexture) :
GaussianDensityTexture2d(webgl, position, box, radius, props, oldTexture)
}
export async function GaussianDensityTexture2d(ctx: RuntimeContext, webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, oldTexture?: Texture): Promise<DensityTextureData> {
return finalizeGaussianDensityTexture(await calcGaussianDensityTexture2d(ctx, webgl, position, box, radius, props, oldTexture))
export function GaussianDensityTexture2d(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, oldTexture?: Texture): DensityTextureData {
return finalizeGaussianDensityTexture(calcGaussianDensityTexture2d(webgl, position, box, radius, props, oldTexture))
}
export async function GaussianDensityTexture3d(ctx: RuntimeContext, webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, oldTexture?: Texture): Promise<DensityTextureData> {
return finalizeGaussianDensityTexture(await calcGaussianDensityTexture3d(ctx, webgl, position, box, radius, props, oldTexture))
export function GaussianDensityTexture3d(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, oldTexture?: Texture): DensityTextureData {
return finalizeGaussianDensityTexture(calcGaussianDensityTexture3d(webgl, position, box, radius, props, oldTexture))
}
function finalizeGaussianDensityTexture({ texture, scale, bbox, dim }: GaussianDensityTextureData): DensityTextureData {
......@@ -94,10 +93,10 @@ function getTransform(scale: Vec3, bbox: Box3D) {
type GaussianDensityTextureData = { texture: Texture, scale: Vec3, bbox: Box3D, dim: Vec3}
async function calcGaussianDensityTexture2d(ctx: RuntimeContext, webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, texture?: Texture): Promise<GaussianDensityTextureData> {
function calcGaussianDensityTexture2d(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, texture?: Texture): GaussianDensityTextureData {
const { smoothness } = props
const { drawCount, positions, radii, groups, delta, expandedBox, dim } = await prepareGaussianDensityData(ctx, position, box, radius, props)
const { drawCount, positions, radii, groups, delta, expandedBox, dim } = prepareGaussianDensityData(position, box, radius, props)
const [ dx, dy, dz ] = dim
const { texDimX, texDimY, texCols } = getTexture2dSize(dim)
......@@ -148,15 +147,13 @@ async function calcGaussianDensityTexture2d(ctx: RuntimeContext, webgl: WebGLCon
setupGroupIdRendering(webgl, renderable)
render(texture)
if (ctx.shouldUpdate) await ctx.update({ message: 'gpu gaussian density calculation' })
return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim }
}
async function calcGaussianDensityTexture3d(ctx: RuntimeContext, webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, texture?: Texture): Promise<GaussianDensityTextureData> {
function calcGaussianDensityTexture3d(webgl: WebGLContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps, texture?: Texture): GaussianDensityTextureData {
const { smoothness } = props
const { drawCount, positions, radii, groups, delta, expandedBox, dim } = await prepareGaussianDensityData(ctx, position, box, radius, props)
const { drawCount, positions, radii, groups, delta, expandedBox, dim } = prepareGaussianDensityData(position, box, radius, props)
const [ dx, dy, dz ] = dim
const minDistanceTexture = createTexture(webgl, 'volume-float32', 'rgba', 'float', 'nearest')
minDistanceTexture.define(dx, dy, dz)
......@@ -193,14 +190,12 @@ async function calcGaussianDensityTexture3d(ctx: RuntimeContext, webgl: WebGLCon
setupGroupIdRendering(webgl, renderable)
render(texture)
if (ctx.shouldUpdate) await ctx.update({ message: 'gpu gaussian density calculation' });
return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim }
}
//
async function prepareGaussianDensityData(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps) {
function prepareGaussianDensityData(position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityGPUProps) {
const { resolution, radiusOffset } = props
const { indices, x, y, z } = position
......@@ -222,10 +217,6 @@ async function prepareGaussianDensityData(ctx: RuntimeContext, position: Positio
if (maxRadius < r) maxRadius = r
radii[i] = r
groups[i] = i
if (i % 10000 === 0 && ctx.shouldUpdate) {
await ctx.update({ message: 'preparing density data', current: i, max: n })
}
}
const pad = maxRadius * 2 + resolution
......@@ -237,9 +228,6 @@ async function prepareGaussianDensityData(ctx: RuntimeContext, position: Positio
Vec3.ceil(dim, dim)
const delta = Vec3.div(Vec3(), dim, expandedDim)
// console.log({ maxRadius, resolution, pad, box, expandedBox, delta })
// console.log('grid dim gpu', dim)
return { drawCount: n, positions, radii, groups, delta, expandedBox, dim }
}
......@@ -330,7 +318,7 @@ function getTexture2dSize(gridDim: Vec3) {
return { texDimX, texDimY, texRows, texCols }
}
export async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3) {
export function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3) {
// console.time('fieldFromTexture2d')
const { framebufferCache } = ctx
const [ dx, dy, dz ] = dim
......@@ -349,8 +337,6 @@ export async function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, di
const framebuffer = framebufferCache.get(FramebufferName).value
framebuffer.bind()
texture.attachFramebuffer(framebuffer, 0)
// TODO too slow, why? Too many checks if gpu ready???
// await ctx.readPixelsAsync(0, 0, width, height, image)
ctx.readPixels(0, 0, width, height, image)
// printImageData(createImageData(image, width, height), 1/3)
......
......@@ -42,14 +42,14 @@ export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityPro
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);
return GaussianDensityTexture(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);
return GaussianDensityTexture2d(webgl, position, unit.lookup3d.boundary.box, radius, props, texture);
});
}
......@@ -65,6 +65,6 @@ export function computeStructureGaussianDensity(structure: Structure, props: Gau
export function computeStructureGaussianDensityTexture(structure: Structure, props: GaussianDensityTextureProps, webgl: WebGLContext, texture?: Texture) {
const { position, radius } = getStructureConformationAndRadius(structure)
return Task.create('Gaussian Density', async ctx => {
return await GaussianDensityTexture(ctx, webgl, position, structure.lookup3d.boundary.box, radius, props, texture);
return GaussianDensityTexture(webgl, position, structure.lookup3d.boundary.box, radius, props, texture);
});
}
\ 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