mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 13:30:24 +08:00
Merge pull request #1761 from molstar/fix-color-smoothing
This commit is contained in:
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file, following t
|
||||
Note that since we don't clearly distinguish between a public and private interfaces there will be changes in non-major versions that are potentially breaking. If we make breaking changes to less used interfaces we will highlight it in here.
|
||||
|
||||
## [Unreleased]
|
||||
- Color smoothing fixes (#1747)
|
||||
- Use correct instance for non instance-type
|
||||
- Never transform for non instance-type
|
||||
- Add extra radius to gaussian surface boundingsphere
|
||||
|
||||
## [v5.6.1] - 2026-01-23
|
||||
- Disable occlusion culling in `ImagePass` (#1758)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2021-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2021-2026 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -29,8 +29,14 @@ interface ColorSmoothingInput {
|
||||
itemSize: 4 | 3 | 1
|
||||
}
|
||||
|
||||
export function calcMeshColorSmoothing(input: ColorSmoothingInput, resolution: number, stride: number, webgl?: WebGLContext, texture?: Texture) {
|
||||
export type ColorSmoothingOptions = {
|
||||
resolution: number,
|
||||
stride: number
|
||||
};
|
||||
|
||||
export function calcMeshColorSmoothing(input: ColorSmoothingInput, options: ColorSmoothingOptions, webgl?: WebGLContext, texture?: Texture) {
|
||||
const { colorType, vertexCount, groupCount, positionBuffer, instanceBuffer, transformBuffer, groupBuffer, itemSize } = input;
|
||||
const { resolution, stride } = options;
|
||||
|
||||
const isInstanceType = colorType.endsWith('Instance');
|
||||
const box = Box3D.fromSphere3D(Box3D(), isInstanceType ? input.boundingSphere : input.invariantBoundingSphere);
|
||||
@@ -70,7 +76,7 @@ export function calcMeshColorSmoothing(input: ColorSmoothingInput, resolution: n
|
||||
for (let i = 0; i < instanceCount; ++i) {
|
||||
// - use reordered index for access from GPU
|
||||
// - use serial index for access from CPU
|
||||
const instanceIndex = webgl ? instanceBuffer[i] : i;
|
||||
const instanceIndex = (webgl && isInstanceType) ? instanceBuffer[i] : i;
|
||||
for (let j = 0; j < vertexCount; j += stride) {
|
||||
Vec3.fromArray(v, positionBuffer, j * 3);
|
||||
if (isInstanceType) Vec3.transformMat4Offset(v, v, transformBuffer, 0, 0, i * 16);
|
||||
@@ -262,7 +268,7 @@ function isSupportedColorType(x: string): x is 'group' | 'groupInstance' {
|
||||
return x === 'group' || x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyMeshColorSmoothing(values: MeshValues, resolution: number, stride: number, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyMeshColorSmoothing(values: MeshValues, options: ColorSmoothingOptions, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedColorType(values.dColorType.ref.value)) return;
|
||||
|
||||
const smoothingData = calcMeshColorSmoothing({
|
||||
@@ -278,7 +284,7 @@ export function applyMeshColorSmoothing(values: MeshValues, resolution: number,
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
itemSize: 3
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
|
||||
if (smoothingData.kind === 'volume') {
|
||||
ValueCell.updateIfChanged(values.dColorType, smoothingData.type);
|
||||
@@ -297,7 +303,7 @@ function isSupportedOverpaintType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyMeshOverpaintSmoothing(values: MeshValues, resolution: number, stride: number, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyMeshOverpaintSmoothing(values: MeshValues, options: ColorSmoothingOptions, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedOverpaintType(values.dOverpaintType.ref.value)) return;
|
||||
|
||||
const smoothingData = calcMeshColorSmoothing({
|
||||
@@ -313,7 +319,7 @@ export function applyMeshOverpaintSmoothing(values: MeshValues, resolution: numb
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
itemSize: 4
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
if (smoothingData.kind === 'volume') {
|
||||
ValueCell.updateIfChanged(values.dOverpaintType, smoothingData.type);
|
||||
ValueCell.update(values.tOverpaintGrid, smoothingData.texture);
|
||||
@@ -331,7 +337,7 @@ function isSupportedTransparencyType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyMeshTransparencySmoothing(values: MeshValues, resolution: number, stride: number, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyMeshTransparencySmoothing(values: MeshValues, options: ColorSmoothingOptions, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedTransparencyType(values.dTransparencyType.ref.value)) return;
|
||||
|
||||
const smoothingData = calcMeshColorSmoothing({
|
||||
@@ -347,7 +353,7 @@ export function applyMeshTransparencySmoothing(values: MeshValues, resolution: n
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
itemSize: 1
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
if (smoothingData.kind === 'volume') {
|
||||
ValueCell.updateIfChanged(values.dTransparencyType, smoothingData.type);
|
||||
ValueCell.update(values.tTransparencyGrid, smoothingData.texture);
|
||||
@@ -365,7 +371,7 @@ function isSupportedEmissiveType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyMeshEmissiveSmoothing(values: MeshValues, resolution: number, stride: number, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyMeshEmissiveSmoothing(values: MeshValues, options: ColorSmoothingOptions, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedEmissiveType(values.dEmissiveType.ref.value)) return;
|
||||
|
||||
const smoothingData = calcMeshColorSmoothing({
|
||||
@@ -381,7 +387,7 @@ export function applyMeshEmissiveSmoothing(values: MeshValues, resolution: numbe
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
itemSize: 1
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
if (smoothingData.kind === 'volume') {
|
||||
ValueCell.updateIfChanged(values.dEmissiveType, smoothingData.type);
|
||||
ValueCell.update(values.tEmissiveGrid, smoothingData.texture);
|
||||
@@ -399,7 +405,7 @@ function isSupportedSubstanceType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyMeshSubstanceSmoothing(values: MeshValues, resolution: number, stride: number, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyMeshSubstanceSmoothing(values: MeshValues, options: ColorSmoothingOptions, webgl?: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedSubstanceType(values.dSubstanceType.ref.value)) return;
|
||||
|
||||
const smoothingData = calcMeshColorSmoothing({
|
||||
@@ -415,7 +421,7 @@ export function applyMeshSubstanceSmoothing(values: MeshValues, resolution: numb
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
itemSize: 4
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
if (smoothingData.kind === 'volume') {
|
||||
ValueCell.updateIfChanged(values.dSubstanceType, smoothingData.type);
|
||||
ValueCell.update(values.tSubstanceGrid, smoothingData.texture);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2021-2024 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2021-2026 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -14,7 +14,7 @@ import { ValueSpec, AttributeSpec, UniformSpec, TextureSpec, Values, DefineSpec
|
||||
import { quad_vert } from '../../../mol-gl/shader/quad.vert';
|
||||
import { normalize_frag } from '../../../mol-gl/shader/compute/color-smoothing/normalize.frag';
|
||||
import { QuadSchema, QuadValues } from '../../../mol-gl/compute/util';
|
||||
import { Vec2, Vec3, Vec4 } from '../../../mol-math/linear-algebra';
|
||||
import { Mat4, Vec2, Vec3, Vec4 } from '../../../mol-math/linear-algebra';
|
||||
import { Box3D, Sphere3D } from '../../../mol-math/geometry';
|
||||
import { accumulate_frag } from '../../../mol-gl/shader/compute/color-smoothing/accumulate.frag';
|
||||
import { accumulate_vert } from '../../../mol-gl/shader/compute/color-smoothing/accumulate.vert';
|
||||
@@ -246,18 +246,30 @@ interface ColorSmoothingInput extends AccumulateInput {
|
||||
invariantBoundingSphere: Sphere3D
|
||||
}
|
||||
|
||||
export function calcTextureMeshColorSmoothing(input: ColorSmoothingInput, resolution: number, stride: number, webgl: WebGLContext, texture?: Texture) {
|
||||
export type ColorSmoothingOptions = {
|
||||
resolution: number,
|
||||
stride: number
|
||||
};
|
||||
|
||||
export function calcTextureMeshColorSmoothing(input: ColorSmoothingInput, options: ColorSmoothingOptions, webgl: WebGLContext, texture?: Texture) {
|
||||
const { drawBuffers } = webgl.extensions;
|
||||
if (!drawBuffers) throw new Error('need WebGL draw buffers');
|
||||
|
||||
if (isTimingMode) webgl.timer.mark('calcTextureMeshColorSmoothing');
|
||||
const { gl, resources, state, extensions: { colorBufferHalfFloat, textureHalfFloat } } = webgl;
|
||||
const { resolution, stride } = options;
|
||||
|
||||
const isInstanceType = input.colorType.endsWith('Instance');
|
||||
const box = Box3D.fromSphere3D(Box3D(), isInstanceType ? input.boundingSphere : input.invariantBoundingSphere);
|
||||
const pad = 1 + resolution;
|
||||
const expandedBox = Box3D.expand(Box3D(), box, Vec3.create(pad, pad, pad));
|
||||
|
||||
if (!isInstanceType) {
|
||||
input.instanceCount = 1;
|
||||
input.instanceBuffer = new Float32Array([0]);
|
||||
input.transformBuffer = new Float32Array(Mat4.id);
|
||||
}
|
||||
|
||||
const scaleFactor = 1 / resolution;
|
||||
const scaledBox = Box3D.scale(Box3D(), expandedBox, scaleFactor);
|
||||
const gridDim = Box3D.size(Vec3(), scaledBox);
|
||||
@@ -389,7 +401,7 @@ export function calcTextureMeshColorSmoothing(input: ColorSmoothingInput, resolu
|
||||
const type = isInstanceType ? 'volumeInstance' : 'volume';
|
||||
if (isTimingMode) webgl.timer.markEnd('calcTextureMeshColorSmoothing');
|
||||
|
||||
// printTextureImage(readTexture(webgl, texture), { scale: 0.75 });
|
||||
// printTextureImage(readTexture(webgl, texture), { scale: 0.75, id: `${texture.id}` });
|
||||
|
||||
return { texture, gridDim, gridTexDim: Vec2.create(width, height), gridTransform, type };
|
||||
}
|
||||
@@ -404,10 +416,10 @@ function isSupportedColorType(x: string): x is 'group' | 'groupInstance' {
|
||||
return x === 'group' || x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyTextureMeshColorSmoothing(values: TextureMeshValues, resolution: number, stride: number, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyTextureMeshColorSmoothing(values: TextureMeshValues, options: ColorSmoothingOptions, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedColorType(values.dColorType.ref.value)) return;
|
||||
|
||||
stride *= 3; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
options = { ...options, stride: options.stride * 3 }; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
|
||||
if (!webgl.namedTextures[ColorSmoothingRgbName]) {
|
||||
webgl.namedTextures[ColorSmoothingRgbName] = webgl.resources.texture('image-uint8', 'rgb', 'ubyte', 'nearest');
|
||||
@@ -427,7 +439,7 @@ export function applyTextureMeshColorSmoothing(values: TextureMeshValues, resolu
|
||||
colorType: values.dColorType.ref.value,
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
|
||||
ValueCell.updateIfChanged(values.dColorType, smoothingData.type);
|
||||
ValueCell.update(values.tColorGrid, smoothingData.texture);
|
||||
@@ -440,10 +452,10 @@ function isSupportedOverpaintType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyTextureMeshOverpaintSmoothing(values: TextureMeshValues, resolution: number, stride: number, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyTextureMeshOverpaintSmoothing(values: TextureMeshValues, options: ColorSmoothingOptions, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedOverpaintType(values.dOverpaintType.ref.value)) return;
|
||||
|
||||
stride *= 3; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
options = { ...options, stride: options.stride * 3 }; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
|
||||
if (!webgl.namedTextures[ColorSmoothingRgbaName]) {
|
||||
webgl.namedTextures[ColorSmoothingRgbaName] = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
|
||||
@@ -463,7 +475,7 @@ export function applyTextureMeshOverpaintSmoothing(values: TextureMeshValues, re
|
||||
colorType: values.dOverpaintType.ref.value,
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
|
||||
ValueCell.updateIfChanged(values.dOverpaintType, smoothingData.type);
|
||||
ValueCell.update(values.tOverpaintGrid, smoothingData.texture);
|
||||
@@ -476,10 +488,10 @@ function isSupportedTransparencyType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyTextureMeshTransparencySmoothing(values: TextureMeshValues, resolution: number, stride: number, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyTextureMeshTransparencySmoothing(values: TextureMeshValues, options: ColorSmoothingOptions, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedTransparencyType(values.dTransparencyType.ref.value)) return;
|
||||
|
||||
stride *= 3; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
options = { ...options, stride: options.stride * 3 }; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
|
||||
if (!webgl.namedTextures[ColorSmoothingAlphaName]) {
|
||||
webgl.namedTextures[ColorSmoothingAlphaName] = webgl.resources.texture('image-uint8', 'alpha', 'ubyte', 'nearest');
|
||||
@@ -499,7 +511,7 @@ export function applyTextureMeshTransparencySmoothing(values: TextureMeshValues,
|
||||
colorType: values.dTransparencyType.ref.value,
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
|
||||
ValueCell.updateIfChanged(values.dTransparencyType, smoothingData.type);
|
||||
ValueCell.update(values.tTransparencyGrid, smoothingData.texture);
|
||||
@@ -512,10 +524,10 @@ function isSupportedEmissiveType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyTextureMeshEmissiveSmoothing(values: TextureMeshValues, resolution: number, stride: number, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyTextureMeshEmissiveSmoothing(values: TextureMeshValues, options: ColorSmoothingOptions, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedEmissiveType(values.dEmissiveType.ref.value)) return;
|
||||
|
||||
stride *= 3; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
options = { ...options, stride: options.stride * 3 }; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
|
||||
if (!webgl.namedTextures[ColorSmoothingAlphaName]) {
|
||||
webgl.namedTextures[ColorSmoothingAlphaName] = webgl.resources.texture('image-uint8', 'alpha', 'ubyte', 'nearest');
|
||||
@@ -535,7 +547,7 @@ export function applyTextureMeshEmissiveSmoothing(values: TextureMeshValues, res
|
||||
colorType: values.dEmissiveType.ref.value,
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
|
||||
ValueCell.updateIfChanged(values.dEmissiveType, smoothingData.type);
|
||||
ValueCell.update(values.tEmissiveGrid, smoothingData.texture);
|
||||
@@ -548,10 +560,10 @@ function isSupportedSubstanceType(x: string): x is 'groupInstance' {
|
||||
return x === 'groupInstance';
|
||||
}
|
||||
|
||||
export function applyTextureMeshSubstanceSmoothing(values: TextureMeshValues, resolution: number, stride: number, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
export function applyTextureMeshSubstanceSmoothing(values: TextureMeshValues, options: ColorSmoothingOptions, webgl: WebGLContext, colorTexture?: Texture) {
|
||||
if (!isSupportedSubstanceType(values.dSubstanceType.ref.value)) return;
|
||||
|
||||
stride *= 3; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
options = { ...options, stride: options.stride * 3 }; // triple because TextureMesh is never indexed (no elements buffer)
|
||||
|
||||
if (!webgl.namedTextures[ColorSmoothingRgbaName]) {
|
||||
webgl.namedTextures[ColorSmoothingRgbaName] = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
|
||||
@@ -571,7 +583,7 @@ export function applyTextureMeshSubstanceSmoothing(values: TextureMeshValues, re
|
||||
colorType: values.dSubstanceType.ref.value,
|
||||
boundingSphere: values.boundingSphere.ref.value,
|
||||
invariantBoundingSphere: values.invariantBoundingSphere.ref.value,
|
||||
}, resolution, stride, webgl, colorTexture);
|
||||
}, options, webgl, colorTexture);
|
||||
|
||||
ValueCell.updateIfChanged(values.dSubstanceType, smoothingData.type);
|
||||
ValueCell.update(values.tSubstanceGrid, smoothingData.texture);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2026 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -82,6 +82,13 @@ export function printTextureImage(textureImage: TextureImage<any>, options: Part
|
||||
} else {
|
||||
data.set(array);
|
||||
}
|
||||
} else if (itemSize === 3) {
|
||||
for (let i = 0, il = width * height; i < il; ++i) {
|
||||
data[i * 4] = array[i * 3];
|
||||
data[i * 4 + 1] = array[i * 3 + 1];
|
||||
data[i * 4 + 2] = array[i * 3 + 2];
|
||||
data[i * 4 + 3] = 255;
|
||||
}
|
||||
} else {
|
||||
console.warn(`itemSize '${itemSize}' not supported`);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2026 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -88,20 +88,20 @@ type GaussianSurfaceMeta = {
|
||||
//
|
||||
|
||||
async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
|
||||
const { smoothness } = props;
|
||||
const { smoothness, floodfill, includeParent, radiusOffset } = props;
|
||||
const { transform, field, idField, radiusFactor, resolution, maxRadius } = await computeUnitGaussianDensity(structure, unit, theme.size, props).runInContext(ctx.runtime);
|
||||
|
||||
const isoLevel = Math.exp(-smoothness) / radiusFactor;
|
||||
const params = {
|
||||
isoLevel,
|
||||
scalarField: props.floodfill !== 'off' ? Tensor.createFloodfilled(field, isoLevel, props.floodfill) : field,
|
||||
scalarField: floodfill !== 'off' ? Tensor.createFloodfilled(field, isoLevel, floodfill) : field,
|
||||
idField
|
||||
};
|
||||
const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime);
|
||||
(surface.meta.resolution as GaussianSurfaceMeta['resolution']) = resolution;
|
||||
|
||||
if (props.includeParent) {
|
||||
const iterations = Math.ceil(2 / props.resolution);
|
||||
if (includeParent) {
|
||||
const iterations = Math.ceil(2 / resolution);
|
||||
Mesh.smoothEdges(surface, { iterations, maxNewEdgeLength: Math.sqrt(2) });
|
||||
}
|
||||
|
||||
@@ -113,7 +113,8 @@ async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structu
|
||||
ValueCell.updateIfChanged(surface.varyingGroup, true);
|
||||
}
|
||||
|
||||
const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, maxRadius);
|
||||
const extraRadius = radiusOffset * (1 + Math.exp(-smoothness));
|
||||
const sphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, maxRadius + extraRadius);
|
||||
surface.setBoundingSphere(sphere);
|
||||
|
||||
return surface;
|
||||
@@ -152,7 +153,7 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss
|
||||
const { resolution, colorTexture } = geometry.meta as GaussianSurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
|
||||
if (csp) {
|
||||
applyMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
|
||||
applyMeshColorSmoothing(values, csp, webgl, colorTexture);
|
||||
(geometry.meta.colorTexture as GaussianSurfaceMeta['colorTexture']) = values.tColorGrid.ref.value;
|
||||
}
|
||||
},
|
||||
@@ -165,20 +166,20 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss
|
||||
//
|
||||
|
||||
async function createStructureGaussianSurfaceMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
|
||||
const { smoothness } = props;
|
||||
const { smoothness, floodfill, includeParent, radiusOffset } = props;
|
||||
const { transform, field, idField, radiusFactor, resolution, maxRadius } = await computeStructureGaussianDensity(structure, theme.size, props).runInContext(ctx.runtime);
|
||||
|
||||
const isoLevel = Math.exp(-smoothness) / radiusFactor;
|
||||
const params = {
|
||||
isoLevel,
|
||||
scalarField: props.floodfill !== 'off' ? Tensor.createFloodfilled(field, isoLevel, props.floodfill) : field,
|
||||
scalarField: floodfill !== 'off' ? Tensor.createFloodfilled(field, isoLevel, floodfill) : field,
|
||||
idField
|
||||
};
|
||||
const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime);
|
||||
(surface.meta.resolution as GaussianSurfaceMeta['resolution']) = resolution;
|
||||
|
||||
if (props.includeParent) {
|
||||
const iterations = Math.ceil(2 / props.resolution);
|
||||
if (includeParent) {
|
||||
const iterations = Math.ceil(2 / resolution);
|
||||
Mesh.smoothEdges(surface, { iterations, maxNewEdgeLength: Math.sqrt(2) });
|
||||
}
|
||||
|
||||
@@ -190,7 +191,8 @@ async function createStructureGaussianSurfaceMesh(ctx: VisualContext, structure:
|
||||
ValueCell.updateIfChanged(surface.varyingGroup, true);
|
||||
}
|
||||
|
||||
const sphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, maxRadius);
|
||||
const extraRadius = radiusOffset * (1 + Math.exp(-smoothness));
|
||||
const sphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, maxRadius + extraRadius);
|
||||
surface.setBoundingSphere(sphere);
|
||||
|
||||
return surface;
|
||||
@@ -229,7 +231,7 @@ export function StructureGaussianSurfaceMeshVisual(materialId: number): ComplexV
|
||||
const { resolution, colorTexture } = geometry.meta as GaussianSurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
|
||||
if (csp) {
|
||||
applyMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
|
||||
applyMeshColorSmoothing(values, csp, webgl, colorTexture);
|
||||
(geometry.meta.colorTexture as GaussianSurfaceMeta['colorTexture']) = values.tColorGrid.ref.value;
|
||||
}
|
||||
},
|
||||
@@ -268,7 +270,8 @@ function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit, struct
|
||||
const gv = extractIsosurface(webgl, densityTextureData.texture, densityTextureData.gridDim, densityTextureData.gridTexDim, densityTextureData.gridDataDim, densityTextureData.gridTexScale, densityTextureData.transform, isoLevel, false, true, axisOrder, true, buffer?.vertex, buffer?.group, buffer?.normal);
|
||||
if (isTimingMode) webgl.timer.markEnd('createGaussianSurfaceTextureMesh');
|
||||
|
||||
const boundingSphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, densityTextureData.maxRadius);
|
||||
const extraRadius = props.radiusOffset * (1 + Math.exp(-props.smoothness));
|
||||
const boundingSphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, densityTextureData.maxRadius + extraRadius);
|
||||
const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, boundingSphere, textureMesh);
|
||||
(surface.meta as GaussianSurfaceMeta).resolution = densityTextureData.resolution;
|
||||
return surface;
|
||||
@@ -314,7 +317,7 @@ export function GaussianSurfaceTextureMeshVisual(materialId: number): UnitsVisua
|
||||
const { resolution, colorTexture } = geometry.meta as GaussianSurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
|
||||
if (csp && webgl) {
|
||||
applyTextureMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
|
||||
applyTextureMeshColorSmoothing(values, csp, webgl, colorTexture);
|
||||
(geometry.meta as GaussianSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
|
||||
}
|
||||
},
|
||||
@@ -356,7 +359,8 @@ function createStructureGaussianSurfaceTextureMesh(ctx: VisualContext, structure
|
||||
const gv = extractIsosurface(webgl, densityTextureData.texture, densityTextureData.gridDim, densityTextureData.gridTexDim, densityTextureData.gridDataDim, densityTextureData.gridTexScale, densityTextureData.transform, isoLevel, false, true, axisOrder, true, buffer?.vertex, buffer?.group, buffer?.normal);
|
||||
if (isTimingMode) webgl.timer.markEnd('createStructureGaussianSurfaceTextureMesh');
|
||||
|
||||
const boundingSphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, densityTextureData.maxRadius);
|
||||
const extraRadius = props.radiusOffset * (1 + Math.exp(-props.smoothness));
|
||||
const boundingSphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, densityTextureData.maxRadius + extraRadius);
|
||||
const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, boundingSphere, textureMesh);
|
||||
(surface.meta as GaussianSurfaceMeta).resolution = densityTextureData.resolution;
|
||||
return surface;
|
||||
@@ -402,7 +406,7 @@ export function StructureGaussianSurfaceTextureMeshVisual(materialId: number): C
|
||||
const { resolution, colorTexture } = geometry.meta as GaussianSurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
|
||||
if (csp && webgl) {
|
||||
applyTextureMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
|
||||
applyTextureMeshColorSmoothing(values, csp, webgl, colorTexture);
|
||||
(geometry.meta as GaussianSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2019-2026 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -101,7 +101,7 @@ export function MolecularSurfaceMeshVisual(materialId: number): UnitsVisual<Mole
|
||||
const { resolution, colorTexture } = geometry.meta as MolecularSurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
|
||||
if (csp) {
|
||||
applyMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
|
||||
applyMeshColorSmoothing(values, csp, webgl, colorTexture);
|
||||
(geometry.meta as MolecularSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
|
||||
}
|
||||
},
|
||||
@@ -173,7 +173,7 @@ export function StructureMolecularSurfaceMeshVisual(materialId: number): Complex
|
||||
const { resolution, colorTexture } = geometry.meta as MolecularSurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
|
||||
if (csp) {
|
||||
applyMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
|
||||
applyMeshColorSmoothing(values, csp, webgl, colorTexture);
|
||||
(geometry.meta as MolecularSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2024 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2026 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -204,14 +204,14 @@ namespace Visual {
|
||||
const { resolution, overpaintTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyMeshOverpaintSmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, overpaintTexture);
|
||||
applyMeshOverpaintSmoothing(renderObject.values as any, csp, webgl, overpaintTexture);
|
||||
(geometry.meta as SurfaceMeta).overpaintTexture = renderObject.values.tOverpaintGrid.ref.value;
|
||||
}
|
||||
} else if (webgl && geometry.kind === 'texture-mesh') {
|
||||
const { resolution, overpaintTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyTextureMeshOverpaintSmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, overpaintTexture);
|
||||
applyTextureMeshOverpaintSmoothing(renderObject.values as any, csp, webgl, overpaintTexture);
|
||||
(geometry.meta as SurfaceMeta).overpaintTexture = renderObject.values.tOverpaintGrid.ref.value;
|
||||
}
|
||||
}
|
||||
@@ -258,14 +258,14 @@ namespace Visual {
|
||||
const { resolution, transparencyTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyMeshTransparencySmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, transparencyTexture);
|
||||
applyMeshTransparencySmoothing(renderObject.values as any, csp, webgl, transparencyTexture);
|
||||
(geometry.meta as SurfaceMeta).transparencyTexture = renderObject.values.tTransparencyGrid.ref.value;
|
||||
}
|
||||
} else if (webgl && geometry.kind === 'texture-mesh') {
|
||||
const { resolution, transparencyTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyTextureMeshTransparencySmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, transparencyTexture);
|
||||
applyTextureMeshTransparencySmoothing(renderObject.values as any, csp, webgl, transparencyTexture);
|
||||
(geometry.meta as SurfaceMeta).transparencyTexture = renderObject.values.tTransparencyGrid.ref.value;
|
||||
}
|
||||
}
|
||||
@@ -311,14 +311,14 @@ namespace Visual {
|
||||
const { resolution, emissiveTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyMeshEmissiveSmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, emissiveTexture);
|
||||
applyMeshEmissiveSmoothing(renderObject.values as any, csp, webgl, emissiveTexture);
|
||||
(geometry.meta as SurfaceMeta).emissiveTexture = renderObject.values.tEmissiveGrid.ref.value;
|
||||
}
|
||||
} else if (webgl && geometry.kind === 'texture-mesh') {
|
||||
const { resolution, emissiveTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyTextureMeshEmissiveSmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, emissiveTexture);
|
||||
applyTextureMeshEmissiveSmoothing(renderObject.values as any, csp, webgl, emissiveTexture);
|
||||
(geometry.meta as SurfaceMeta).emissiveTexture = renderObject.values.tEmissiveGrid.ref.value;
|
||||
}
|
||||
}
|
||||
@@ -365,14 +365,14 @@ namespace Visual {
|
||||
const { resolution, substanceTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyMeshSubstanceSmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, substanceTexture);
|
||||
applyMeshSubstanceSmoothing(renderObject.values as any, csp, webgl, substanceTexture);
|
||||
(geometry.meta as SurfaceMeta).substanceTexture = renderObject.values.tSubstanceGrid.ref.value;
|
||||
}
|
||||
} else if (webgl && geometry.kind === 'texture-mesh') {
|
||||
const { resolution, substanceTexture } = geometry.meta as SurfaceMeta;
|
||||
const csp = getColorSmoothingProps(props.smoothColors, true, resolution);
|
||||
if (csp) {
|
||||
applyTextureMeshSubstanceSmoothing(renderObject.values as any, csp.resolution, csp.stride, webgl, substanceTexture);
|
||||
applyTextureMeshSubstanceSmoothing(renderObject.values as any, csp, webgl, substanceTexture);
|
||||
(geometry.meta as SurfaceMeta).substanceTexture = renderObject.values.tSubstanceGrid.ref.value;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user