diff --git a/src/mol-gl/renderable/gaussian-density.ts b/src/mol-gl/renderable/gaussian-density.ts index 1fe68a5aae45fe6a59550402226b1f9f31798425..bc738d0ecfede0009fc9f58a46d8f6cb58208fe7 100644 --- a/src/mol-gl/renderable/gaussian-density.ts +++ b/src/mol-gl/renderable/gaussian-density.ts @@ -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> diff --git a/src/mol-gl/shader/gaussian-density.frag b/src/mol-gl/shader/gaussian-density.frag index 546267b47df69a4640019cd537ffad4ba96b4272..3589c7213a1237d3eeb9d5b332643b061c1d3957 100644 --- a/src/mol-gl/shader/gaussian-density.frag +++ b/src/mol-gl/shader/gaussian-density.frag @@ -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 diff --git a/src/mol-gl/shader/gaussian-density.vert b/src/mol-gl/shader/gaussian-density.vert index 217f0085a8a5d87aa2f6341e87f49bf122f54861..d4319f57930b5d4baafe9342bb5ffd3283d04ff2 100644 --- a/src/mol-gl/shader/gaussian-density.vert +++ b/src/mol-gl/shader/gaussian-density.vert @@ -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 diff --git a/src/mol-math/geometry/gaussian-density/gpu.ts b/src/mol-math/geometry/gaussian-density/gpu.ts index 6d6c8c8e5a2c8da9afc23775a528bf806dedcd19..f989d971cbfe0c36bc7496ab861b1effb187c7f7 100644 --- a/src/mol-math/geometry/gaussian-density/gpu.ts +++ b/src/mol-math/geometry/gaussian-density/gpu.ts @@ -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