-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Color blend mode support for vertex shaders #5874
Closed
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
c85a838
Doc clarification for color blend mode when feature is white
lilleyse ec154ca
Support tileset.colorBlendMode of REPLACE or MIX with uniforms in ver…
lilleyse 65cf58b
Updated CHANGES.md
lilleyse 3c80aff
Slight reorganization / renaming
lilleyse b2fa293
Look for semantic by programId
lilleyse 83bb864
Merge branch 'master' into color-blend-mode-doc
lilleyse File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -846,14 +846,16 @@ define([ | |
'} \n'; | ||
} | ||
|
||
Cesium3DTileBatchTable.prototype.getVertexShaderCallback = function(handleTranslucent, batchIdAttributeName) { | ||
Cesium3DTileBatchTable.prototype.getVertexShaderCallback = function(handleTranslucent, batchIdAttributeName, diffuseUniformName) { | ||
if (this.featuresLength === 0) { | ||
return; | ||
} | ||
|
||
var that = this; | ||
return function(source) { | ||
var renamedSource = ShaderSource.replaceMain(source, 'tile_main'); | ||
// If the color blend mode is HIGHLIGHT, the highlight color will always be applied in the fragment shader. | ||
// No need to apply the highlight color in the vertex shader as well. | ||
var renamedSource = modifyDiffuse(source, diffuseUniformName, false); | ||
var newMain; | ||
|
||
if (ContextLimits.maximumVertexTextureImageUnits > 0) { | ||
|
@@ -867,9 +869,9 @@ define([ | |
'varying vec4 tile_featureColor; \n' + | ||
'void main() \n' + | ||
'{ \n' + | ||
' tile_main(); \n' + | ||
' vec2 st = computeSt(' + batchIdAttributeName + '); \n' + | ||
' vec4 featureProperties = texture2D(tile_batchTexture, st); \n' + | ||
' tile_color(featureProperties); \n' + | ||
' float show = ceil(featureProperties.a); \n' + // 0 - false, non-zeo - true | ||
' gl_Position *= show; \n'; // Per-feature show/hide | ||
if (handleTranslucent) { | ||
|
@@ -894,11 +896,12 @@ define([ | |
' tile_featureColor = featureProperties; \n' + | ||
'}'; | ||
} else { | ||
// When VTF is not supported, color blend mode MIX will look incorrect due to the feature's color not being available in the vertex shader | ||
newMain = | ||
'varying vec2 tile_featureSt; \n' + | ||
'void main() \n' + | ||
'{ \n' + | ||
' tile_main(); \n' + | ||
' tile_color(vec4(1.0)); \n' + | ||
' tile_featureSt = computeSt(' + batchIdAttributeName + '); \n' + | ||
'}'; | ||
} | ||
|
@@ -907,21 +910,35 @@ define([ | |
}; | ||
}; | ||
|
||
function getHighlightOnlyShader(source) { | ||
function getDefaultShader(source, applyHighlight) { | ||
source = ShaderSource.replaceMain(source, 'tile_main'); | ||
|
||
if (!applyHighlight) { | ||
return source + | ||
'void tile_color(vec4 tile_featureColor) \n' + | ||
'{ \n' + | ||
' tile_main(); \n' + | ||
'} \n'; | ||
} | ||
|
||
// The color blend mode is intended for the RGB channels so alpha is always just multiplied. | ||
// gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) | ||
return source + | ||
'uniform float tile_colorBlend; \n' + | ||
'void tile_color(vec4 tile_featureColor) \n' + | ||
'{ \n' + | ||
' tile_main(); \n' + | ||
' gl_FragColor *= tile_featureColor; \n' + | ||
' gl_FragColor.a *= tile_featureColor.a; \n' + | ||
' float highlight = ceil(tile_colorBlend); \n' + | ||
' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n' + | ||
'} \n'; | ||
} | ||
|
||
function modifyDiffuse(source, diffuseUniformName) { | ||
// If the glTF does not specify the _3DTILESDIFFUSE semantic, return a basic highlight shader. | ||
function modifyDiffuse(source, diffuseUniformName, applyHighlight) { | ||
// If the glTF does not specify the _3DTILESDIFFUSE semantic, return the default shader. | ||
// Otherwise if _3DTILESDIFFUSE is defined prefer the shader below that can switch the color mode at runtime. | ||
if (!defined(diffuseUniformName)) { | ||
return getHighlightOnlyShader(source); | ||
return getDefaultShader(source, applyHighlight); | ||
} | ||
|
||
// Find the diffuse uniform. Examples matches: | ||
|
@@ -932,7 +949,7 @@ define([ | |
|
||
if (!defined(uniformMatch)) { | ||
// Could not find uniform declaration of type vec3, vec4, or sampler2D | ||
return getHighlightOnlyShader(source); | ||
return getDefaultShader(source, applyHighlight); | ||
} | ||
|
||
var declaration = uniformMatch[0]; | ||
|
@@ -946,16 +963,20 @@ define([ | |
// Replace: tile_colorBlend is 1.0 and the tile color is used | ||
// Mix: tile_colorBlend is between 0.0 and 1.0, causing the source color and tile color to mix | ||
var finalDiffuseFunction = | ||
'bool isWhite(vec3 color) \n' + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this because I noticed the |
||
'{ \n' + | ||
' return all(greaterThan(color, vec3(1.0 - czm_epsilon3))); \n' + | ||
'} \n' + | ||
'vec4 tile_diffuse_final(vec4 sourceDiffuse, vec4 tileDiffuse) \n' + | ||
'{ \n' + | ||
' vec4 blendDiffuse = mix(sourceDiffuse, tileDiffuse, tile_colorBlend); \n' + | ||
' vec4 diffuse = (tileDiffuse.rgb == vec3(1.0)) ? sourceDiffuse : blendDiffuse; \n' + | ||
' vec4 diffuse = isWhite(tileDiffuse.rgb) ? sourceDiffuse : blendDiffuse; \n' + | ||
' return vec4(diffuse.rgb, sourceDiffuse.a); \n' + | ||
'} \n'; | ||
|
||
// The color blend mode is intended for the RGB channels so alpha is always just multiplied. | ||
// gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) | ||
var applyHighlight = | ||
var highlight = | ||
' gl_FragColor.a *= tile_featureColor.a; \n' + | ||
' float highlight = ceil(tile_colorBlend); \n' + | ||
' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n'; | ||
|
@@ -971,7 +992,10 @@ define([ | |
' tile_diffuse = tile_diffuse_final(source, tile_featureColor); \n' + | ||
' tile_main(); \n'; | ||
} else if (type === 'sampler2D') { | ||
regex = new RegExp('texture2D\\(' + diffuseUniformName + '.*?\\)', 'g'); | ||
// Regex handles up to one level of nested parentheses: | ||
// E.g. texture2D(u_diffuse, uv) | ||
// E.g. texture2D(u_diffuse, computeUV(index)) | ||
regex = new RegExp('texture2D\\(' + diffuseUniformName + '.*?(\\)\\)|\\))', 'g'); | ||
source = source.replace(regex, 'tile_diffuse_final($&, tile_diffuse)'); | ||
setColor = | ||
' tile_diffuse = tile_featureColor; \n' + | ||
|
@@ -986,9 +1010,13 @@ define([ | |
source + '\n' + | ||
'void tile_color(vec4 tile_featureColor) \n' + | ||
'{ \n' + | ||
setColor + | ||
applyHighlight + | ||
'} \n'; | ||
setColor; | ||
|
||
if (applyHighlight) { | ||
source += highlight; | ||
} | ||
|
||
source += '} \n'; | ||
|
||
return source; | ||
} | ||
|
@@ -998,7 +1026,7 @@ define([ | |
return; | ||
} | ||
return function(source) { | ||
source = modifyDiffuse(source, diffuseUniformName); | ||
source = modifyDiffuse(source, diffuseUniformName, true); | ||
if (ContextLimits.maximumVertexTextureImageUnits > 0) { | ||
// When VTF is supported, per-feature show/hide already happened in the fragment shader | ||
source += | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A diff marker slipped through here.