diff --git a/src/mol-geo/geometry/color-data.ts b/src/mol-geo/geometry/color-data.ts index 646e3938db1d15063b6c9ecb373065ce559905a5..85e3039b78f62c7d2f400feef186d2c37ad9cd15 100644 --- a/src/mol-geo/geometry/color-data.ts +++ b/src/mol-geo/geometry/color-data.ts @@ -13,18 +13,21 @@ import { LocationIterator } from '../util/location-iterator'; import { NullLocation } from '../../mol-model/location'; import { LocationColor, ColorTheme } from '../../mol-theme/color'; import { Geometry } from './geometry'; +import { createNullTexture, Texture } from '../../mol-gl/webgl/texture'; -export type ColorType = 'uniform' | 'instance' | 'group' | 'groupInstance' | 'vertex' | 'vertexInstance' | 'volume' +export type ColorType = 'uniform' | 'instance' | 'group' | 'groupInstance' | 'vertex' | 'vertexInstance' | 'volume' | 'volumeInstance' export type ColorData = { uColor: ValueCell<Vec3>, tColor: ValueCell<TextureImage<Uint8Array>>, + tColorGrid: ValueCell<Texture>, tPalette: ValueCell<TextureImage<Uint8Array>>, uColorTexDim: ValueCell<Vec2>, uColorGridDim: ValueCell<Vec3>, uColorGridTransform: ValueCell<Vec4>, dColorType: ValueCell<string>, dUsePalette: ValueCell<boolean>, + dColorGridType: ValueCell<string>, } export function createColors(locationIt: LocationIterator, positionIt: LocationIterator, colorTheme: ColorTheme<any>, colorData?: ColorData): ColorData { @@ -47,6 +50,7 @@ function _createColors(locationIt: LocationIterator, positionIt: LocationIterato case 'vertex': return createVertexColor(positionIt, colorTheme.color, colorData); case 'vertexInstance': return createVertexInstanceColor(positionIt, colorTheme.color, colorData); case 'volume': return createGridColor((colorTheme as any).grid, 'volume', colorData); + case 'volumeInstance': return createGridColor((colorTheme as any).grid, 'volumeInstance', colorData); } } @@ -92,12 +96,14 @@ export function createValueColor(value: Color, colorData?: ColorData): ColorData return { uColor: ValueCell.create(Color.toVec3Normalized(Vec3(), value)), tColor: ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), + tColorGrid: ValueCell.create(createNullTexture()), tPalette: ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: ValueCell.create(Vec2.create(1, 1)), uColorGridDim: ValueCell.create(Vec3.create(1, 1, 1)), uColorGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)), dColorType: ValueCell.create('uniform'), dUsePalette: ValueCell.create(false), + dColorGridType: ValueCell.create('2d'), }; } } @@ -119,12 +125,14 @@ export function createTextureColor(colors: TextureImage<Uint8Array>, type: Color return { uColor: ValueCell.create(Vec3()), tColor: ValueCell.create(colors), + tColorGrid: ValueCell.create(createNullTexture()), tPalette: ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: ValueCell.create(Vec2.create(colors.width, colors.height)), uColorGridDim: ValueCell.create(Vec3.create(1, 1, 1)), uColorGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)), dColorType: ValueCell.create(type), dUsePalette: ValueCell.create(false), + dColorGridType: ValueCell.create('2d'), }; } } @@ -202,34 +210,35 @@ function createVertexInstanceColor(locationIt: LocationIterator, color: Location // interface ColorVolume { - colors: TextureImage<Uint8Array> // | Texture + colors: Texture dimension: Vec3 transform: Vec4 } export function createGridColor(grid: ColorVolume, type: ColorType, colorData?: ColorData): ColorData { const { colors, dimension, transform } = grid; - // const width = 'array' in colors ? colors.width : colors.getWidth(); - // const height = 'array' in colors ? colors.height : colors.getHeight(); - const width = colors.width; - const height = colors.height; + const width = colors.getWidth(); + const height = colors.getHeight(); if (colorData) { - ValueCell.update(colorData.tColor, colors); + ValueCell.update(colorData.tColorGrid, colors); ValueCell.update(colorData.uColorTexDim, Vec2.create(width, height)); ValueCell.update(colorData.uColorGridDim, Vec3.clone(dimension)); ValueCell.update(colorData.uColorGridTransform, Vec4.clone(transform)); ValueCell.updateIfChanged(colorData.dColorType, type); + ValueCell.updateIfChanged(colorData.dColorGridType, colors.getDepth() ? '3d' : '2d'); return colorData; } else { return { uColor: ValueCell.create(Vec3()), - tColor: ValueCell.create(colors), + tColor: ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), + tColorGrid: ValueCell.create(colors), tPalette: ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }), uColorTexDim: ValueCell.create(Vec2.create(width, height)), uColorGridDim: ValueCell.create(Vec3.clone(dimension)), uColorGridTransform: ValueCell.create(Vec4.clone(transform)), dColorType: ValueCell.create(type), dUsePalette: ValueCell.create(false), + dColorGridType: ValueCell.create('2d'), }; } } diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 1811555d6af000e0a1ac0e227857dd320430e5ff..88617f619ca647facbadfdb5f7844aabdfcc6ea9 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -188,8 +188,10 @@ export const ColorSchema = { uColorGridTransform: UniformSpec('v4'), tColor: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'), tPalette: TextureSpec('image-uint8', 'rgb', 'ubyte', 'nearest'), - dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'groupInstance', 'vertex', 'vertexInstance']), + tColorGrid: TextureSpec('texture', 'rgb', 'ubyte', 'linear'), + dColorType: DefineSpec('string', ['uniform', 'attribute', 'instance', 'group', 'groupInstance', 'vertex', 'vertexInstance', 'volume', 'volumeInstance']), dUsePalette: DefineSpec('boolean'), + dColorGridType: DefineSpec('string', ['2d', '3d']), } as const; export type ColorSchema = typeof ColorSchema export type ColorValues = Values<ColorSchema> diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index e69cd1d69814b208c07956e41855d890a5a259bf..6a00aeee047fd814d999aed8eb7abbb681e3f12f 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -190,7 +190,7 @@ namespace Renderer { let transparentBackground = false; - const nullDepthTexture = createNullTexture(gl, 'image-depth'); + const nullDepthTexture = createNullTexture(gl); const sharedTexturesList: Textures = [ ['tDepth', nullDepthTexture] ]; diff --git a/src/mol-gl/shader/chunks/assign-color-varying.glsl.ts b/src/mol-gl/shader/chunks/assign-color-varying.glsl.ts index a25ab15972b6dd98f5c5f9226426b702ca69c698..4ecf5965ee9b0a1c0b2951bdbc127e36e4075e82 100644 --- a/src/mol-gl/shader/chunks/assign-color-varying.glsl.ts +++ b/src/mol-gl/shader/chunks/assign-color-varying.glsl.ts @@ -12,9 +12,12 @@ export const assign_color_varying = ` vColor.rgb = readFromTexture(tColor, VertexID, uColorTexDim).rgb; #elif defined(dColorType_vertexInstance) vColor.rgb = readFromTexture(tColor, int(aInstance) * uVertexCount + VertexID, uColorTexDim).rgb; - #elif defined(dColorType_grid) + #elif defined(dColorType_volume) vec3 gridPos = (uColorGridTransform.w * (position - uColorGridTransform.xyz)) / uColorGridDim; - vColor.rgb = texture3dFrom2dLinear(tColor, gridPos, uColorGridDim, uColorTexDim).rgb; + vColor.rgb = texture3dFrom2dLinear(tColorGrid, gridPos, uColorGridDim, uColorTexDim).rgb; + #elif defined(dColorType_volumeInstance) + vec3 gridPos = (uColorGridTransform.w * (vModelPosition - uColorGridTransform.xyz)) / uColorGridDim; + vColor.rgb = texture3dFrom2dLinear(tColorGrid, gridPos, uColorGridDim, uColorTexDim).rgb; #endif #ifdef dUsePalette diff --git a/src/mol-gl/shader/chunks/assign-position.glsl.ts b/src/mol-gl/shader/chunks/assign-position.glsl.ts index ad101abc64deaea90335cdf7dba16a8eba382825..2f971cc0493ae4129aa67b73bf2f842b8ef4fc5c 100644 --- a/src/mol-gl/shader/chunks/assign-position.glsl.ts +++ b/src/mol-gl/shader/chunks/assign-position.glsl.ts @@ -7,7 +7,8 @@ mat4 modelView = uView * model; vec3 position = aPosition; #endif vec4 position4 = vec4(position, 1.0); -vModelPosition = (model * position4).xyz; // for clipping in frag shader +// for accessing tColorGrid in vert shader and for clipping in frag shader +vModelPosition = (model * position4).xyz; vec4 mvPosition = modelView * position4; vViewPosition = mvPosition.xyz; gl_Position = uProjection * mvPosition; diff --git a/src/mol-gl/shader/chunks/color-vert-params.glsl.ts b/src/mol-gl/shader/chunks/color-vert-params.glsl.ts index 83a34c0acd63ac497b344174b68c2118a94c7ce6..b2c7cbf1497aac5dee70bbed67e6a267e68a484c 100644 --- a/src/mol-gl/shader/chunks/color-vert-params.glsl.ts +++ b/src/mol-gl/shader/chunks/color-vert-params.glsl.ts @@ -14,7 +14,8 @@ export const color_vert_params = ` uniform vec2 uColorTexDim; uniform vec3 uColorGridDim; uniform vec4 uColorGridTransform; - uniform sampler2D tColor; + // TODO handle 3D + uniform sampler2D tColorGrid; #endif #ifdef dOverpaint diff --git a/src/mol-gl/shader/chunks/common.glsl.ts b/src/mol-gl/shader/chunks/common.glsl.ts index d7292c6dc03165bc18e0709d05e17749d19ddcf4..14296e294232baa234bed597d814cc8dc23c28f1 100644 --- a/src/mol-gl/shader/chunks/common.glsl.ts +++ b/src/mol-gl/shader/chunks/common.glsl.ts @@ -13,11 +13,11 @@ export const common = ` #define dColorType_texture #endif -#if defined(dColorType_volume) +#if defined(dColorType_volume) || defined(dColorType_volumeInstance) #define dColorType_grid #endif -#if defined(dColorType_attribute) || defined(dColorType_texture) || defined(dColorType_volume) +#if defined(dColorType_attribute) || defined(dColorType_texture) || defined(dColorType_grid) #define dColorType_varying #endif diff --git a/src/mol-gl/shader/mesh.vert.ts b/src/mol-gl/shader/mesh.vert.ts index 1b7078288371696b675087c840bcf79340f52307..15cae0285ffa0ed2fb7d343e97481b48152b6044 100644 --- a/src/mol-gl/shader/mesh.vert.ts +++ b/src/mol-gl/shader/mesh.vert.ts @@ -15,7 +15,7 @@ precision highp sampler2D; #include color_vert_params #include common_clip -#if defined(dColorType_volume) +#if defined(dColorType_grid) #include texture3d_from_2d_linear #endif diff --git a/src/mol-gl/webgl/render-target.ts b/src/mol-gl/webgl/render-target.ts index 59821823b332644c82ae63781cb19f6cdc82f9b0..18d15ef9415d2d8e2c9e89e6dbbd016a8943af09 100644 --- a/src/mol-gl/webgl/render-target.ts +++ b/src/mol-gl/webgl/render-target.ts @@ -88,7 +88,7 @@ export function createRenderTarget(gl: GLRenderingContext, resources: WebGLResou export function createNullRenderTarget(gl: GLRenderingContext): RenderTarget { return { id: getNextRenderTargetId(), - texture: createNullTexture(gl, 'image-uint8'), + texture: createNullTexture(gl), framebuffer: createNullFramebuffer(), getWidth: () => 0, diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts index 042d931bd435d1e9f4046d22e74f67c300e67253..62f65ec8db38d8bc4005181d039502650aa85090 100644 --- a/src/mol-gl/webgl/texture.ts +++ b/src/mol-gl/webgl/texture.ts @@ -394,7 +394,7 @@ export function createTextures(ctx: WebGLContext, schema: RenderableSchema, valu /** * Loads an image from a url to a textures and triggers update asynchronously. - * This will not work on node.js with a polyfill for HTMLImageElement. + * This will not work on node.js without a polyfill for `HTMLImageElement`. */ export function loadImageTexture(src: string, cell: ValueCell<Texture>, texture: Texture) { const img = new Image(); @@ -407,8 +407,8 @@ export function loadImageTexture(src: string, cell: ValueCell<Texture>, texture: // -export function createNullTexture(gl: GLRenderingContext, kind: TextureKind): Texture { - const target = getTarget(gl, kind); +export function createNullTexture(gl?: GLRenderingContext): Texture { + const target = 3553; return { id: getNextTextureId(), target, @@ -424,12 +424,16 @@ export function createNullTexture(gl: GLRenderingContext, kind: TextureKind): Te define: () => {}, load: () => {}, bind: (id: TextureId) => { - gl.activeTexture(gl.TEXTURE0 + id); - gl.bindTexture(target, null); + if (gl) { + gl.activeTexture(gl.TEXTURE0 + id); + gl.bindTexture(target, null); + } }, unbind: (id: TextureId) => { - gl.activeTexture(gl.TEXTURE0 + id); - gl.bindTexture(target, null); + if (gl) { + gl.activeTexture(gl.TEXTURE0 + id); + gl.bindTexture(target, null); + } }, attachFramebuffer: () => {}, detachFramebuffer: () => {},