Loading app/src/components/viewports/ChromatinViewport.tsx +23 −9 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import { sasa } from "../../modules/sasa"; import { ChromatinViewportConfiguration, ConfigurationAction, ConfigurationState, getDefaultViewportSelectionOptions, ChromatinViewportToolType } from "../../modules/storage/models/viewports"; import { useDeepCompareEffect, useMouseHovered, usePrevious } from "react-use"; import { ChromatinIntersection, ContinuousTube, Sphere, CullPlane } from "../../modules/graphics"; import { vec3, vec4 } from "gl-matrix"; import { vec2, vec3, vec4 } from "gl-matrix"; import { BEDAnnotations, BEDAnnotation, BinPositionsData, Data, DataAction, DataState, isoDataID, Positions3D, Sparse1DNumericData, Sparse1DTextData } from "../../modules/storage/models/data"; import { SelectionAction, SelectionActionKind, SelectionState } from "../../modules/storage/models/selections"; import { useConfiguration } from "../hooks"; Loading Loading @@ -605,16 +605,30 @@ export function ChromatinViewport(props: { let i = 0; for (const [position, marker, color] of labelsWorldSpace) { const viewSpacePosition = vec4.transformMat4(vec4.create(), vec4.fromValues(position[0], position[1], position[2], 1.0), mvm); const screenSpacePosition = vec4.transformMat4(vec4.create(), viewSpacePosition, pm); const w = screenSpacePosition[3]; const finalPos = vec3.fromValues(screenSpacePosition[0] / w, screenSpacePosition[1] / w, screenSpacePosition[2] / w); const clipSpacePosition = vec4.transformMat4(vec4.create(), viewSpacePosition, pm); const w = clipSpacePosition[3]; const finalPos = vec3.fromValues(clipSpacePosition[0] / w, clipSpacePosition[1] / w, clipSpacePosition[2] / w); finalPos[0] = 0.5 * finalPos[0] + 0.5; finalPos[1] = 0.5 * finalPos[1] + 0.5; const text = (typeof marker === "string") ? marker : "error"; const newLbl = makeLabel(text, i, 0.5 * finalPos[0] + 0.5, 0.5 * finalPos[1] + 0.5, color); const newLbl = makeLabel(text, i, finalPos[0], finalPos[1], color); if (newLbl != null) { if (viewport?.depthArrayBuffer) { const screenSpacePosition = vec2.fromValues(Math.round(finalPos[0] * viewport.width), Math.round(finalPos[1] * viewport.height)); const floats = new Float32Array(viewport.depthArrayBuffer); const rowSize = viewport.width + (64 - viewport.width % 64); const depth = floats[screenSpacePosition[1] * rowSize + screenSpacePosition[0]]; if (depth < finalPos[2]) { labels.push(newLbl); i += 1; } } } } } //#endregion Labels Loading libs/graphics/src/viewports/3d_viewport.ts +30 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ export class Viewport3D { protected outputTexture: GPUTexture | null = null; protected depthTexture: GPUTexture | null = null; public depthArrayBuffer: ArrayBuffer | null = null; protected gBuffer: { colorsOpaque: GPUTexture, colorsTransparent: GPUTexture, Loading Loading @@ -315,7 +317,7 @@ export class Viewport3D { size, sampleCount, format: "depth32float", usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC }); this.outputTexture = this.graphicsLibrary.device.createTexture({ Loading Loading @@ -406,6 +408,11 @@ export class Viewport3D { // console.log('render ', this._canvas.width); const depthBuffer = this.graphicsLibrary.device.createBuffer({ size: (this.width + (64 - (this.width % 64))) * this.height * 4, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, }); const textureView = this._context.getCurrentTexture().createView(); if (this._camera == null || this.scene == null) { Loading Loading @@ -763,6 +770,12 @@ export class Viewport3D { // commandEncoder.resolveQuerySet(this.timestampsQuerySet, 0, 3, this.timestampsBuffer, 0); // commandEncoder.copyBufferToBuffer(this.timestampsBuffer, 0, this.timestampsResolvedBuffer, 0, 4 * 8); commandEncoder.copyTextureToBuffer( { texture: this.depthTexture, aspect: 'depth-only' }, { buffer: depthBuffer, rowsPerImage: this.height, bytesPerRow: (this.width + (64 - (this.width % 64))) * 4 }, { width: this.width, height: this.height } ); const commandBuffer = commandEncoder.finish(); device.queue.submit([commandBuffer]); Loading @@ -784,6 +797,17 @@ export class Viewport3D { // console.log((combined2 - combined) / 1000000.0, (combined3 - combined2) / 1000000.0); this.dirty = false; //#region Download Depth Buffer const shouldHaveSize = (this.width + (64 - (this.width % 64))) * this.height * 4; if (depthBuffer) { await depthBuffer.mapAsync(GPUMapMode.READ); const depthArrayBuffer = depthBuffer.getMappedRange(0, shouldHaveSize); this.depthArrayBuffer = depthArrayBuffer.slice(0); depthBuffer.unmap(); } //#endregion Download Depth Buffer } public getIDBuffer(): GPUTexture | null { Loading Loading
app/src/components/viewports/ChromatinViewport.tsx +23 −9 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import { sasa } from "../../modules/sasa"; import { ChromatinViewportConfiguration, ConfigurationAction, ConfigurationState, getDefaultViewportSelectionOptions, ChromatinViewportToolType } from "../../modules/storage/models/viewports"; import { useDeepCompareEffect, useMouseHovered, usePrevious } from "react-use"; import { ChromatinIntersection, ContinuousTube, Sphere, CullPlane } from "../../modules/graphics"; import { vec3, vec4 } from "gl-matrix"; import { vec2, vec3, vec4 } from "gl-matrix"; import { BEDAnnotations, BEDAnnotation, BinPositionsData, Data, DataAction, DataState, isoDataID, Positions3D, Sparse1DNumericData, Sparse1DTextData } from "../../modules/storage/models/data"; import { SelectionAction, SelectionActionKind, SelectionState } from "../../modules/storage/models/selections"; import { useConfiguration } from "../hooks"; Loading Loading @@ -605,16 +605,30 @@ export function ChromatinViewport(props: { let i = 0; for (const [position, marker, color] of labelsWorldSpace) { const viewSpacePosition = vec4.transformMat4(vec4.create(), vec4.fromValues(position[0], position[1], position[2], 1.0), mvm); const screenSpacePosition = vec4.transformMat4(vec4.create(), viewSpacePosition, pm); const w = screenSpacePosition[3]; const finalPos = vec3.fromValues(screenSpacePosition[0] / w, screenSpacePosition[1] / w, screenSpacePosition[2] / w); const clipSpacePosition = vec4.transformMat4(vec4.create(), viewSpacePosition, pm); const w = clipSpacePosition[3]; const finalPos = vec3.fromValues(clipSpacePosition[0] / w, clipSpacePosition[1] / w, clipSpacePosition[2] / w); finalPos[0] = 0.5 * finalPos[0] + 0.5; finalPos[1] = 0.5 * finalPos[1] + 0.5; const text = (typeof marker === "string") ? marker : "error"; const newLbl = makeLabel(text, i, 0.5 * finalPos[0] + 0.5, 0.5 * finalPos[1] + 0.5, color); const newLbl = makeLabel(text, i, finalPos[0], finalPos[1], color); if (newLbl != null) { if (viewport?.depthArrayBuffer) { const screenSpacePosition = vec2.fromValues(Math.round(finalPos[0] * viewport.width), Math.round(finalPos[1] * viewport.height)); const floats = new Float32Array(viewport.depthArrayBuffer); const rowSize = viewport.width + (64 - viewport.width % 64); const depth = floats[screenSpacePosition[1] * rowSize + screenSpacePosition[0]]; if (depth < finalPos[2]) { labels.push(newLbl); i += 1; } } } } } //#endregion Labels Loading
libs/graphics/src/viewports/3d_viewport.ts +30 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ export class Viewport3D { protected outputTexture: GPUTexture | null = null; protected depthTexture: GPUTexture | null = null; public depthArrayBuffer: ArrayBuffer | null = null; protected gBuffer: { colorsOpaque: GPUTexture, colorsTransparent: GPUTexture, Loading Loading @@ -315,7 +317,7 @@ export class Viewport3D { size, sampleCount, format: "depth32float", usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC }); this.outputTexture = this.graphicsLibrary.device.createTexture({ Loading Loading @@ -406,6 +408,11 @@ export class Viewport3D { // console.log('render ', this._canvas.width); const depthBuffer = this.graphicsLibrary.device.createBuffer({ size: (this.width + (64 - (this.width % 64))) * this.height * 4, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, }); const textureView = this._context.getCurrentTexture().createView(); if (this._camera == null || this.scene == null) { Loading Loading @@ -763,6 +770,12 @@ export class Viewport3D { // commandEncoder.resolveQuerySet(this.timestampsQuerySet, 0, 3, this.timestampsBuffer, 0); // commandEncoder.copyBufferToBuffer(this.timestampsBuffer, 0, this.timestampsResolvedBuffer, 0, 4 * 8); commandEncoder.copyTextureToBuffer( { texture: this.depthTexture, aspect: 'depth-only' }, { buffer: depthBuffer, rowsPerImage: this.height, bytesPerRow: (this.width + (64 - (this.width % 64))) * 4 }, { width: this.width, height: this.height } ); const commandBuffer = commandEncoder.finish(); device.queue.submit([commandBuffer]); Loading @@ -784,6 +797,17 @@ export class Viewport3D { // console.log((combined2 - combined) / 1000000.0, (combined3 - combined2) / 1000000.0); this.dirty = false; //#region Download Depth Buffer const shouldHaveSize = (this.width + (64 - (this.width % 64))) * this.height * 4; if (depthBuffer) { await depthBuffer.mapAsync(GPUMapMode.READ); const depthArrayBuffer = depthBuffer.getMappedRange(0, shouldHaveSize); this.depthArrayBuffer = depthArrayBuffer.slice(0); depthBuffer.unmap(); } //#endregion Download Depth Buffer } public getIDBuffer(): GPUTexture | null { Loading