Skip to content

Commit

Permalink
Merge pull request #284 from AnalyticalGraphicsInc/diffuse-texture-al…
Browse files Browse the repository at this point in the history
…pha-fix

Fix issue with transparent diffuse texture setting the technique state
  • Loading branch information
pjcozzi authored May 25, 2017
2 parents 45f1bb8 + 1a76402 commit 3449df8
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 24 deletions.
70 changes: 51 additions & 19 deletions lib/addDefaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,45 @@ function addDefaultTechnique(gltf) {
}
}

function isTechniqueShared(gltf, techniqueId) {
var referenced = false;
var materials = gltf.materials;
for (var materialId in materials) {
if (materials.hasOwnProperty(materialId)) {
var material = materials[materialId];
if (material.technique === techniqueId) {
if (referenced) {
return true;
}
referenced = true;
}
}
}
return false;
}

function makeTechniqueTransparent(technique) {
technique.states = {
enable: [
WebGLConstants.DEPTH_TEST,
WebGLConstants.BLEND
],
depthMask: false,
functions: {
blendEquationSeparate: [
WebGLConstants.FUNC_ADD,
WebGLConstants.FUNC_ADD
],
blendFuncSeparate: [
WebGLConstants.ONE,
WebGLConstants.ONE_MINUS_SRC_ALPHA,
WebGLConstants.ONE,
WebGLConstants.ONE_MINUS_SRC_ALPHA
]
}
};
}

function enableDiffuseTransparency(gltf) {
var materials = gltf.materials;
var techniques = gltf.techniques;
Expand All @@ -364,30 +403,23 @@ function enableDiffuseTransparency(gltf) {
diffuseTransparent = diffuse[3] < 1.0;
}

var technique = techniques[material.technique];
var techniqueId = material.technique;
var technique = techniques[techniqueId];
var blendingEnabled = technique.states.enable.indexOf(WebGLConstants.BLEND) > -1;

// Override the technique's states if blending isn't already enabled
if (diffuseTransparent && !blendingEnabled) {
technique.states = {
enable: [
WebGLConstants.DEPTH_TEST,
WebGLConstants.BLEND
],
depthMask: false,
functions: {
blendEquationSeparate: [
WebGLConstants.FUNC_ADD,
WebGLConstants.FUNC_ADD
],
blendFuncSeparate: [
WebGLConstants.ONE,
WebGLConstants.ONE_MINUS_SRC_ALPHA,
WebGLConstants.ONE,
WebGLConstants.ONE_MINUS_SRC_ALPHA
]
if (isTechniqueShared(gltf, techniqueId)) {
var transparentTechniqueId = techniqueId + '_transparent';
if (!defined(techniques[transparentTechniqueId])) {
technique = clone(technique, true);
makeTechniqueTransparent(technique);
gltf.techniques[transparentTechniqueId] = technique;
}
};
material.technique = transparentTechniqueId;
} else {
makeTechniqueTransparent(technique);
}
}
}
}
Expand Down
41 changes: 36 additions & 5 deletions specs/lib/addDefaultsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
var Cesium = require('cesium');
var clone = require('clone');
var fsExtra = require('fs-extra');
var Promise = require('bluebird');

var WebGLConstants = Cesium.WebGLConstants;

Expand All @@ -12,7 +11,8 @@ var loadGltfUris = require('../../lib/loadGltfUris');
var readGltf = require('../../lib/readGltf');
var removePipelineExtras = require('../../lib/removePipelineExtras');

var transparentImageUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AcGERIfpcOGjwAAAQZJREFUGNMFwcErQ3EAwPHv7+3JEw2FFe+lZ9vpTTnYiR2MsyKuE8VB/ojdlZuDg4sVyUU7TVK7KG05jFgWPdt6oqWI5/E87/l8RNO8zyoylF4EtTeB6wWMhH2mNMG3B3KHDMemxOFdQEj4qN3tPDoS9Q+HxaiPdNkS5G5+SUV1xoYG6VNcRvvh9ClMS+hIZ6aLocZY0M+Zj1X59CMcXXmsJUO4dh7Z0HTiEZvN3DQDvcNk5mrYyU5q5SUK1QuktGpxkE/x8OpSaVqUSxt81bfYKewxkVhF9h1BjxJHyBW84I/dk23ebVieWWF2fB1hNZ6zSlsXxdt9rhtFgsDH0CZJJzK43g//gYBjzrZ4jf0AAAAASUVORK5CYII=';
var opaqueImageUri = './specs/data/boxTexturedUnoptimized/Cesium_Logo_Flat.jpg';
var transparentImageUri = './specs/data/boxTexturedUnoptimized/Cesium_Logo_Flat_Transparent.png';
var gltfTransparentPath = './specs/data/boxTexturedUnoptimized/CesiumTexturedBoxTestTransparent.gltf';

describe('addDefaults', function() {
Expand Down Expand Up @@ -155,6 +155,13 @@ describe('addDefaults', function() {
}
};

var opaqueBlendState = {
enable : [
WebGLConstants.CULL_FACE,
WebGLConstants.DEPTH_TEST
]
};

it('generates a material with alpha blending if the diffuse texture is transparent and no technique or extension values are given', function(done) {
var gltf = {
"textures": {
Expand All @@ -165,12 +172,24 @@ describe('addDefaults', function() {
"source": "Image0001",
"target": 3553,
"type": 5121
},
"texture0002": {
"format": 6408,
"internalFormat": 6408,
"sampler": "sampler_0",
"source": "Image0002",
"target": 3553,
"type": 5121
}
},
"images": {
"Image0001": {
"name": "Image0001",
"uri": transparentImageUri
},
"Image0002": {
"name": "Image0002",
"uri": opaqueImageUri
}
},
"materials": {
Expand All @@ -180,16 +199,28 @@ describe('addDefaults', function() {
"diffuse": "texture0001",
"emission": [1, 0, 0, 1]
}
},
"material2": {
"values": {
"ambient": [0, 0, 0, 1],
"diffuse": "texture0002",
"emission": [1, 0, 0, 1]
}
}
}
};

var options = {
basePath : './'
};
addPipelineExtras(gltf);
expect(loadGltfUris(gltf)
expect(loadGltfUris(gltf, options)
.then(function() {
addDefaults(gltf);
var technique = gltf.techniques[Object.keys(gltf.techniques)[0]];
expect(technique.states).toEqual(alphaBlendState);
var techniqueOpaque = gltf.techniques[Object.keys(gltf.techniques)[0]];
var techniqueAlpha = gltf.techniques[Object.keys(gltf.techniques)[1]];
expect(techniqueAlpha.states).toEqual(alphaBlendState);
expect(techniqueOpaque.states).toEqual(opaqueBlendState);
}), done).toResolve();
});

Expand Down

0 comments on commit 3449df8

Please sign in to comment.