Shading and alpha issues with entities and primitives

I am trying to create overlapping rectangles in the sky that have partially transparent textures. If I try to create them using entities, the transparency works perfectly but there are abrupt shading changes (i.e. the rectangles get a lot darker when the camera is pointed directly at them).

On the other hand, if I try to create the rectangles as primitives and set faceForward to false in the appearance options (which seems to fix the shading/lighting issue), then there is a different problem--the transparency of one rectangle will overwrite other rectangles behind it. I suspect this could be fixed by either tweaking whichever of the shader sources primitives use by default, or by changing some alpha blending function option in a renderState that I'd pass into the primitive appearance. But I don't really know specifically what I should change in the shader or render state. Any pointers?

Paste to Sandcastle to see issue:

var viewer = new Cesium.Viewer('cesiumContainer', {
        'timeline': false,
        'animation': false,
        'homeButton': false,
        'geocoder': false,
        'fullscreenButton': false,
        'searchButton': false,
        'scene3DOnly': false,
  'orderIndependentTranslucency': false, // this does not appear to make a difference in this case
  'terrainShadows': Cesium.ShadowMode.DISABLED,
        'navigationHelpButton': false,
        'selectionIndicator': false,
  'sceneModePicker': false,
        'infoBox': false,
        'baseLayerPicker': false,
        'shadows': false,
});

viewer.camera.position = new Cesium.Cartesian3(-5077718.912198819, 3502183.4223716888, 1623436.7903385134);
viewer.camera.setView({
            orientation: {
                roll: 0.5073851418388697,
                heading: 2.120649161455434,
                pitch: 0.17861047868488078
            }
            });

function createRect (w, s, e, n, h) {
    return viewer.entities.add({
                 rectangle: {
                     coordinates: Cesium.Rectangle.fromDegrees(w,s,e,n),
                     height: h,
                     material: new Cesium.ImageMaterialProperty({
                         image: '../images/Cesium_Logo_overlay.png',
                         repeat : new Cesium.Cartesian2(1, 1),
                         transparent: true
                     })
                 }
    });
}

function createRectPrimitive (w, s, e, n, h) {
    var rectangleInstance = new Cesium.GeometryInstance({
            geometry : new Cesium.RectangleGeometry({
                rectangle : Cesium.Rectangle.fromDegrees(w,s,e,n),
                height: h,
            })
        });
        var prim = new Cesium.Primitive({
            geometryInstances: rectangleInstance,
            appearance: new Cesium.MaterialAppearance({
                material : Cesium.Material.fromType("Image", {
                    image: '../images/Cesium_Logo_overlay.png',
                    repeat : new Cesium.Cartesian2(1, 1),
                }),
                faceForward : false,
                translucent: true
            })
        });
        viewer.scene.primitives.add(prim);
}

var option1 = 1;
var option2 = 2;
var currentDisplayed = option1;

// option1: create rects as entities (shading/lighting glitch)
if (currentDisplayed === option1) {
    createRect (145.55805556, 14.66000000, 145.64861111, 14.73583333, 9000);
    createRect (145.61083333, 14.70638889, 145.70500000, 14.75007778, 9002);
}

// option2: create rects as primitives (alpha glitch)
else if (currentDisplayed === option2) {
    createRectPrimitive (145.55805556, 14.66000000, 145.64861111, 14.73583333, 9000);
    createRectPrimitive (145.61083333, 14.70638889, 145.70500000, 14.75007778, 9002);
}

I’m not sure about the faceFowards and how it affects lighting for rectangles, so I can’t really answer about the entity case.

But after digging around a bit for the primitive case it looks like the translucent property of MaterialAppearance only affects the render state but does not put the primitive in the translucent pass. Only when the material is determined to have translucency does it work. My hacked up solution is to add a slight alpha to the material color:

material : Cesium.Material.fromType(“Image”, {

image: ‘…/images/Cesium_Logo_overlay.png’,

repeat : new Cesium.Cartesian2(1, 1),

color: new Cesium.Color(1.0, 1.0, 1.0, 0.99)

}),

``

Also https://github.com/AnalyticalGraphicsInc/cesium/issues/2484 has another example.

Yep, that seems to do the trick. Thanks!