Skip to content

Commit

Permalink
Merge pull request #4979 from AnalyticalGraphicsInc/pick-translucent
Browse files Browse the repository at this point in the history
Pick translucent geometry
  • Loading branch information
pjcozzi authored Feb 22, 2017
2 parents 913b253 + 4686c2f commit 7a0a6e7
Show file tree
Hide file tree
Showing 9 changed files with 528 additions and 108 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Change Log
* Fixed an issue with constant `VertexArray` attributes not being set correctly. [#4995](https://github.com/AnalyticalGraphicsInc/cesium/pull/4995)
* Add support for `Scene.pickPosition` in Columbus view and 2D. [#4990](https://github.com/AnalyticalGraphicsInc/cesium/pull/4990)
* Added `Label.scaleByDistance` to control minimum/maximum label size based on distance from the camera. [#5019](https://github.com/AnalyticalGraphicsInc/cesium/pull/5019)
* Add support for depth picking translucent primitives when `Scene.pickTranslucentDepth` is `true`. [#4979](https://github.com/AnalyticalGraphicsInc/cesium/pull/4979)

### 1.30 - 2017-02-01

Expand Down
85 changes: 78 additions & 7 deletions Source/Renderer/ShaderCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ define([
* fragmentShaderSource : fs,
* attributeLocations : attributeLocations
* });
*
*
* @see ShaderCache#getShaderProgram
*/
ShaderCache.prototype.replaceShaderProgram = function(options) {
Expand Down Expand Up @@ -103,7 +103,7 @@ define([
var keyword = vertexShaderText + fragmentShaderText + JSON.stringify(attributeLocations);
var cachedShader;

if (this._shaders[keyword]) {
if (defined(this._shaders[keyword])) {
cachedShader = this._shaders[keyword];

// No longer want to release this if it was previously released.
Expand All @@ -125,6 +125,7 @@ define([
cache : this,
shaderProgram : shaderProgram,
keyword : keyword,
derivedKeywords : [],
count : 0
};

Expand All @@ -138,14 +139,86 @@ define([
return cachedShader.shaderProgram;
};

ShaderCache.prototype.getDerivedShaderProgram = function(shaderProgram, keyword) {
var cachedShader = shaderProgram._cachedShader;
var derivedKeyword = keyword + cachedShader.keyword;
var cachedDerivedShader = this._shaders[derivedKeyword];
if (!defined(cachedDerivedShader)) {
return undefined;
}

return cachedDerivedShader.shaderProgram;
};

ShaderCache.prototype.createDerivedShaderProgram = function(shaderProgram, keyword, options) {
var cachedShader = shaderProgram._cachedShader;
var derivedKeyword = keyword + cachedShader.keyword;

var vertexShaderSource = options.vertexShaderSource;
var fragmentShaderSource = options.fragmentShaderSource;
var attributeLocations = options.attributeLocations;

if (typeof vertexShaderSource === 'string') {
vertexShaderSource = new ShaderSource({
sources : [vertexShaderSource]
});
}

if (typeof fragmentShaderSource === 'string') {
fragmentShaderSource = new ShaderSource({
sources : [fragmentShaderSource]
});
}

var vertexShaderText = vertexShaderSource.createCombinedVertexShader();
var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader();

var context = this._context;
var derivedShaderProgram = new ShaderProgram({
gl : context._gl,
logShaderCompilation : context.logShaderCompilation,
debugShaders : context.debugShaders,
vertexShaderSource : vertexShaderSource,
vertexShaderText : vertexShaderText,
fragmentShaderSource : fragmentShaderSource,
fragmentShaderText : fragmentShaderText,
attributeLocations : attributeLocations
});

var derivedCachedShader = {
cache : this,
shaderProgram : derivedShaderProgram,
keyword : derivedKeyword,
derivedKeywords : [],
count : 0
};

cachedShader.derivedKeywords.push(keyword);
derivedShaderProgram._cachedShader = derivedCachedShader;
this._shaders[derivedKeyword] = derivedCachedShader;
return derivedShaderProgram;
};

function destroyShader(cache, cachedShader) {
var derivedKeywords = cachedShader.derivedKeywords;
var length = derivedKeywords.length;
for (var i = 0; i < length; ++i) {
var keyword = derivedKeywords[i] + cachedShader.keyword;
var derivedCachedShader = cache._shaders[keyword];
destroyShader(cache, derivedCachedShader);
}

delete cache._shaders[cachedShader.keyword];
cachedShader.shaderProgram.finalDestroy();
}

ShaderCache.prototype.destroyReleasedShaderPrograms = function() {
var shadersToRelease = this._shadersToRelease;

for ( var keyword in shadersToRelease) {
if (shadersToRelease.hasOwnProperty(keyword)) {
var cachedShader = shadersToRelease[keyword];
delete this._shaders[cachedShader.keyword];
cachedShader.shaderProgram.finalDestroy();
destroyShader(this, cachedShader);
--this._numberOfShaders;
}
}
Expand All @@ -168,13 +241,11 @@ define([

ShaderCache.prototype.destroy = function() {
var shaders = this._shaders;

for ( var keyword in shaders) {
for (var keyword in shaders) {
if (shaders.hasOwnProperty(keyword)) {
shaders[keyword].shaderProgram.finalDestroy();
}
}

return destroyObject(this);
};

Expand Down
9 changes: 8 additions & 1 deletion Source/Scene/FrameState.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,14 @@ define([
* @type {Boolean}
* @default false
*/
pick : false
pick : false,

/**
* <code>true</code> if the primitive should update for a depth only pass, <code>false</code> otherwise.
* @type {Boolean}
* @default false
*/
depth : false
};

/**
Expand Down
47 changes: 12 additions & 35 deletions Source/Scene/OIT.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ define([

this._translucentRenderStateCache = {};
this._alphaRenderStateCache = {};
this._translucentShaderCache = {};
this._alphaShaderCache = {};

this._compositeCommand = undefined;
this._adjustTranslucentCommand = undefined;
Expand Down Expand Up @@ -411,9 +409,8 @@ define([
' float ai = czm_gl_FragColor.a;\n' +
' gl_FragColor = vec4(ai);\n';

function getTranslucentShaderProgram(context, shaderProgram, cache, source) {
var id = shaderProgram.id;
var shader = cache[id];
function getTranslucentShaderProgram(context, shaderProgram, keyword, source) {
var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, keyword);
if (!defined(shader)) {
var attributeLocations = shaderProgram._attributeLocations;

Expand Down Expand Up @@ -446,29 +443,26 @@ define([
source +
'}\n');

shader = ShaderProgram.fromCache({
context : context,
shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, keyword, {
vertexShaderSource : shaderProgram.vertexShaderSource,
fragmentShaderSource : fs,
attributeLocations : attributeLocations
});

cache[id] = shader;
}

return shader;
}

function getTranslucentMRTShaderProgram(oit, context, shaderProgram) {
return getTranslucentShaderProgram(context, shaderProgram, oit._translucentShaderCache, mrtShaderSource);
function getTranslucentMRTShaderProgram(context, shaderProgram) {
return getTranslucentShaderProgram(context, shaderProgram, 'translucentMRT', mrtShaderSource);
}

function getTranslucentColorShaderProgram(oit, context, shaderProgram) {
return getTranslucentShaderProgram(context, shaderProgram, oit._translucentShaderCache, colorShaderSource);
function getTranslucentColorShaderProgram(context, shaderProgram) {
return getTranslucentShaderProgram(context, shaderProgram, 'translucentMultipass', colorShaderSource);
}

function getTranslucentAlphaShaderProgram(oit, context, shaderProgram) {
return getTranslucentShaderProgram(context, shaderProgram, oit._alphaShaderCache, alphaShaderSource);
function getTranslucentAlphaShaderProgram(context, shaderProgram) {
return getTranslucentShaderProgram(context, shaderProgram, 'alphaMultipass', alphaShaderSource);
}

OIT.prototype.createDerivedCommands = function(command, context, result) {
Expand All @@ -487,7 +481,7 @@ define([
result.translucentCommand = DrawCommand.shallowClone(command, result.translucentCommand);

if (!defined(translucentShader) || result.shaderProgramId !== command.shaderProgram.id) {
result.translucentCommand.shaderProgram = getTranslucentMRTShaderProgram(this, context, command.shaderProgram);
result.translucentCommand.shaderProgram = getTranslucentMRTShaderProgram(context, command.shaderProgram);
result.translucentCommand.renderState = getTranslucentMRTRenderState(this, context, command.renderState);
result.shaderProgramId = command.shaderProgram.id;
} else {
Expand All @@ -510,9 +504,9 @@ define([
result.alphaCommand = DrawCommand.shallowClone(command, result.alphaCommand);

if (!defined(colorShader) || result.shaderProgramId !== command.shaderProgram.id) {
result.translucentCommand.shaderProgram = getTranslucentColorShaderProgram(this, context, command.shaderProgram);
result.translucentCommand.shaderProgram = getTranslucentColorShaderProgram(context, command.shaderProgram);
result.translucentCommand.renderState = getTranslucentColorRenderState(this, context, command.renderState);
result.alphaCommand.shaderProgram = getTranslucentAlphaShaderProgram(this, context, command.shaderProgram);
result.alphaCommand.shaderProgram = getTranslucentAlphaShaderProgram(context, command.shaderProgram);
result.alphaCommand.renderState = getTranslucentAlphaRenderState(this, context, command.renderState);
result.shaderProgramId = command.shaderProgram.id;
} else {
Expand Down Expand Up @@ -639,23 +633,6 @@ define([
this._adjustAlphaCommand.shaderProgram = this._adjustAlphaCommand.shaderProgram && this._adjustAlphaCommand.shaderProgram.destroy();
}

var name;
var cache = this._translucentShaderCache;
for (name in cache) {
if (cache.hasOwnProperty(name) && defined(cache[name])) {
cache[name].destroy();
}
}
this._translucentShaderCache = {};

cache = this._alphaShaderCache;
for (name in cache) {
if (cache.hasOwnProperty(name) && defined(cache[name])) {
cache[name].destroy();
}
}
this._alphaShaderCache = {};

return destroyObject(this);
};

Expand Down
Loading

0 comments on commit 7a0a6e7

Please sign in to comment.