|
@@ -1,5 +1,5 @@
|
|
/**
|
|
/**
|
|
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
|
|
|
+ * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
*
|
|
*
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
*/
|
|
*/
|
|
@@ -48,6 +48,8 @@ interface Renderer {
|
|
|
|
|
|
renderPick: (group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, depthTexture: Texture | null) => void
|
|
renderPick: (group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, depthTexture: Texture | null) => void
|
|
renderDepth: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderDepth: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
|
|
+ renderMarkingDepth: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
|
|
+ renderMarkingMask: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderBlended: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderBlended: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderBlendedOpaque: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderBlendedOpaque: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderBlendedTransparent: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
renderBlendedTransparent: (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => void
|
|
@@ -76,6 +78,8 @@ export const RendererParams = {
|
|
|
|
|
|
highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)),
|
|
highlightColor: PD.Color(Color.fromNormalizedRgb(1.0, 0.4, 0.6)),
|
|
selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)),
|
|
selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)),
|
|
|
|
+ highlightStrength: PD.Numeric(0.7, { min: 0.0, max: 1.0, step: 0.1 }),
|
|
|
|
+ selectStrength: PD.Numeric(0.7, { min: 0.0, max: 1.0, step: 0.1 }),
|
|
|
|
|
|
xrayEdgeFalloff: PD.Numeric(1, { min: 0.0, max: 3.0, step: 0.1 }),
|
|
xrayEdgeFalloff: PD.Numeric(1, { min: 0.0, max: 3.0, step: 0.1 }),
|
|
|
|
|
|
@@ -242,6 +246,7 @@ namespace Renderer {
|
|
uFogColor: ValueCell.create(bgColor),
|
|
uFogColor: ValueCell.create(bgColor),
|
|
|
|
|
|
uRenderWboit: ValueCell.create(false),
|
|
uRenderWboit: ValueCell.create(false),
|
|
|
|
+ uMarkingDepthTest: ValueCell.create(false),
|
|
|
|
|
|
uTransparentBackground: ValueCell.create(false),
|
|
uTransparentBackground: ValueCell.create(false),
|
|
|
|
|
|
@@ -267,6 +272,8 @@ namespace Renderer {
|
|
|
|
|
|
uHighlightColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.highlightColor)),
|
|
uHighlightColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.highlightColor)),
|
|
uSelectColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.selectColor)),
|
|
uSelectColor: ValueCell.create(Color.toVec3Normalized(Vec3(), p.selectColor)),
|
|
|
|
+ uHighlightStrength: ValueCell.create(p.highlightStrength),
|
|
|
|
+ uSelectStrength: ValueCell.create(p.selectStrength),
|
|
|
|
|
|
uXrayEdgeFalloff: ValueCell.create(p.xrayEdgeFalloff),
|
|
uXrayEdgeFalloff: ValueCell.create(p.xrayEdgeFalloff),
|
|
};
|
|
};
|
|
@@ -375,7 +382,7 @@ namespace Renderer {
|
|
ValueCell.updateIfChanged(globalUniforms.uTransparentBackground, transparentBackground);
|
|
ValueCell.updateIfChanged(globalUniforms.uTransparentBackground, transparentBackground);
|
|
};
|
|
};
|
|
|
|
|
|
- const updateInternal = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null, renderWboit: boolean) => {
|
|
|
|
|
|
+ const updateInternal = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null, renderWboit: boolean, markingDepthTest: boolean) => {
|
|
arrayMapUpsert(sharedTexturesList, 'tDepth', depthTexture || nullDepthTexture);
|
|
arrayMapUpsert(sharedTexturesList, 'tDepth', depthTexture || nullDepthTexture);
|
|
|
|
|
|
ValueCell.update(globalUniforms.uModel, group.view);
|
|
ValueCell.update(globalUniforms.uModel, group.view);
|
|
@@ -385,6 +392,7 @@ namespace Renderer {
|
|
ValueCell.update(globalUniforms.uInvModelViewProjection, Mat4.invert(invModelViewProjection, modelViewProjection));
|
|
ValueCell.update(globalUniforms.uInvModelViewProjection, Mat4.invert(invModelViewProjection, modelViewProjection));
|
|
|
|
|
|
ValueCell.updateIfChanged(globalUniforms.uRenderWboit, renderWboit);
|
|
ValueCell.updateIfChanged(globalUniforms.uRenderWboit, renderWboit);
|
|
|
|
+ ValueCell.updateIfChanged(globalUniforms.uMarkingDepthTest, markingDepthTest);
|
|
|
|
|
|
state.enable(gl.SCISSOR_TEST);
|
|
state.enable(gl.SCISSOR_TEST);
|
|
state.colorMask(true, true, true, true);
|
|
state.colorMask(true, true, true, true);
|
|
@@ -402,7 +410,7 @@ namespace Renderer {
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.depthMask(true);
|
|
state.depthMask(true);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
@@ -417,7 +425,7 @@ namespace Renderer {
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.depthMask(true);
|
|
state.depthMask(true);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
@@ -425,6 +433,40 @@ namespace Renderer {
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ const renderMarkingDepth = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
|
|
+ state.disable(gl.BLEND);
|
|
|
|
+ state.enable(gl.DEPTH_TEST);
|
|
|
|
+ state.depthMask(true);
|
|
|
|
+
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
+
|
|
|
|
+ const { renderables } = group;
|
|
|
|
+ for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
|
|
+ const r = renderables[i];
|
|
|
|
+
|
|
|
|
+ if (r.values.markerAverage.ref.value !== 1) {
|
|
|
|
+ renderObject(renderables[i], 'markingDepth');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const renderMarkingMask = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
|
|
+ state.disable(gl.BLEND);
|
|
|
|
+ state.enable(gl.DEPTH_TEST);
|
|
|
|
+ state.depthMask(true);
|
|
|
|
+
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, !!depthTexture);
|
|
|
|
+
|
|
|
|
+ const { renderables } = group;
|
|
|
|
+ for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
|
|
+ const r = renderables[i];
|
|
|
|
+
|
|
|
|
+ if (r.values.markerAverage.ref.value > 0) {
|
|
|
|
+ renderObject(renderables[i], 'markingMask');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
const renderBlended = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
const renderBlended = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
renderBlendedOpaque(group, camera, depthTexture);
|
|
renderBlendedOpaque(group, camera, depthTexture);
|
|
renderBlendedTransparent(group, camera, depthTexture);
|
|
renderBlendedTransparent(group, camera, depthTexture);
|
|
@@ -435,7 +477,7 @@ namespace Renderer {
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.depthMask(true);
|
|
state.depthMask(true);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
@@ -449,7 +491,7 @@ namespace Renderer {
|
|
const renderBlendedTransparent = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
const renderBlendedTransparent = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.enable(gl.DEPTH_TEST);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
|
|
|
|
@@ -481,13 +523,13 @@ namespace Renderer {
|
|
state.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
state.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
state.enable(gl.BLEND);
|
|
state.enable(gl.BLEND);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
const r = renderables[i];
|
|
const r = renderables[i];
|
|
|
|
|
|
- // TODO: simplify, handle on renderable.state???
|
|
|
|
|
|
+ // TODO: simplify, handle in renderable.state???
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
if (alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && !r.values.dXrayShaded?.ref.value) {
|
|
if (alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && !r.values.dXrayShaded?.ref.value) {
|
|
@@ -500,13 +542,13 @@ namespace Renderer {
|
|
state.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
state.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
state.enable(gl.BLEND);
|
|
state.enable(gl.BLEND);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
const r = renderables[i];
|
|
const r = renderables[i];
|
|
|
|
|
|
- // TODO: simplify, handle on renderable.state???
|
|
|
|
|
|
+ // TODO: simplify, handle in renderable.state???
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dXrayShaded?.ref.value) {
|
|
if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dXrayShaded?.ref.value) {
|
|
@@ -520,13 +562,13 @@ namespace Renderer {
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.enable(gl.DEPTH_TEST);
|
|
state.depthMask(true);
|
|
state.depthMask(true);
|
|
|
|
|
|
- updateInternal(group, camera, depthTexture, false);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, false, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
const r = renderables[i];
|
|
const r = renderables[i];
|
|
|
|
|
|
- // TODO: simplify, handle on renderable.state???
|
|
|
|
|
|
+ // TODO: simplify, handle in renderable.state???
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
if (alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dRenderMode?.ref.value !== 'volume' && !r.values.dPointFilledCircle?.ref.value && !r.values.dXrayShaded?.ref.value) {
|
|
if (alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dRenderMode?.ref.value !== 'volume' && !r.values.dPointFilledCircle?.ref.value && !r.values.dXrayShaded?.ref.value) {
|
|
@@ -536,13 +578,13 @@ namespace Renderer {
|
|
};
|
|
};
|
|
|
|
|
|
const renderWboitTransparent = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
const renderWboitTransparent = (group: Scene.Group, camera: ICamera, depthTexture: Texture | null) => {
|
|
- updateInternal(group, camera, depthTexture, true);
|
|
|
|
|
|
+ updateInternal(group, camera, depthTexture, true, false);
|
|
|
|
|
|
const { renderables } = group;
|
|
const { renderables } = group;
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
for (let i = 0, il = renderables.length; i < il; ++i) {
|
|
const r = renderables[i];
|
|
const r = renderables[i];
|
|
|
|
|
|
- // TODO: simplify, handle on renderable.state???
|
|
|
|
|
|
+ // TODO: simplify, handle in renderable.state???
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
// uAlpha is updated in "render" so we need to recompute it here
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
|
|
if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dRenderMode?.ref.value === 'volume' || r.values.dPointFilledCircle?.ref.value || !!r.values.uBackgroundColor || r.values.dXrayShaded?.ref.value) {
|
|
if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dRenderMode?.ref.value === 'volume' || r.values.dPointFilledCircle?.ref.value || !!r.values.uBackgroundColor || r.values.dXrayShaded?.ref.value) {
|
|
@@ -577,6 +619,8 @@ namespace Renderer {
|
|
|
|
|
|
renderPick,
|
|
renderPick,
|
|
renderDepth,
|
|
renderDepth,
|
|
|
|
+ renderMarkingDepth,
|
|
|
|
+ renderMarkingMask,
|
|
renderBlended,
|
|
renderBlended,
|
|
renderBlendedOpaque,
|
|
renderBlendedOpaque,
|
|
renderBlendedTransparent,
|
|
renderBlendedTransparent,
|
|
@@ -618,6 +662,14 @@ namespace Renderer {
|
|
p.selectColor = props.selectColor;
|
|
p.selectColor = props.selectColor;
|
|
ValueCell.update(globalUniforms.uSelectColor, Color.toVec3Normalized(globalUniforms.uSelectColor.ref.value, p.selectColor));
|
|
ValueCell.update(globalUniforms.uSelectColor, Color.toVec3Normalized(globalUniforms.uSelectColor.ref.value, p.selectColor));
|
|
}
|
|
}
|
|
|
|
+ if (props.highlightStrength !== undefined && props.highlightStrength !== p.highlightStrength) {
|
|
|
|
+ p.highlightStrength = props.highlightStrength;
|
|
|
|
+ ValueCell.update(globalUniforms.uHighlightStrength, p.highlightStrength);
|
|
|
|
+ }
|
|
|
|
+ if (props.selectStrength !== undefined && props.selectStrength !== p.selectStrength) {
|
|
|
|
+ p.selectStrength = props.selectStrength;
|
|
|
|
+ ValueCell.update(globalUniforms.uSelectStrength, p.selectStrength);
|
|
|
|
+ }
|
|
|
|
|
|
if (props.xrayEdgeFalloff !== undefined && props.xrayEdgeFalloff !== p.xrayEdgeFalloff) {
|
|
if (props.xrayEdgeFalloff !== undefined && props.xrayEdgeFalloff !== p.xrayEdgeFalloff) {
|
|
p.xrayEdgeFalloff = props.xrayEdgeFalloff;
|
|
p.xrayEdgeFalloff = props.xrayEdgeFalloff;
|