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

removed MRT support for GPU gaussian density (slow)

parent 9606ec42
No related branches found
No related tags found
No related merge requests found
......@@ -25,8 +25,6 @@ export const GaussianDensitySchema = {
uBboxSize: UniformSpec('v3'),
uGridDim: UniformSpec('v3'),
uAlpha: UniformSpec('f'),
dDrawBuffers: DefineSpec('number'),
}
export type GaussianDensitySchema = typeof GaussianDensitySchema
export type GaussianDensityValues = Values<GaussianDensitySchema>
......
......@@ -7,8 +7,8 @@
precision highp float;
varying vec3 position;
varying float radius;
varying vec3 vPosition;
varying float vRadius;
uniform vec3 uBboxSize;
uniform vec3 uBboxMin;
......@@ -19,40 +19,15 @@ uniform float uCurrentX;
uniform float uCurrentY;
uniform float uAlpha;
#if dDrawBuffers >= 4
layout(location = 1) out vec4 out1;
layout(location = 2) out vec4 out2;
layout(location = 3) out vec4 out3;
#endif
#if dDrawBuffers >= 8
layout(location = 4) out vec4 out4;
layout(location = 5) out vec4 out5;
layout(location = 6) out vec4 out6;
layout(location = 7) out vec4 out7;
#endif
float calcDensity(float x, float y, float z, float radiusSq) {
vec4 calc(float x, float y, float z, float radiusSq) {
vec3 fragPos = vec3(x, y, z) / uGridDim;
float dist = distance(fragPos * uBboxSize, position * uBboxSize);
float dist = distance(fragPos * uBboxSize, vPosition * uBboxSize);
float density = exp(-uAlpha * ((dist * dist) / radiusSq));
return density;
return vec4(density);
}
const vec3 color = vec3(1.0, 1.0, 1.0);
void main() {
float radiusSq = radius * radius;
float radiusSq = vRadius * vRadius;
vec2 v = gl_FragCoord.xy - vec2(uCurrentX, uCurrentY) - 0.5;
gl_FragColor = vec4(color, calcDensity(v.x, v.y, uCurrentSlice, radiusSq));
#if dDrawBuffers >= 4
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, 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
gl_FragColor = calc(v.x, v.y, uCurrentSlice, radiusSq);
}
\ No newline at end of file
......@@ -10,8 +10,8 @@ precision highp float;
attribute vec3 aPosition;
attribute float aRadius;
varying vec3 position;
varying float radius;
varying vec3 vPosition;
varying float vRadius;
uniform vec3 uBboxSize;
uniform vec3 uBboxMin;
......@@ -20,9 +20,9 @@ uniform vec3 uGridDim;
uniform float uCurrentSlice;
void main() {
radius = aRadius;
vRadius = aRadius;
float scale = max(uBboxSize.z, max(uBboxSize.x, uBboxSize.y));
gl_PointSize = (radius / scale) * max(uGridDim.x, uGridDim.y) * 6.0;
position = (aPosition - uBboxMin) / uBboxSize;
gl_Position = vec4(position * 2.0 - 1.0, 1.0);
gl_PointSize = (vRadius / scale) * max(uGridDim.x, uGridDim.y) * 6.0;
vPosition = (aPosition - uBboxMin) / uBboxSize;
gl_Position = vec4(vPosition * 2.0 - 1.0, 1.0);
}
\ No newline at end of file
......@@ -17,7 +17,7 @@ import { RenderableState } from 'mol-gl/renderable'
import { createRenderable, createGaussianDensityRenderObject } from 'mol-gl/render-object'
import { Context, createContext, getGLContext } from 'mol-gl/webgl/context';
import { createFramebuffer } from 'mol-gl/webgl/framebuffer';
import { createTexture, Texture, TextureAttachment } from 'mol-gl/webgl/texture';
import { createTexture, Texture } from 'mol-gl/webgl/texture';
import { GLRenderingContext } from 'mol-gl/webgl/compat';
export async function GaussianDensityGPU(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps): Promise<DensityData> {
......@@ -36,11 +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'}`)
console.time(`GaussianDensityTexture, ${webgl.isWebGL2 ? '3d' : '2d'}`)
const { texture, scale, bbox, dim } = webgl.isWebGL2 ?
await GaussianDensityTexture3d(ctx, webgl, position, box, radius, props, oldTexture) :
await GaussianDensityTexture2d(ctx, webgl, position, box, radius, props, oldTexture)
console.timeEnd(`GaussianDensityTexture, ${webgl.isWebGL2 ? '3d' : '2d'}`)
const transform = Mat4.identity()
Mat4.fromScaling(transform, scale)
......@@ -51,7 +51,7 @@ export async function GaussianDensityTexture(ctx: RuntimeContext, webgl: Context
//
async function GaussianDensitySingleDrawBuffer(ctx: RuntimeContext, webgl: Context, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, texture?: Texture) {
async function GaussianDensityTexture2d(ctx: RuntimeContext, webgl: Context, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, texture?: Texture) {
const { smoothness } = props
const { drawCount, positions, radii, delta, expandedBox, dim } = await prepareGaussianDensityData(ctx, position, box, radius, props)
......@@ -119,14 +119,13 @@ async function GaussianDensitySingleDrawBuffer(ctx: RuntimeContext, webgl: Conte
return { texture, scale: Vec3.inverse(Vec3.zero(), delta), bbox: expandedBox, dim }
}
async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Context, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, texture?: Texture) {
async function GaussianDensityTexture3d(ctx: RuntimeContext, webgl: Context, position: PositionData, box: Box3D, radius: (index: number) => number, props: GaussianDensityProps, texture?: Texture) {
const { smoothness } = props
const { drawCount, positions, radii, delta, expandedBox, dim } = await prepareGaussianDensityData(ctx, position, box, radius, props)
const [ dx, dy, dz ] = dim
const renderObject = getGaussianDensityRenderObject(webgl, drawCount, positions, radii, expandedBox, dim, smoothness)
const renderable = createRenderable(webgl, renderObject)
const drawBuffers = Math.min(8, webgl.maxDrawBuffers)
//
......@@ -136,7 +135,6 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex
const framebuffer = createFramebuffer(webgl)
framebuffer.bind()
setDrawBuffers(gl, drawBuffers)
gl.viewport(0, 0, dx, dy)
setRenderingDefaults(gl)
......@@ -145,36 +143,14 @@ async function GaussianDensityMultiDrawBuffer(ctx: RuntimeContext, webgl: Contex
}
texture.define(dx, dy, dz)
// z-slices to be render with multi render targets
const dzMulti = Math.floor(dz / drawBuffers) * drawBuffers
// render multi target
const programMulti = renderable.getProgram('draw')
programMulti.use()
for (let i = 0; i < dzMulti; i += drawBuffers) {
ValueCell.update(uCurrentSlice, i)
for (let k = 0; k < drawBuffers; ++k) {
texture.attachFramebuffer(framebuffer, k as TextureAttachment, i + k)
}
renderable.render('draw');
}
// render single target
ValueCell.updateIfChanged(renderable.values.dDrawBuffers, 1)
renderable.update()
const programSingle = renderable.getProgram('draw')
programSingle.use()
for (let i = dzMulti; i < dz; ++i) {
const programDensity = renderable.getProgram('draw')
programDensity.use()
for (let i = 0; i < dz; ++i) {
ValueCell.update(uCurrentSlice, i)
texture.attachFramebuffer(framebuffer, 0, i)
renderable.render('draw')
}
// must detach framebuffer attachments before reading is possible
for (let k = 0; k < drawBuffers; ++k) {
texture.detachFramebuffer(framebuffer, k as TextureAttachment)
}
framebuffer.destroy() // clean up
await ctx.update({ message: 'gpu gaussian density calculation' });
......@@ -256,8 +232,6 @@ function getGaussianDensityRenderObject(webgl: Context, drawCount: number, posit
uBboxSize: ValueCell.create(extent),
uGridDim: ValueCell.create(dimensions),
uAlpha: ValueCell.create(smoothness),
dDrawBuffers: ValueCell.create(Math.min(8, webgl.maxDrawBuffers)),
}
const state: RenderableState = {
visible: true,
......@@ -279,23 +253,6 @@ function setRenderingDefaults(gl: GLRenderingContext) {
gl.enable(gl.BLEND)
}
function setDrawBuffers(gl: WebGL2RenderingContext, drawBuffers: number) {
if (drawBuffers === 1) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0,
]);
} else if (drawBuffers === 4) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3,
]);
} else if (drawBuffers === 8) {
gl.drawBuffers([
gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3,
gl.COLOR_ATTACHMENT4, gl.COLOR_ATTACHMENT5, gl.COLOR_ATTACHMENT6, gl.COLOR_ATTACHMENT7,
]);
}
}
function fieldFromTexture2d(ctx: Context, texture: Texture, dim: Vec3) {
console.time('fieldFromTexture2d')
const { gl } = ctx
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment