import BoundingRectangle from '../Core/BoundingRectangle.js';
|
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 WebGLConstants from '../Core/WebGLConstants.js';
|
import ClearCommand from '../Renderer/ClearCommand.js';
|
import DrawCommand from '../Renderer/DrawCommand.js';
|
import Framebuffer from '../Renderer/Framebuffer.js';
|
import PixelDatatype from '../Renderer/PixelDatatype.js';
|
import RenderState from '../Renderer/RenderState.js';
|
import ShaderSource from '../Renderer/ShaderSource.js';
|
import Texture from '../Renderer/Texture.js';
|
import AdjustTranslucentFS from '../Shaders/AdjustTranslucentFS.js';
|
import CompositeOITFS from '../Shaders/CompositeOITFS.js';
|
import BlendEquation from './BlendEquation.js';
|
import BlendFunction from './BlendFunction.js';
|
|
/**
|
* @private
|
*/
|
function OIT(context) {
|
// We support multipass for the Chrome D3D9 backend and ES 2.0 on mobile.
|
this._translucentMultipassSupport = false;
|
this._translucentMRTSupport = false;
|
|
var extensionsSupported = context.colorBufferFloat && context.depthTexture;
|
this._translucentMRTSupport = context.drawBuffers && extensionsSupported;
|
this._translucentMultipassSupport = !this._translucentMRTSupport && extensionsSupported;
|
|
this._opaqueFBO = undefined;
|
this._opaqueTexture = undefined;
|
this._depthStencilTexture = undefined;
|
|
this._accumulationTexture = undefined;
|
|
this._translucentFBO = undefined;
|
this._alphaFBO = undefined;
|
|
this._adjustTranslucentFBO = undefined;
|
this._adjustAlphaFBO = undefined;
|
|
this._opaqueClearCommand = new ClearCommand({
|
color : new Color(0.0, 0.0, 0.0, 0.0),
|
owner : this
|
});
|
this._translucentMRTClearCommand = new ClearCommand({
|
color : new Color(0.0, 0.0, 0.0, 1.0),
|
owner : this
|
});
|
this._translucentMultipassClearCommand = new ClearCommand({
|
color : new Color(0.0, 0.0, 0.0, 0.0),
|
owner : this
|
});
|
this._alphaClearCommand = new ClearCommand({
|
color : new Color(1.0, 1.0, 1.0, 1.0),
|
owner : this
|
});
|
|
this._translucentRenderStateCache = {};
|
this._alphaRenderStateCache = {};
|
|
this._compositeCommand = undefined;
|
this._adjustTranslucentCommand = undefined;
|
this._adjustAlphaCommand = undefined;
|
|
this._viewport = new BoundingRectangle();
|
this._rs = undefined;
|
|
this._useScissorTest = false;
|
this._scissorRectangle = undefined;
|
|
this._useHDR = false;
|
}
|
|
function destroyTextures(oit) {
|
oit._accumulationTexture = oit._accumulationTexture && !oit._accumulationTexture.isDestroyed() && oit._accumulationTexture.destroy();
|
oit._revealageTexture = oit._revealageTexture && !oit._revealageTexture.isDestroyed() && oit._revealageTexture.destroy();
|
}
|
|
function destroyFramebuffers(oit) {
|
oit._translucentFBO = oit._translucentFBO && !oit._translucentFBO.isDestroyed() && oit._translucentFBO.destroy();
|
oit._alphaFBO = oit._alphaFBO && !oit._alphaFBO.isDestroyed() && oit._alphaFBO.destroy();
|
oit._adjustTranslucentFBO = oit._adjustTranslucentFBO && !oit._adjustTranslucentFBO.isDestroyed() && oit._adjustTranslucentFBO.destroy();
|
oit._adjustAlphaFBO = oit._adjustAlphaFBO && !oit._adjustAlphaFBO.isDestroyed() && oit._adjustAlphaFBO.destroy();
|
}
|
|
function destroyResources(oit) {
|
destroyTextures(oit);
|
destroyFramebuffers(oit);
|
}
|
|
function updateTextures(oit, context, width, height) {
|
destroyTextures(oit);
|
|
oit._accumulationTexture = new Texture({
|
context : context,
|
width : width,
|
height : height,
|
pixelFormat : PixelFormat.RGBA,
|
pixelDatatype : PixelDatatype.FLOAT
|
});
|
|
// Use zeroed arraybuffer instead of null to initialize texture
|
// to workaround Firefox. Only needed for the second color attachment.
|
var source = new Float32Array(width * height * 4);
|
oit._revealageTexture = new Texture({
|
context : context,
|
pixelFormat : PixelFormat.RGBA,
|
pixelDatatype : PixelDatatype.FLOAT,
|
source : {
|
arrayBufferView : source,
|
width : width,
|
height : height
|
},
|
flipY : false
|
});
|
}
|
|
function updateFramebuffers(oit, context) {
|
destroyFramebuffers(oit);
|
|
var completeFBO = WebGLConstants.FRAMEBUFFER_COMPLETE;
|
var supported = true;
|
|
// if MRT is supported, attempt to make an FBO with multiple color attachments
|
if (oit._translucentMRTSupport) {
|
oit._translucentFBO = new Framebuffer({
|
context : context,
|
colorTextures : [oit._accumulationTexture, oit._revealageTexture],
|
depthStencilTexture : oit._depthStencilTexture,
|
destroyAttachments : false
|
});
|
oit._adjustTranslucentFBO = new Framebuffer({
|
context : context,
|
colorTextures : [oit._accumulationTexture, oit._revealageTexture],
|
destroyAttachments : false
|
});
|
|
if (oit._translucentFBO.status !== completeFBO || oit._adjustTranslucentFBO.status !== completeFBO) {
|
destroyFramebuffers(oit);
|
oit._translucentMRTSupport = false;
|
}
|
}
|
|
// either MRT isn't supported or FBO creation failed, attempt multipass
|
if (!oit._translucentMRTSupport) {
|
oit._translucentFBO = new Framebuffer({
|
context : context,
|
colorTextures : [oit._accumulationTexture],
|
depthStencilTexture : oit._depthStencilTexture,
|
destroyAttachments : false
|
});
|
oit._alphaFBO = new Framebuffer({
|
context : context,
|
colorTextures : [oit._revealageTexture],
|
depthStencilTexture : oit._depthStencilTexture,
|
destroyAttachments : false
|
});
|
oit._adjustTranslucentFBO = new Framebuffer({
|
context : context,
|
colorTextures : [oit._accumulationTexture],
|
destroyAttachments : false
|
});
|
oit._adjustAlphaFBO = new Framebuffer({
|
context : context,
|
colorTextures : [oit._revealageTexture],
|
destroyAttachments : false
|
});
|
|
var translucentComplete = oit._translucentFBO.status === completeFBO;
|
var alphaComplete = oit._alphaFBO.status === completeFBO;
|
var adjustTranslucentComplete = oit._adjustTranslucentFBO.status === completeFBO;
|
var adjustAlphaComplete = oit._adjustAlphaFBO.status === completeFBO;
|
if (!translucentComplete || !alphaComplete || !adjustTranslucentComplete || !adjustAlphaComplete) {
|
destroyResources(oit);
|
oit._translucentMultipassSupport = false;
|
supported = false;
|
}
|
}
|
|
return supported;
|
}
|
|
OIT.prototype.update = function(context, passState, framebuffer, useHDR) {
|
if (!this.isSupported()) {
|
return;
|
}
|
|
this._opaqueFBO = framebuffer;
|
this._opaqueTexture = framebuffer.getColorTexture(0);
|
this._depthStencilTexture = framebuffer.depthStencilTexture;
|
|
var width = this._opaqueTexture.width;
|
var height = this._opaqueTexture.height;
|
|
var accumulationTexture = this._accumulationTexture;
|
var textureChanged = !defined(accumulationTexture) || accumulationTexture.width !== width || accumulationTexture.height !== height || useHDR !== this._useHDR;
|
if (textureChanged) {
|
updateTextures(this, context, width, height);
|
}
|
|
if (!defined(this._translucentFBO) || textureChanged) {
|
if (!updateFramebuffers(this, context)) {
|
// framebuffer creation failed
|
return;
|
}
|
}
|
|
this._useHDR = useHDR;
|
|
var that = this;
|
var fs;
|
var uniformMap;
|
|
if (!defined(this._compositeCommand)) {
|
fs = new ShaderSource({
|
sources : [CompositeOITFS]
|
});
|
if (this._translucentMRTSupport) {
|
fs.defines.push('MRT');
|
}
|
|
uniformMap = {
|
u_opaque : function() {
|
return that._opaqueTexture;
|
},
|
u_accumulation : function() {
|
return that._accumulationTexture;
|
},
|
u_revealage : function() {
|
return that._revealageTexture;
|
}
|
};
|
this._compositeCommand = context.createViewportQuadCommand(fs, {
|
uniformMap : uniformMap,
|
owner : this
|
});
|
}
|
|
if (!defined(this._adjustTranslucentCommand)) {
|
if (this._translucentMRTSupport) {
|
fs = new ShaderSource({
|
defines : ['MRT'],
|
sources : [AdjustTranslucentFS]
|
});
|
|
uniformMap = {
|
u_bgColor : function() {
|
return that._translucentMRTClearCommand.color;
|
},
|
u_depthTexture : function() {
|
return that._depthStencilTexture;
|
}
|
};
|
|
this._adjustTranslucentCommand = context.createViewportQuadCommand(fs, {
|
uniformMap : uniformMap,
|
owner : this
|
});
|
} else if (this._translucentMultipassSupport) {
|
fs = new ShaderSource({
|
sources : [AdjustTranslucentFS]
|
});
|
|
uniformMap = {
|
u_bgColor : function() {
|
return that._translucentMultipassClearCommand.color;
|
},
|
u_depthTexture : function() {
|
return that._depthStencilTexture;
|
}
|
};
|
|
this._adjustTranslucentCommand = context.createViewportQuadCommand(fs, {
|
uniformMap : uniformMap,
|
owner : this
|
});
|
|
uniformMap = {
|
u_bgColor : function() {
|
return that._alphaClearCommand.color;
|
},
|
u_depthTexture : function() {
|
return that._depthStencilTexture;
|
}
|
};
|
|
this._adjustAlphaCommand = context.createViewportQuadCommand(fs, {
|
uniformMap : uniformMap,
|
owner : this
|
});
|
}
|
}
|
|
this._viewport.width = width;
|
this._viewport.height = height;
|
|
var useScissorTest = !BoundingRectangle.equals(this._viewport, passState.viewport);
|
var updateScissor = useScissorTest !== this._useScissorTest;
|
this._useScissorTest = useScissorTest;
|
|
if (!BoundingRectangle.equals(this._scissorRectangle, passState.viewport)) {
|
this._scissorRectangle = BoundingRectangle.clone(passState.viewport, this._scissorRectangle);
|
updateScissor = true;
|
}
|
|
if (!defined(this._rs) || !BoundingRectangle.equals(this._viewport, this._rs.viewport) || updateScissor) {
|
this._rs = RenderState.fromCache({
|
viewport : this._viewport,
|
scissorTest : {
|
enabled : this._useScissorTest,
|
rectangle : this._scissorRectangle
|
}
|
});
|
}
|
|
if (defined(this._compositeCommand)) {
|
this._compositeCommand.renderState = this._rs;
|
}
|
|
if (this._adjustTranslucentCommand) {
|
this._adjustTranslucentCommand.renderState = this._rs;
|
}
|
|
if (defined(this._adjustAlphaCommand)) {
|
this._adjustAlphaCommand.renderState = this._rs;
|
}
|
};
|
|
var translucentMRTBlend = {
|
enabled : true,
|
color : new Color(0.0, 0.0, 0.0, 0.0),
|
equationRgb : BlendEquation.ADD,
|
equationAlpha : BlendEquation.ADD,
|
functionSourceRgb : BlendFunction.ONE,
|
functionDestinationRgb : BlendFunction.ONE,
|
functionSourceAlpha : BlendFunction.ZERO,
|
functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA
|
};
|
|
var translucentColorBlend = {
|
enabled : true,
|
color : new Color(0.0, 0.0, 0.0, 0.0),
|
equationRgb : BlendEquation.ADD,
|
equationAlpha : BlendEquation.ADD,
|
functionSourceRgb : BlendFunction.ONE,
|
functionDestinationRgb : BlendFunction.ONE,
|
functionSourceAlpha : BlendFunction.ONE,
|
functionDestinationAlpha : BlendFunction.ONE
|
};
|
|
var translucentAlphaBlend = {
|
enabled : true,
|
color : new Color(0.0, 0.0, 0.0, 0.0),
|
equationRgb : BlendEquation.ADD,
|
equationAlpha : BlendEquation.ADD,
|
functionSourceRgb : BlendFunction.ZERO,
|
functionDestinationRgb : BlendFunction.ONE_MINUS_SOURCE_ALPHA,
|
functionSourceAlpha : BlendFunction.ZERO,
|
functionDestinationAlpha : BlendFunction.ONE_MINUS_SOURCE_ALPHA
|
};
|
|
function getTranslucentRenderState(context, translucentBlending, cache, renderState) {
|
var translucentState = cache[renderState.id];
|
if (!defined(translucentState)) {
|
var rs = RenderState.getState(renderState);
|
rs.depthMask = false;
|
rs.blending = translucentBlending;
|
|
translucentState = RenderState.fromCache(rs);
|
cache[renderState.id] = translucentState;
|
}
|
|
return translucentState;
|
}
|
|
function getTranslucentMRTRenderState(oit, context, renderState) {
|
return getTranslucentRenderState(context, translucentMRTBlend, oit._translucentRenderStateCache, renderState);
|
}
|
|
function getTranslucentColorRenderState(oit, context, renderState) {
|
return getTranslucentRenderState(context, translucentColorBlend, oit._translucentRenderStateCache, renderState);
|
}
|
|
function getTranslucentAlphaRenderState(oit, context, renderState) {
|
return getTranslucentRenderState(context, translucentAlphaBlend, oit._alphaRenderStateCache, renderState);
|
}
|
|
var mrtShaderSource =
|
' vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n' +
|
' float ai = czm_gl_FragColor.a;\n' +
|
' float wzi = czm_alphaWeight(ai);\n' +
|
' gl_FragData[0] = vec4(Ci * wzi, ai);\n' +
|
' gl_FragData[1] = vec4(ai * wzi);\n';
|
|
var colorShaderSource =
|
' vec3 Ci = czm_gl_FragColor.rgb * czm_gl_FragColor.a;\n' +
|
' float ai = czm_gl_FragColor.a;\n' +
|
' float wzi = czm_alphaWeight(ai);\n' +
|
' gl_FragColor = vec4(Ci, ai) * wzi;\n';
|
|
var alphaShaderSource =
|
' float ai = czm_gl_FragColor.a;\n' +
|
' gl_FragColor = vec4(ai);\n';
|
|
function getTranslucentShaderProgram(context, shaderProgram, keyword, source) {
|
var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword);
|
if (!defined(shader)) {
|
var attributeLocations = shaderProgram._attributeLocations;
|
|
var fs = shaderProgram.fragmentShaderSource.clone();
|
|
fs.sources = fs.sources.map(function(source) {
|
source = ShaderSource.replaceMain(source, 'czm_translucent_main');
|
source = source.replace(/gl_FragColor/g, 'czm_gl_FragColor');
|
source = source.replace(/\bdiscard\b/g, 'czm_discard = true');
|
source = source.replace(/czm_phong/g, 'czm_translucentPhong');
|
return source;
|
});
|
|
// Discarding the fragment in main is a workaround for ANGLE D3D9
|
// shader compilation errors.
|
|
fs.sources.splice(0, 0,
|
(source.indexOf('gl_FragData') !== -1 ? '#extension GL_EXT_draw_buffers : enable \n' : '') +
|
'vec4 czm_gl_FragColor;\n' +
|
'bool czm_discard = false;\n');
|
|
fs.sources.push(
|
'void main()\n' +
|
'{\n' +
|
' czm_translucent_main();\n' +
|
' if (czm_discard)\n' +
|
' {\n' +
|
' discard;\n' +
|
' }\n' +
|
source +
|
'}\n');
|
|
shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, {
|
vertexShaderSource : shaderProgram.vertexShaderSource,
|
fragmentShaderSource : fs,
|
attributeLocations : attributeLocations
|
});
|
}
|
|
return shader;
|
}
|
|
function getTranslucentMRTShaderProgram(context, shaderProgram) {
|
return getTranslucentShaderProgram(context, shaderProgram, 'translucentMRT', mrtShaderSource);
|
}
|
|
function getTranslucentColorShaderProgram(context, shaderProgram) {
|
return getTranslucentShaderProgram(context, shaderProgram, 'translucentMultipass', colorShaderSource);
|
}
|
|
function getTranslucentAlphaShaderProgram(context, shaderProgram) {
|
return getTranslucentShaderProgram(context, shaderProgram, 'alphaMultipass', alphaShaderSource);
|
}
|
|
OIT.prototype.createDerivedCommands = function(command, context, result) {
|
if (!defined(result)) {
|
result = {};
|
}
|
|
if (this._translucentMRTSupport) {
|
var translucentShader;
|
var translucentRenderState;
|
if (defined(result.translucentCommand)) {
|
translucentShader = result.translucentCommand.shaderProgram;
|
translucentRenderState = result.translucentCommand.renderState;
|
}
|
|
result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand);
|
|
if (!defined(translucentShader) || result.shaderProgramId !== command.shaderProgram.id) {
|
result.translucentCommand.shaderProgram = getTranslucentMRTShaderProgram(context, command.shaderProgram);
|
result.translucentCommand.renderState = getTranslucentMRTRenderState(this, context, command.renderState);
|
result.shaderProgramId = command.shaderProgram.id;
|
} else {
|
result.translucentCommand.shaderProgram = translucentShader;
|
result.translucentCommand.renderState = translucentRenderState;
|
}
|
} else {
|
var colorShader;
|
var colorRenderState;
|
var alphaShader;
|
var alphaRenderState;
|
if (defined(result.translucentCommand)) {
|
colorShader = result.translucentCommand.shaderProgram;
|
colorRenderState = result.translucentCommand.renderState;
|
alphaShader = result.alphaCommand.shaderProgram;
|
alphaRenderState = result.alphaCommand.renderState;
|
}
|
|
result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand);
|
result.alphaCommand = DrawCommand.shallowClone(command, result.alphaCommand);
|
|
if (!defined(colorShader) || result.shaderProgramId !== command.shaderProgram.id) {
|
result.translucentCommand.shaderProgram = getTranslucentColorShaderProgram(context, command.shaderProgram);
|
result.translucentCommand.renderState = getTranslucentColorRenderState(this, context, command.renderState);
|
result.alphaCommand.shaderProgram = getTranslucentAlphaShaderProgram(context, command.shaderProgram);
|
result.alphaCommand.renderState = getTranslucentAlphaRenderState(this, context, command.renderState);
|
result.shaderProgramId = command.shaderProgram.id;
|
} else {
|
result.translucentCommand.shaderProgram = colorShader;
|
result.translucentCommand.renderState = colorRenderState;
|
result.alphaCommand.shaderProgram = alphaShader;
|
result.alphaCommand.renderState = alphaRenderState;
|
}
|
}
|
|
return result;
|
};
|
|
function executeTranslucentCommandsSortedMultipass(oit, scene, executeFunction, passState, commands, invertClassification) {
|
var command;
|
var derivedCommand;
|
var j;
|
|
var context = scene.context;
|
var useLogDepth = scene.frameState.useLogDepth;
|
var useHdr = scene._hdr;
|
var framebuffer = passState.framebuffer;
|
var length = commands.length;
|
|
var lightShadowsEnabled = scene.frameState.shadowState.lightShadowsEnabled;
|
|
passState.framebuffer = oit._adjustTranslucentFBO;
|
oit._adjustTranslucentCommand.execute(context, passState);
|
passState.framebuffer = oit._adjustAlphaFBO;
|
oit._adjustAlphaCommand.execute(context, passState);
|
|
var debugFramebuffer = oit._opaqueFBO;
|
passState.framebuffer = oit._translucentFBO;
|
|
for (j = 0; j < length; ++j) {
|
command = commands[j];
|
command = useLogDepth ? command.derivedCommands.logDepth.command : command;
|
command = useHdr ? command.derivedCommands.hdr.command : command;
|
derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand;
|
executeFunction(derivedCommand, scene, context, passState, debugFramebuffer);
|
}
|
|
if (defined(invertClassification)) {
|
command = invertClassification.unclassifiedCommand;
|
derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand;
|
executeFunction(derivedCommand, scene, context, passState, debugFramebuffer);
|
}
|
|
passState.framebuffer = oit._alphaFBO;
|
|
for (j = 0; j < length; ++j) {
|
command = commands[j];
|
command = useLogDepth ? command.derivedCommands.logDepth.command : command;
|
command = useHdr ? command.derivedCommands.hdr.command : command;
|
derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand;
|
executeFunction(derivedCommand, scene, context, passState, debugFramebuffer);
|
}
|
|
if (defined(invertClassification)) {
|
command = invertClassification.unclassifiedCommand;
|
derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand;
|
executeFunction(derivedCommand, scene, context, passState, debugFramebuffer);
|
}
|
|
passState.framebuffer = framebuffer;
|
}
|
|
function executeTranslucentCommandsSortedMRT(oit, scene, executeFunction, passState, commands, invertClassification) {
|
var context = scene.context;
|
var useLogDepth = scene.frameState.useLogDepth;
|
var useHdr = scene._hdr;
|
var framebuffer = passState.framebuffer;
|
var length = commands.length;
|
|
var lightShadowsEnabled = scene.frameState.shadowState.lightShadowsEnabled;
|
|
passState.framebuffer = oit._adjustTranslucentFBO;
|
oit._adjustTranslucentCommand.execute(context, passState);
|
|
var debugFramebuffer = oit._opaqueFBO;
|
passState.framebuffer = oit._translucentFBO;
|
|
var command;
|
var derivedCommand;
|
|
for (var j = 0; j < length; ++j) {
|
command = commands[j];
|
command = useLogDepth ? command.derivedCommands.logDepth.command : command;
|
command = useHdr ? command.derivedCommands.hdr.command : command;
|
derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand;
|
executeFunction(derivedCommand, scene, context, passState, debugFramebuffer);
|
}
|
|
if (defined(invertClassification)) {
|
command = invertClassification.unclassifiedCommand;
|
derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand;
|
executeFunction(derivedCommand, scene, context, passState, debugFramebuffer);
|
}
|
|
passState.framebuffer = framebuffer;
|
}
|
|
OIT.prototype.executeCommands = function(scene, executeFunction, passState, commands, invertClassification) {
|
if (this._translucentMRTSupport) {
|
executeTranslucentCommandsSortedMRT(this, scene, executeFunction, passState, commands, invertClassification);
|
return;
|
}
|
|
executeTranslucentCommandsSortedMultipass(this, scene, executeFunction, passState, commands, invertClassification);
|
};
|
|
OIT.prototype.execute = function(context, passState) {
|
this._compositeCommand.execute(context, passState);
|
};
|
|
OIT.prototype.clear = function(context, passState, clearColor) {
|
var framebuffer = passState.framebuffer;
|
|
passState.framebuffer = this._opaqueFBO;
|
Color.clone(clearColor, this._opaqueClearCommand.color);
|
this._opaqueClearCommand.execute(context, passState);
|
|
passState.framebuffer = this._translucentFBO;
|
var translucentClearCommand = this._translucentMRTSupport ? this._translucentMRTClearCommand : this._translucentMultipassClearCommand;
|
translucentClearCommand.execute(context, passState);
|
|
if (this._translucentMultipassSupport) {
|
passState.framebuffer = this._alphaFBO;
|
this._alphaClearCommand.execute(context, passState);
|
}
|
|
passState.framebuffer = framebuffer;
|
};
|
|
OIT.prototype.isSupported = function() {
|
return this._translucentMRTSupport || this._translucentMultipassSupport;
|
};
|
|
OIT.prototype.isDestroyed = function() {
|
return false;
|
};
|
|
OIT.prototype.destroy = function() {
|
destroyResources(this);
|
|
if (defined(this._compositeCommand)) {
|
this._compositeCommand.shaderProgram = this._compositeCommand.shaderProgram && this._compositeCommand.shaderProgram.destroy();
|
}
|
|
if (defined(this._adjustTranslucentCommand)) {
|
this._adjustTranslucentCommand.shaderProgram = this._adjustTranslucentCommand.shaderProgram && this._adjustTranslucentCommand.shaderProgram.destroy();
|
}
|
|
if (defined(this._adjustAlphaCommand)) {
|
this._adjustAlphaCommand.shaderProgram = this._adjustAlphaCommand.shaderProgram && this._adjustAlphaCommand.shaderProgram.destroy();
|
}
|
|
return destroyObject(this);
|
};
|
export default OIT;
|