Select to view content in your preferred language

How to make material opacity and transparent in ExternalRenderer with three.js?

7742
2
Jump to solution
10-21-2019 09:07 PM
zhiminzhang
Occasional Contributor

Hello, I am doing some webgl extensions with three.js following the ExternalRenderer sample,  I have created a CustomRenderer like this:

public setup(context: __esri.RenderContext): void {
    // Setup webgl renderer
    this.renderer = new WebGLRenderer({
        context: context.gl,
        alpha: true,
        antialias: true
    });
    this.renderer.autoClear = false;
    // this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setViewport(0, 0, this.view.width, this.view.height);
    this.scene = new Scene();
    this.camera = new PerspectiveCamera();
}

Then load a texture from a url, and add it to scene, the code looks like this:

const extent = this.properties.extent;
const elevation = this.properties.elevation;
const unit = Math.PI / 180.0 * (EarthRadius + elevation);
const width = (extent.xmax - extent.xmin) * unit;
const height = (extent.ymax - extent.ymin) * unit;
const segs = 36;
const geometry = new PlaneBufferGeometry(width, height, segs, segs);
const textureLoader = new TextureLoader();

const texture = textureLoader.load(this.properties.url);

const material = new MeshBasicMaterial({
    // color: 0xffff00,
    map: texture,
    wireframe: false,
    opacity: 0.5,
    transparent: true,
    alphaTest: 0.05,
    side: DoubleSide
});
this.plane = new Mesh(geometry, material);
const srcCoord = [
    (extent.xmin + extent.xmax) / 2,
    (extent.ymin + extent.ymax) / 2,
    elevation
];
const destCoord = [0, 0, 0];
externalRenderers.toRenderCoordinates(
    this.view,
    srcCoord,
    0,
    SpatialReference.WGS84,
    destCoord,
    0,
    1
);
const transform = new Matrix4();
transform.fromArray(
    externalRenderers.renderCoordinateTransformAt(
        this.view,
        srcCoord,
        SpatialReference.WGS84,
        new Float32Array(16)
    )
);
transform.decompose(
    this.plane.position,
    this.plane.quaternion,
    this.plane.scale
);
this.scene.add(this.plane);

I have set transparent to true, and opacity to 0.5 , but the texture loaded looks not transparent, but it it looks transparent in three.js.

So, how to make texture loaded transparent in external renderer?

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
zhiminzhang
Occasional Contributor

Finally I get the magic, enable alpha blend before render, it is disabled by arcgis js api

protected beforeRender(context: __esri.RenderContext): void {
    super.beforeRender(context);
    const opacity = this.props.opacity;
    if (this.isTransparent()) {
        const gl = context.gl;
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.NONE, gl.ONE_MINUS_SRC_ALPHA);
    }
}

View solution in original post

0 Kudos
2 Replies
zhiminzhang
Occasional Contributor

I have built a demo with three.js on stackbliz , with pure three.js, make things transparent is easy, just set the transparent property  MeshBasicMaterial to true , and set opacity property to less then 1.0 , the result looks like this:

But set the transparent and opaticy properties does not work in an ExternalRenderer of SceneView, can not make things transparent and opaque.

0 Kudos
zhiminzhang
Occasional Contributor

Finally I get the magic, enable alpha blend before render, it is disabled by arcgis js api

protected beforeRender(context: __esri.RenderContext): void {
    super.beforeRender(context);
    const opacity = this.props.opacity;
    if (this.isTransparent()) {
        const gl = context.gl;
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.NONE, gl.ONE_MINUS_SRC_ALPHA);
    }
}
0 Kudos