diff --git a/src/mol-canvas3d/passes/postprocessing.ts b/src/mol-canvas3d/passes/postprocessing.ts index 0dee8714a31d7030c64f34e081ad45471b53f586..1ec9cf0c9ddd3bee62a58903ff13e5d14df329d4 100644 --- a/src/mol-canvas3d/passes/postprocessing.ts +++ b/src/mol-canvas3d/passes/postprocessing.ts @@ -27,10 +27,10 @@ const PostprocessingSchema = { tDepth: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'), uTexSize: UniformSpec('v2'), - dUseFog: DefineSpec('boolean'), dOrthographic: DefineSpec('number'), uNear: UniformSpec('f'), uFar: UniformSpec('f'), + dFogEnable: DefineSpec('boolean'), uFogNear: UniformSpec('f'), uFogFar: UniformSpec('f'), uFogColor: UniformSpec('v3'), @@ -57,7 +57,7 @@ export const PostprocessingParams = { outlineScale: PD.Numeric(1, { min: 0, max: 10, step: 1 }), outlineThreshold: PD.Numeric(0.8, { min: 0, max: 1, step: 0.01 }), - useFog: PD.Boolean(true), + fogEnable: PD.Boolean(true), } export type PostprocessingProps = PD.Values<typeof PostprocessingParams> @@ -71,10 +71,10 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d tDepth: ValueCell.create(depthTexture), uTexSize: ValueCell.create(Vec2.create(colorTexture.width, colorTexture.height)), - dUseFog: ValueCell.create(p.useFog), dOrthographic: ValueCell.create(0), uNear: ValueCell.create(1), uFar: ValueCell.create(10000), + dFogEnable: ValueCell.create(p.fogEnable), uFogNear: ValueCell.create(10000), uFogFar: ValueCell.create(10000), uFogColor: ValueCell.create(Vec3.create(1, 1, 1)), @@ -151,9 +151,9 @@ export class PostprocessingPass { ValueCell.update(this.renderable.values.uOutlineThreshold, props.outlineThreshold) } - if (props.useFog !== undefined) { - this.props.useFog = props.useFog - ValueCell.update(this.renderable.values.dUseFog, props.useFog) + if (props.fogEnable !== undefined) { + this.props.fogEnable = props.fogEnable + ValueCell.update(this.renderable.values.dFogEnable, props.fogEnable) } this.renderable.update() diff --git a/src/mol-geo/geometry/base.ts b/src/mol-geo/geometry/base.ts index 318a67c4b9ebee8b1265f052d2ed398b3033ec90..5cce347e24baa25b2e09a91c197d8728f68d4834 100644 --- a/src/mol-geo/geometry/base.ts +++ b/src/mol-geo/geometry/base.ts @@ -9,8 +9,6 @@ import { ValueCell } from '../../mol-util'; import { BaseValues } from '../../mol-gl/renderable/schema'; import { LocationIterator } from '../util/location-iterator'; import { ParamDefinition as PD } from '../../mol-util/param-definition' -import { Color } from '../../mol-util/color'; -import { Vec3 } from '../../mol-math/linear-algebra'; import { TransformData, createIdentityTransform } from './transform-data'; import { Theme } from '../../mol-theme/theme'; import { ColorNames } from '../../mol-util/color/names'; @@ -38,10 +36,6 @@ export const VisualQualityOptions = VisualQualityNames.map(n => [n, n] as [Visua export namespace BaseGeometry { export const Params = { alpha: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }, { label: 'Opacity' }), - useFog: PD.Boolean(true), - highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)), - selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)), - quality: PD.Select<VisualQuality>('auto', VisualQualityOptions), } export type Params = typeof Params @@ -62,24 +56,13 @@ export namespace BaseGeometry { return { alpha: ValueCell.create(props.alpha), uAlpha: ValueCell.create(props.alpha), - uHighlightColor: ValueCell.create(Color.toArrayNormalized(props.highlightColor, Vec3.zero(), 0)), - uSelectColor: ValueCell.create(Color.toArrayNormalized(props.selectColor, Vec3.zero(), 0)), - dUseFog: ValueCell.create(props.useFog), - uGroupCount: ValueCell.create(counts.groupCount), drawCount: ValueCell.create(counts.drawCount), } } export function updateValues(values: BaseValues, props: PD.Values<Params>) { - if (Color.fromNormalizedArray(values.uHighlightColor.ref.value, 0) !== props.highlightColor) { - ValueCell.update(values.uHighlightColor, Color.toArrayNormalized(props.highlightColor, values.uHighlightColor.ref.value, 0)) - } - if (Color.fromNormalizedArray(values.uSelectColor.ref.value, 0) !== props.selectColor) { - ValueCell.update(values.uSelectColor, Color.toArrayNormalized(props.selectColor, values.uSelectColor.ref.value, 0)) - } ValueCell.updateIfChanged(values.alpha, props.alpha) // `uAlpha` is set in renderable.render - ValueCell.updateIfChanged(values.dUseFog, props.useFog) } export function createRenderableState(props: Partial<PD.Values<Params>> = {}): RenderableState { diff --git a/src/mol-geo/geometry/direct-volume/direct-volume.ts b/src/mol-geo/geometry/direct-volume/direct-volume.ts index b87cfee41de95789c1e5b6587e688f028f97b5bd..0cf01cbc784a99178b989597a8897b6c270ae1a7 100644 --- a/src/mol-geo/geometry/direct-volume/direct-volume.ts +++ b/src/mol-geo/geometry/direct-volume/direct-volume.ts @@ -153,7 +153,6 @@ export namespace DirectVolume { function updateValues(values: DirectVolumeValues, props: PD.Values<Params>) { ValueCell.updateIfChanged(values.uIsoValue, props.isoValueNorm) ValueCell.updateIfChanged(values.uAlpha, props.alpha) - ValueCell.updateIfChanged(values.dUseFog, props.useFog) ValueCell.updateIfChanged(values.dRenderMode, props.renderMode) const controlPoints = getControlPointsFromVec2Array(props.controlPoints) diff --git a/src/mol-geo/geometry/texture-mesh/texture-mesh.ts b/src/mol-geo/geometry/texture-mesh/texture-mesh.ts index 2853d84a9e2400a7e456dce8f0f187be717e26f4..1ca2f0a90775553fb540c627b20f2e0d97c65f7c 100644 --- a/src/mol-geo/geometry/texture-mesh/texture-mesh.ts +++ b/src/mol-geo/geometry/texture-mesh/texture-mesh.ts @@ -128,14 +128,7 @@ export namespace TextureMesh { } function updateValues(values: TextureMeshValues, props: PD.Values<Params>) { - if (Color.fromNormalizedArray(values.uHighlightColor.ref.value, 0) !== props.highlightColor) { - ValueCell.update(values.uHighlightColor, Color.toArrayNormalized(props.highlightColor, values.uHighlightColor.ref.value, 0)) - } - if (Color.fromNormalizedArray(values.uSelectColor.ref.value, 0) !== props.selectColor) { - ValueCell.update(values.uSelectColor, Color.toArrayNormalized(props.selectColor, values.uSelectColor.ref.value, 0)) - } ValueCell.updateIfChanged(values.alpha, props.alpha) // `uAlpha` is set in renderable.render - ValueCell.updateIfChanged(values.dUseFog, props.useFog) ValueCell.updateIfChanged(values.dDoubleSided, props.doubleSided) ValueCell.updateIfChanged(values.dFlatShaded, props.flatShaded) diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index c6bc26503d683882b822491ed95018d4adb76982..850386fdca5c377b8df3249977fcadcd7ccffd23 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/src/mol-gl/_spec/renderer.spec.ts @@ -65,8 +65,6 @@ function createPoints() { ...transparency, uAlpha: ValueCell.create(1.0), - uHighlightColor: ValueCell.create(Vec3.create(1.0, 0.4, 0.6)), - uSelectColor: ValueCell.create(Vec3.create(0.2, 1.0, 0.1)), uInstanceCount: ValueCell.create(1), uGroupCount: ValueCell.create(3), @@ -83,7 +81,6 @@ function createPoints() { dPointSizeAttenuation: ValueCell.create(true), dPointFilledCircle: ValueCell.create(false), uPointEdgeBleach: ValueCell.create(0.5), - dUseFog: ValueCell.create(true), } const state: RenderableState = { visible: true, diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 285020da1307e67d2b0d1217b79592b5e452adf3..6049da42422d1b121e5e7b9b2e41976065263947 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/src/mol-gl/renderable/direct-volume.ts @@ -51,9 +51,6 @@ export const DirectVolumeSchema = { elements: ElementsSpec('uint32'), uAlpha: UniformSpec('f'), - uHighlightColor: UniformSpec('v3'), - uSelectColor: UniformSpec('v3'), - dUseFog: DefineSpec('boolean'), uIsoValue: UniformSpec('f'), uBboxMin: UniformSpec('v3'), diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 92078c52f47c48b0489ae282fa0c1652e053fa4b..3c4a745944a02be691c3d91e055672087d498c33 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -148,13 +148,6 @@ export const GlobalUniformSchema = { uModelViewProjection: UniformSpec('m4'), uInvModelViewProjection: UniformSpec('m4'), - uLightIntensity: UniformSpec('f'), - uAmbientIntensity: UniformSpec('f'), - - uMetalness: UniformSpec('f'), - uRoughness: UniformSpec('f'), - uReflectivity: UniformSpec('f'), - uIsOrtho: UniformSpec('f'), uPixelRatio: UniformSpec('f'), uViewportHeight: UniformSpec('f'), @@ -169,10 +162,27 @@ export const GlobalUniformSchema = { uFogColor: UniformSpec('v3'), uTransparentBackground: UniformSpec('i'), + + // all the following could in principle be per object + // as a kind of 'material' parameter set + // would need to test performance implications + uLightIntensity: UniformSpec('f'), + uAmbientIntensity: UniformSpec('f'), + + uMetalness: UniformSpec('f'), + uRoughness: UniformSpec('f'), + uReflectivity: UniformSpec('f'), + uPickingAlphaThreshold: UniformSpec('f'), + uInteriorDarkening: UniformSpec('f'), uInteriorColorFlag: UniformSpec('i'), uInteriorColor: UniformSpec('v3'), + + uHighlightColor: UniformSpec('v3'), + uSelectColor: UniformSpec('v3'), + + uFogFlag: UniformSpec('i'), } export type GlobalUniformSchema = typeof GlobalUniformSchema export type GlobalUniformValues = Values<GlobalUniformSchema> // { [k in keyof GlobalUniformSchema]: ValueCell<any> } @@ -252,9 +262,6 @@ export const BaseSchema = { uInstanceCount: UniformSpec('i'), uGroupCount: UniformSpec('i'), - uHighlightColor: UniformSpec('v3', true), - uSelectColor: UniformSpec('v3', true), - drawCount: ValueSpec('number'), instanceCount: ValueSpec('number'), @@ -272,8 +279,6 @@ export const BaseSchema = { boundingSphere: ValueSpec('sphere'), /** bounding sphere NOT taking aTransform into account */ invariantBoundingSphere: ValueSpec('sphere'), - - dUseFog: DefineSpec('boolean'), } export type BaseSchema = typeof BaseSchema export type BaseValues = Values<BaseSchema> \ No newline at end of file diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 7bfcad1d691550c9192c02a00eb3089775418453..b2f4eef00edc942c6d6e8e522bc2e30e72e2d7a0 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -46,9 +46,12 @@ interface Renderer { export const RendererParams = { backgroundColor: PD.Color(Color(0x000000), { description: 'Background color of the 3D canvas' }), + + // the following are general 'material' parameters pickingAlphaThreshold: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }, { description: 'The minimum opacity value needed for an object to be pickable.' }), + interiorDarkening: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }), - interiorColorFlag: PD.Boolean(true), + interiorColorFlag: PD.Boolean(true, { label: 'Use Interior Color' }), interiorColor: PD.Color(Color.fromNormalizedRgb(0.3, 0.3, 0.3)), lightIntensity: PD.Numeric(0.6, { min: 0.0, max: 1.0, step: 0.01 }), @@ -57,6 +60,11 @@ export const RendererParams = { metalness: PD.Numeric(0.0, { min: 0.0, max: 1.0, step: 0.01 }), roughness: PD.Numeric(1.0, { min: 0.0, max: 1.0, step: 0.01 }), reflectivity: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }), + + highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)), + selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)), + + fogFlag: PD.Boolean(true, { label: 'Use Fog' }), } export type RendererProps = PD.Values<typeof RendererParams> @@ -67,7 +75,6 @@ namespace Renderer { const viewport = Viewport() const bgColor = Color.toVec3Normalized(Vec3(), p.backgroundColor) - const interiorColor = Color.toVec3Normalized(Vec3(), p.interiorColor) const view = Mat4() const invView = Mat4() @@ -97,13 +104,6 @@ namespace Renderer { uViewportHeight: ValueCell.create(viewport.height), uViewport: ValueCell.create(Viewport.toVec4(Vec4(), viewport)), - uLightIntensity: ValueCell.create(p.lightIntensity), - uAmbientIntensity: ValueCell.create(p.ambientIntensity), - - uMetalness: ValueCell.create(p.metalness), - uRoughness: ValueCell.create(p.roughness), - uReflectivity: ValueCell.create(p.reflectivity), - uCameraPosition: ValueCell.create(Vec3()), uNear: ValueCell.create(1), uFar: ValueCell.create(10000), @@ -112,10 +112,24 @@ namespace Renderer { uFogColor: ValueCell.create(bgColor), uTransparentBackground: ValueCell.create(0), + // the following are general 'material' uniforms + uLightIntensity: ValueCell.create(p.lightIntensity), + uAmbientIntensity: ValueCell.create(p.ambientIntensity), + + uMetalness: ValueCell.create(p.metalness), + uRoughness: ValueCell.create(p.roughness), + uReflectivity: ValueCell.create(p.reflectivity), + uPickingAlphaThreshold: ValueCell.create(p.pickingAlphaThreshold), + uInteriorDarkening: ValueCell.create(p.interiorDarkening), uInteriorColorFlag: ValueCell.create(p.interiorColorFlag ? 1 : 0), - uInteriorColor: ValueCell.create(interiorColor), + uInteriorColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.interiorColor)), + + uHighlightColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.highlightColor)), + uSelectColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.selectColor)), + + uFogFlag: ValueCell.create(p.fogFlag ? 1 : 0), } const globalUniformList = Object.entries(globalUniforms) @@ -241,10 +255,17 @@ namespace Renderer { render, setProps: (props: Partial<RendererProps>) => { + if (props.backgroundColor !== undefined && props.backgroundColor !== p.backgroundColor) { + p.backgroundColor = props.backgroundColor + Color.toVec3Normalized(bgColor, p.backgroundColor) + ValueCell.update(globalUniforms.uFogColor, Vec3.copy(globalUniforms.uFogColor.ref.value, bgColor)) + } + if (props.pickingAlphaThreshold !== undefined && props.pickingAlphaThreshold !== p.pickingAlphaThreshold) { p.pickingAlphaThreshold = props.pickingAlphaThreshold ValueCell.update(globalUniforms.uPickingAlphaThreshold, p.pickingAlphaThreshold) } + if (props.interiorDarkening !== undefined && props.interiorDarkening !== p.interiorDarkening) { p.interiorDarkening = props.interiorDarkening ValueCell.update(globalUniforms.uInteriorDarkening, p.interiorDarkening) @@ -255,14 +276,9 @@ namespace Renderer { } if (props.interiorColor !== undefined && props.interiorColor !== p.interiorColor) { p.interiorColor = props.interiorColor - Color.toVec3Normalized(interiorColor, p.interiorColor) - ValueCell.update(globalUniforms.uInteriorColor, Vec3.copy(globalUniforms.uInteriorColor.ref.value, interiorColor)) - } - if (props.backgroundColor !== undefined && props.backgroundColor !== p.backgroundColor) { - p.backgroundColor = props.backgroundColor - Color.toVec3Normalized(bgColor, p.backgroundColor) - ValueCell.update(globalUniforms.uFogColor, Vec3.copy(globalUniforms.uFogColor.ref.value, bgColor)) + ValueCell.update(globalUniforms.uInteriorColor, Color.toVec3Normalized(globalUniforms.uInteriorColor.ref.value, p.interiorColor)) } + if (props.lightIntensity !== undefined && props.lightIntensity !== p.lightIntensity) { p.lightIntensity = props.lightIntensity ValueCell.update(globalUniforms.uLightIntensity, p.lightIntensity) @@ -284,6 +300,20 @@ namespace Renderer { p.reflectivity = props.reflectivity ValueCell.update(globalUniforms.uReflectivity, p.reflectivity) } + + if (props.highlightColor !== undefined && props.highlightColor !== p.highlightColor) { + p.highlightColor = props.highlightColor + ValueCell.update(globalUniforms.uHighlightColor, Color.toVec3Normalized(globalUniforms.uHighlightColor.ref.value, p.highlightColor)) + } + if (props.selectColor !== undefined && props.selectColor !== p.selectColor) { + p.selectColor = props.selectColor + ValueCell.update(globalUniforms.uSelectColor, Color.toVec3Normalized(globalUniforms.uSelectColor.ref.value, p.selectColor)) + } + + if (props.fogFlag !== undefined && props.fogFlag !== p.fogFlag) { + p.fogFlag = props.fogFlag + ValueCell.update(globalUniforms.uFogFlag, p.fogFlag ? 1 : 0) + } }, setViewport: (x: number, y: number, width: number, height: number) => { gl.viewport(x, y, width, height) diff --git a/src/mol-gl/shader/chunks/apply-fog.glsl.ts b/src/mol-gl/shader/chunks/apply-fog.glsl.ts index 2bfd2cd87b334cb9d77d8be7e0c9ce734d723f78..fe13b547fb55cc7cb8819fec4cfc09ef510cb2f9 100644 --- a/src/mol-gl/shader/chunks/apply-fog.glsl.ts +++ b/src/mol-gl/shader/chunks/apply-fog.glsl.ts @@ -1,5 +1,5 @@ export default ` -#ifdef dUseFog +if (uFogFlag == 1) { float depth = length(vViewPosition); float fogFactor = smoothstep(uFogNear, uFogFar, depth); if (uTransparentBackground == 0) { @@ -8,5 +8,5 @@ export default ` float fogAlpha = (1.0 - fogFactor) * gl_FragColor.a; gl_FragColor.a = fogAlpha; } -#endif +} ` \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts index 1525fce4da7faa2dacb4815172f91018d811d768..3fa91f2cd9234d179be7dfe746f9f8de5636960f 100644 --- a/src/mol-gl/shader/chunks/common-frag-params.glsl.ts +++ b/src/mol-gl/shader/chunks/common-frag-params.glsl.ts @@ -15,6 +15,7 @@ varying vec3 vViewPosition; uniform vec2 uViewOffset; +uniform int uFogFlag; uniform float uFogNear; uniform float uFogFar; uniform vec3 uFogColor; diff --git a/src/mol-gl/shader/postprocessing.frag.ts b/src/mol-gl/shader/postprocessing.frag.ts index a52b07d78f984e81402b849e5077fd275e0b8d95..5ba919877321c8e2cc1d3cb37a5b3d93141cebbe 100644 --- a/src/mol-gl/shader/postprocessing.frag.ts +++ b/src/mol-gl/shader/postprocessing.frag.ts @@ -105,7 +105,7 @@ void main(void) { vec2 edgeDepth = calcEdgeDepth(coords); float edgeFlag = step(edgeDepth.x, uOutlineThreshold); color.rgb *= edgeFlag; - #ifdef dUseFog + #ifdef dFogEnable float viewDist = abs(getViewZ(edgeDepth.y)); float fogFactor = smoothstep(uFogNear, uFogFar, viewDist) * (1.0 - edgeFlag); color.rgb = mix(color.rgb, uFogColor, fogFactor); diff --git a/src/mol-plugin-ui/viewport/simple-settings.tsx b/src/mol-plugin-ui/viewport/simple-settings.tsx index 8d55f0768f2a83d8e9025f2edbd525954c6bf432..8071722c9c6c1cb55fd05f14ed665f3da25f4d2c 100644 --- a/src/mol-plugin-ui/viewport/simple-settings.tsx +++ b/src/mol-plugin-ui/viewport/simple-settings.tsx @@ -77,9 +77,11 @@ export class SimpleSettingsControl extends PluginUIComponent { PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: { postprocessing: { ...postprocessing, outlineEnable: p.value }, } }); - } else if (p.name === 'fog') {; + } else if (p.name === 'fog') { + if (!this.plugin.canvas3d) return; + const renderer = this.plugin.canvas3d.props.renderer; PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: { - cameraFog: p.value ? 50 : 1, + renderer: { ...renderer, fogFlag: p.value }, } }); } } @@ -117,7 +119,7 @@ export class SimpleSettingsControl extends PluginUIComponent { renderStyle, occlusion: this.plugin.canvas3d?.props.postprocessing.occlusionEnable, outline: this.plugin.canvas3d?.props.postprocessing.outlineEnable, - fog: this.plugin.canvas3d ? this.plugin.canvas3d.props.cameraFog > 1 : false + fog: this.plugin.canvas3d?.props.renderer.fogFlag } }