Skip to content

Commit

Permalink
Support alpha in blend color
Browse files Browse the repository at this point in the history
  • Loading branch information
lilleyse committed Dec 5, 2016
1 parent bdc8425 commit 4bd0ad6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 9 deletions.
20 changes: 17 additions & 3 deletions Apps/Sandcastle/gallery/3D Models.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@
<input type="text" size="5" data-bind="value: blendColor">
</td>
</tr>
<tr>
<td>Blend Alpha</td>
<td>
<input type="range" min="0.0" max="1.0" step="0.01" data-bind="value: blendAlpha, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: blendAlpha">
</td>
</tr>
</tbody></table>

</div>
Expand All @@ -66,7 +73,8 @@
// The viewModel tracks the state of our mini application.
var viewModel = {
blendAmount : 0.0,
blendColor : 0.0
blendColor : 0.0,
blendAlpha : 1.0
};
// Convert the viewModel members into knockout observables.
Cesium.knockout.track(viewModel);
Expand All @@ -83,7 +91,13 @@

Cesium.knockout.getObservable(viewModel, 'blendColor').subscribe(
function(newValue) {
entity.model.blendColor = Cesium.Color.fromHsl(newValue, 1.0, 0.5);
entity.model.blendColor = Cesium.Color.fromHsl(newValue, 1.0, 0.5, viewModel.blendAlpha);
}
);

Cesium.knockout.getObservable(viewModel, 'blendAlpha').subscribe(
function(newValue) {
entity.model.blendColor = Cesium.Color.fromHsl(viewModel.blendColor, 1.0, 0.5, newValue);
}
);

Expand All @@ -106,7 +120,7 @@
minimumPixelSize : 128,
maximumScale : 20000,
blendAmount : viewModel.blendAmount,
blendColor : Cesium.Color.fromHsl(viewModel.blendColor, 1.0, 0.5)
blendColor : Cesium.Color.fromHsl(viewModel.blendColor, 1.0, 0.5, viewModel.blendAlpha)
}
});
viewer.trackedEntity = entity;
Expand Down
20 changes: 17 additions & 3 deletions Apps/Sandcastle/gallery/development/3D Models.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@
<input type="text" size="5" data-bind="value: blendColor">
</td>
</tr>
<tr>
<td>Blend Alpha</td>
<td>
<input type="range" min="0.0" max="1.0" step="0.01" data-bind="value: blendAlpha, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: blendAlpha">
</td>
</tr>
</tbody></table>

</div>
Expand All @@ -65,7 +72,8 @@
// The viewModel tracks the state of our mini application.
var viewModel = {
blendAmount : 0.0,
blendColor : 0.0
blendColor : 0.0,
blendAlpha : 1.0
};

// Convert the viewModel members into knockout observables.
Expand All @@ -83,7 +91,13 @@

Cesium.knockout.getObservable(viewModel, 'blendColor').subscribe(
function(newValue) {
model.blendColor = Cesium.Color.fromHsl(newValue, 1.0, 0.5);
entity.model.blendColor = Cesium.Color.fromHsl(newValue, 1.0, 0.5, viewModel.blendAlpha);
}
);

Cesium.knockout.getObservable(viewModel, 'blendAlpha').subscribe(
function(newValue) {
entity.model.blendColor = Cesium.Color.fromHsl(viewModel.blendColor, 1.0, 0.5, newValue);
}
);

Expand All @@ -106,7 +120,7 @@

model.readyPromise.then(function(model) {
model.blendAmount = viewModel.blendAmount;
model.blendColor = Cesium.Color.fromHsl(viewModel.blendColor, 1.0, 0.5);
model.blendColor = Cesium.Color.fromHsl(viewModel.blendColor, 1.0, viewModel.blendAlpha);
// Play and loop all animations at half-speed
model.activeAnimations.addAll({
speedup : 0.5,
Expand Down
30 changes: 27 additions & 3 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1739,15 +1739,28 @@ define([
return shader;
}

function modifyShaderForBlendColor(shader) {
function hasPremultipliedAlpha(model) {
var gltf = model.gltf;
return defined(gltf.asset) ? defaultValue(gltf.asset.premultipliedAlpha, false) : false;
}

function modifyShaderForBlendColor(shader, premultipliedAlpha) {
shader = ShaderSource.replaceMain(shader, 'gltf_blend_main');
shader +=
'uniform vec4 gltf_blendColor; \n' +
'uniform float gltf_blendAmount; \n' +
'void main() \n' +
'{ \n' +
' gltf_blend_main(); \n' +
' gltf_blend_main(); \n';

// Un-premultiply the alpha so that blending is correct.
if (premultipliedAlpha) {
shader += ' gl_FragColor.rgb /= gl_FragColor.a; \n';
}

shader +=
' gl_FragColor.rgb = mix(gl_FragColor.rgb, gltf_blendColor.rgb, gltf_blendAmount); \n' +
' gl_FragColor.a *= gltf_blendColor.a; \n' +
'} \n';
return shader;
}
Expand Down Expand Up @@ -1783,7 +1796,8 @@ define([
vs = modifyShaderForQuantizedAttributes(vs, id, model, context);
}

var blendFS = modifyShaderForBlendColor(fs);
var premultipliedAlpha = hasPremultipliedAlpha(model);
var blendFS = modifyShaderForBlendColor(fs, premultipliedAlpha);

var drawVS = modifyShader(vs, id, model._vertexShaderLoaded);
var drawFS = modifyShader(blendFS, id, model._fragmentShaderLoaded);
Expand Down Expand Up @@ -2319,6 +2333,16 @@ define([
var polygonOffset = defaultValue(statesFunctions.polygonOffset, [0.0, 0.0]);
var scissor = defaultValue(statesFunctions.scissor, [0.0, 0.0, 0.0, 0.0]);

// Change the render state to use traditional alpha blending instead of premultiplied alpha blending
if (booleanStates[WebGLConstants.BLEND] && hasPremultipliedAlpha(model)) {
if ((blendFuncSeparate[0] === WebGLConstants.ONE) && (blendFuncSeparate[1] === WebGLConstants.ONE_MINUS_SRC_ALPHA)) {
blendFuncSeparate[0] = WebGLConstants.SRC_ALPHA;
blendFuncSeparate[1] = WebGLConstants.ONE_MINUS_SRC_ALPHA;
blendFuncSeparate[2] = WebGLConstants.ONE;
blendFuncSeparate[3] = WebGLConstants.ONE_MINUS_SRC_ALPHA;
}
}

rendererRenderStates[id] = RenderState.fromCache({
frontFace : defined(statesFunctions.frontFace) ? statesFunctions.frontFace[0] : WebGLConstants.CCW,
cull : {
Expand Down

0 comments on commit 4bd0ad6

Please sign in to comment.