Add existing to tracked
This commit is contained in:
+381
@@ -0,0 +1,381 @@
|
||||
import Color from "../Core/Color.js";
|
||||
import defined from "../Core/defined.js";
|
||||
import destroyObject from "../Core/destroyObject.js";
|
||||
import PixelFormat from "../Core/PixelFormat.js";
|
||||
import ClearCommand from "../Renderer/ClearCommand.js";
|
||||
import FramebufferManager from "../Renderer/FramebufferManager.js";
|
||||
import PixelDatatype from "../Renderer/PixelDatatype.js";
|
||||
import Renderbuffer from "../Renderer/Renderbuffer.js";
|
||||
import RenderbufferFormat from "../Renderer/RenderbufferFormat.js";
|
||||
import RenderState from "../Renderer/RenderState.js";
|
||||
import ShaderSource from "../Renderer/ShaderSource.js";
|
||||
import Texture from "../Renderer/Texture.js";
|
||||
import PassThrough from "../Shaders/PostProcessStages/PassThrough.js";
|
||||
import BlendingState from "./BlendingState.js";
|
||||
import StencilConstants from "./StencilConstants.js";
|
||||
import StencilFunction from "./StencilFunction.js";
|
||||
import StencilOperation from "./StencilOperation.js";
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function InvertClassification() {
|
||||
this._numSamples = 1;
|
||||
this.previousFramebuffer = undefined;
|
||||
this._previousFramebuffer = undefined;
|
||||
|
||||
this._depthStencilTexture = undefined;
|
||||
this._depthStencilRenderbuffer = undefined;
|
||||
this._fbo = new FramebufferManager({
|
||||
depthStencil: true,
|
||||
createDepthAttachments: false,
|
||||
});
|
||||
this._fboClassified = new FramebufferManager({
|
||||
depthStencil: true,
|
||||
createDepthAttachments: false,
|
||||
});
|
||||
|
||||
this._rsUnclassified = undefined;
|
||||
this._rsClassified = undefined;
|
||||
|
||||
this._unclassifiedCommand = undefined;
|
||||
this._classifiedCommand = undefined;
|
||||
this._translucentCommand = undefined;
|
||||
|
||||
this._clearColorCommand = new ClearCommand({
|
||||
color: new Color(0.0, 0.0, 0.0, 0.0),
|
||||
owner: this,
|
||||
});
|
||||
this._clearCommand = new ClearCommand({
|
||||
color: new Color(0.0, 0.0, 0.0, 0.0),
|
||||
depth: 1.0,
|
||||
stencil: 0,
|
||||
});
|
||||
|
||||
const that = this;
|
||||
this._uniformMap = {
|
||||
colorTexture: function () {
|
||||
return that._fbo.getColorTexture();
|
||||
},
|
||||
depthTexture: function () {
|
||||
return that._depthStencilTexture;
|
||||
},
|
||||
classifiedTexture: function () {
|
||||
return that._fboClassified.getColorTexture();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Object.defineProperties(InvertClassification.prototype, {
|
||||
unclassifiedCommand: {
|
||||
get: function () {
|
||||
return this._unclassifiedCommand;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
InvertClassification.isTranslucencySupported = function (context) {
|
||||
return context.depthTexture && context.fragmentDepth;
|
||||
};
|
||||
|
||||
const rsUnclassified = {
|
||||
depthMask: false,
|
||||
stencilTest: {
|
||||
enabled: true,
|
||||
frontFunction: StencilFunction.EQUAL,
|
||||
frontOperation: {
|
||||
fail: StencilOperation.KEEP,
|
||||
zFail: StencilOperation.KEEP,
|
||||
zPass: StencilOperation.KEEP,
|
||||
},
|
||||
backFunction: StencilFunction.NEVER,
|
||||
reference: 0,
|
||||
mask: StencilConstants.CLASSIFICATION_MASK,
|
||||
},
|
||||
blending: BlendingState.ALPHA_BLEND,
|
||||
};
|
||||
|
||||
const rsClassified = {
|
||||
depthMask: false,
|
||||
stencilTest: {
|
||||
enabled: true,
|
||||
frontFunction: StencilFunction.NOT_EQUAL,
|
||||
frontOperation: {
|
||||
fail: StencilOperation.KEEP,
|
||||
zFail: StencilOperation.KEEP,
|
||||
zPass: StencilOperation.KEEP,
|
||||
},
|
||||
backFunction: StencilFunction.NEVER,
|
||||
reference: 0,
|
||||
mask: StencilConstants.CLASSIFICATION_MASK,
|
||||
},
|
||||
blending: BlendingState.ALPHA_BLEND,
|
||||
};
|
||||
|
||||
// Set the 3D Tiles bit when rendering back into the scene's framebuffer. This is only needed if
|
||||
// invert classification does not use the scene's depth-stencil texture, which is the case if the invert
|
||||
// classification color is translucent.
|
||||
const rsDefault = {
|
||||
depthMask: true,
|
||||
depthTest: {
|
||||
enabled: true,
|
||||
},
|
||||
stencilTest: StencilConstants.setCesium3DTileBit(),
|
||||
stencilMask: StencilConstants.CESIUM_3D_TILE_MASK,
|
||||
blending: BlendingState.ALPHA_BLEND,
|
||||
};
|
||||
|
||||
const translucentFS =
|
||||
"uniform sampler2D colorTexture;\n" +
|
||||
"uniform sampler2D depthTexture;\n" +
|
||||
"uniform sampler2D classifiedTexture;\n" +
|
||||
"in vec2 v_textureCoordinates;\n" +
|
||||
"void main()\n" +
|
||||
"{\n" +
|
||||
" vec4 color = texture(colorTexture, v_textureCoordinates);\n" +
|
||||
" if (color.a == 0.0)\n" +
|
||||
" {\n" +
|
||||
" discard;\n" +
|
||||
" }\n" +
|
||||
" bool isClassified = all(equal(texture(classifiedTexture, v_textureCoordinates), vec4(0.0)));\n" +
|
||||
"#ifdef UNCLASSIFIED\n" +
|
||||
" vec4 highlightColor = czm_invertClassificationColor;\n" +
|
||||
" if (isClassified)\n" +
|
||||
" {\n" +
|
||||
" discard;\n" +
|
||||
" }\n" +
|
||||
"#else\n" +
|
||||
" vec4 highlightColor = vec4(1.0);\n" +
|
||||
" if (!isClassified)\n" +
|
||||
" {\n" +
|
||||
" discard;\n" +
|
||||
" }\n" +
|
||||
"#endif\n" +
|
||||
" out_FragColor = color * highlightColor;\n" +
|
||||
" gl_FragDepth = texture(depthTexture, v_textureCoordinates).r;\n" +
|
||||
"}\n";
|
||||
|
||||
const opaqueFS =
|
||||
"uniform sampler2D colorTexture;\n" +
|
||||
"in vec2 v_textureCoordinates;\n" +
|
||||
"void main()\n" +
|
||||
"{\n" +
|
||||
" vec4 color = texture(colorTexture, v_textureCoordinates);\n" +
|
||||
" if (color.a == 0.0)\n" +
|
||||
" {\n" +
|
||||
" discard;\n" +
|
||||
" }\n" +
|
||||
"#ifdef UNCLASSIFIED\n" +
|
||||
" out_FragColor = color * czm_invertClassificationColor;\n" +
|
||||
"#else\n" +
|
||||
" out_FragColor = color;\n" +
|
||||
"#endif\n" +
|
||||
"}\n";
|
||||
|
||||
InvertClassification.prototype.update = function (
|
||||
context,
|
||||
numSamples,
|
||||
globeFramebuffer,
|
||||
) {
|
||||
const texture = this._fbo.getColorTexture();
|
||||
const previousFramebufferChanged =
|
||||
this.previousFramebuffer !== this._previousFramebuffer;
|
||||
this._previousFramebuffer = this.previousFramebuffer;
|
||||
const samplesChanged = this._numSamples !== numSamples;
|
||||
|
||||
const width = context.drawingBufferWidth;
|
||||
const height = context.drawingBufferHeight;
|
||||
const textureChanged =
|
||||
!defined(texture) || texture.width !== width || texture.height !== height;
|
||||
|
||||
if (textureChanged || previousFramebufferChanged || samplesChanged) {
|
||||
this._numSamples = numSamples;
|
||||
this._depthStencilTexture =
|
||||
this._depthStencilTexture && this._depthStencilTexture.destroy();
|
||||
this._depthStencilRenderbuffer =
|
||||
this._depthStencilRenderbuffer &&
|
||||
this._depthStencilRenderbuffer.destroy();
|
||||
|
||||
if (!defined(this._previousFramebuffer)) {
|
||||
this._depthStencilTexture = new Texture({
|
||||
context: context,
|
||||
width: width,
|
||||
height: height,
|
||||
pixelFormat: PixelFormat.DEPTH_STENCIL,
|
||||
pixelDatatype: PixelDatatype.UNSIGNED_INT_24_8,
|
||||
});
|
||||
if (numSamples > 1) {
|
||||
this._depthStencilRenderbuffer = new Renderbuffer({
|
||||
context: context,
|
||||
width: width,
|
||||
height: height,
|
||||
format: RenderbufferFormat.DEPTH24_STENCIL8,
|
||||
numSamples: numSamples,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!defined(this._fbo.framebuffer) ||
|
||||
textureChanged ||
|
||||
previousFramebufferChanged ||
|
||||
samplesChanged
|
||||
) {
|
||||
this._fbo.destroy();
|
||||
this._fboClassified.destroy();
|
||||
|
||||
let depthStencilTexture;
|
||||
let depthStencilRenderbuffer;
|
||||
if (defined(this._previousFramebuffer)) {
|
||||
depthStencilTexture = globeFramebuffer.getDepthStencilTexture();
|
||||
depthStencilRenderbuffer = globeFramebuffer.getDepthStencilRenderbuffer();
|
||||
} else {
|
||||
depthStencilTexture = this._depthStencilTexture;
|
||||
depthStencilRenderbuffer = this._depthStencilRenderbuffer;
|
||||
}
|
||||
|
||||
this._fbo.setDepthStencilTexture(depthStencilTexture);
|
||||
if (defined(depthStencilRenderbuffer)) {
|
||||
this._fbo.setDepthStencilRenderbuffer(depthStencilRenderbuffer);
|
||||
}
|
||||
this._fbo.update(context, width, height, numSamples);
|
||||
|
||||
if (!defined(this._previousFramebuffer)) {
|
||||
this._fboClassified.setDepthStencilTexture(depthStencilTexture);
|
||||
this._fboClassified.update(context, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined(this._rsUnclassified)) {
|
||||
this._rsUnclassified = RenderState.fromCache(rsUnclassified);
|
||||
this._rsClassified = RenderState.fromCache(rsClassified);
|
||||
this._rsDefault = RenderState.fromCache(rsDefault);
|
||||
}
|
||||
|
||||
if (
|
||||
!defined(this._unclassifiedCommand) ||
|
||||
previousFramebufferChanged ||
|
||||
samplesChanged
|
||||
) {
|
||||
if (defined(this._unclassifiedCommand)) {
|
||||
this._unclassifiedCommand.shaderProgram =
|
||||
this._unclassifiedCommand.shaderProgram &&
|
||||
this._unclassifiedCommand.shaderProgram.destroy();
|
||||
this._classifiedCommand.shaderProgram =
|
||||
this._classifiedCommand.shaderProgram &&
|
||||
this._classifiedCommand.shaderProgram.destroy();
|
||||
}
|
||||
|
||||
const fs = defined(this._previousFramebuffer) ? opaqueFS : translucentFS;
|
||||
const unclassifiedFSSource = new ShaderSource({
|
||||
defines: ["UNCLASSIFIED"],
|
||||
sources: [fs],
|
||||
});
|
||||
const classifiedFSSource = new ShaderSource({
|
||||
sources: [fs],
|
||||
});
|
||||
this._unclassifiedCommand = context.createViewportQuadCommand(
|
||||
unclassifiedFSSource,
|
||||
{
|
||||
renderState: defined(this._previousFramebuffer)
|
||||
? this._rsUnclassified
|
||||
: this._rsDefault,
|
||||
uniformMap: this._uniformMap,
|
||||
owner: this,
|
||||
},
|
||||
);
|
||||
this._classifiedCommand = context.createViewportQuadCommand(
|
||||
classifiedFSSource,
|
||||
{
|
||||
renderState: defined(this._previousFramebuffer)
|
||||
? this._rsClassified
|
||||
: this._rsDefault,
|
||||
uniformMap: this._uniformMap,
|
||||
owner: this,
|
||||
},
|
||||
);
|
||||
|
||||
if (defined(this._translucentCommand)) {
|
||||
this._translucentCommand.shaderProgram =
|
||||
this._translucentCommand.shaderProgram &&
|
||||
this._translucentCommand.shaderProgram.destroy();
|
||||
}
|
||||
if (!defined(this._previousFramebuffer)) {
|
||||
this._translucentCommand = context.createViewportQuadCommand(
|
||||
PassThrough,
|
||||
{
|
||||
renderState: this._rsUnclassified,
|
||||
uniformMap: this._uniformMap,
|
||||
owner: this,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InvertClassification.prototype.prepareTextures = function (
|
||||
context,
|
||||
blitStencil,
|
||||
) {
|
||||
if (this._fbo._numSamples > 1) {
|
||||
this._fbo.prepareTextures(context, blitStencil);
|
||||
}
|
||||
};
|
||||
|
||||
InvertClassification.prototype.clear = function (context, passState) {
|
||||
if (defined(this._previousFramebuffer)) {
|
||||
this._fbo.clear(context, this._clearColorCommand, passState);
|
||||
} else {
|
||||
this._fbo.clear(context, this._clearCommand, passState);
|
||||
this._fboClassified.clear(context, this._clearCommand, passState);
|
||||
}
|
||||
};
|
||||
|
||||
InvertClassification.prototype.executeClassified = function (
|
||||
context,
|
||||
passState,
|
||||
) {
|
||||
if (!defined(this._previousFramebuffer)) {
|
||||
const framebuffer = passState.framebuffer;
|
||||
|
||||
this.prepareTextures(context, true);
|
||||
passState.framebuffer = this._fboClassified.framebuffer;
|
||||
this._translucentCommand.execute(context, passState);
|
||||
|
||||
passState.framebuffer = framebuffer;
|
||||
}
|
||||
this._classifiedCommand.execute(context, passState);
|
||||
};
|
||||
|
||||
InvertClassification.prototype.executeUnclassified = function (
|
||||
context,
|
||||
passState,
|
||||
) {
|
||||
this._unclassifiedCommand.execute(context, passState);
|
||||
};
|
||||
|
||||
InvertClassification.prototype.isDestroyed = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
InvertClassification.prototype.destroy = function () {
|
||||
this._fbo.destroy();
|
||||
this._fboClassified.destroy();
|
||||
this._depthStencilTexture =
|
||||
this._depthStencilTexture && this._depthStencilTexture.destroy();
|
||||
this._depthStencilRenderbuffer =
|
||||
this._depthStencilRenderbuffer && this._depthStencilRenderbuffer.destroy();
|
||||
|
||||
if (defined(this._unclassifiedCommand)) {
|
||||
this._unclassifiedCommand.shaderProgram =
|
||||
this._unclassifiedCommand.shaderProgram &&
|
||||
this._unclassifiedCommand.shaderProgram.destroy();
|
||||
this._classifiedCommand.shaderProgram =
|
||||
this._classifiedCommand.shaderProgram &&
|
||||
this._classifiedCommand.shaderProgram.destroy();
|
||||
}
|
||||
|
||||
return destroyObject(this);
|
||||
};
|
||||
export default InvertClassification;
|
||||
Reference in New Issue
Block a user