Three.js: RawShaderMaterial does not use opacity

Created on 23 Mar 2017  ·  3Comments  ·  Source: mrdoob/three.js

Description of the problem

RawShaderMaterial opacity is not used, even when the transparency flag is set. I have seen this issue in r84 & versions as far back as r78. I have mainly been using Chrome Version 56.0.2924.87 (64-bit), but saw this in Firefox for r84 as well. I expect my objects to use 50% opacity if the opacity in the RawShaderMaterial is set.

I have a test html page that shows the issue. Note that the opacity & transparency are passed into the RawShaderMaterial yet the points render as solid blue:

https://jsfiddle.net/jg4ta1po/

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.js"></script>
<style>
body { background-color: grey; }
#render canvas {border: 1px solid black; }
</style>

<div id="render"></div>

<script type="text/javascript">
    function drawDots(scene) {
        var vertices = new Float32Array( [-32, 0, 0, 32, 0, 0] );
        var geometry = new THREE.BufferGeometry();
        geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
        var shaders = {
            vertex: document.getElementById('rasterVertexShader').textContent,
            fragment: document.getElementById('rasterFragmentShader').textContent,
        };
        var material = new THREE.RawShaderMaterial({
            uniforms:       {},
            vertexShader:   shaders.vertex,
            fragmentShader: shaders.fragment,
            transparent:    true,
            depthTest:      false,
            opacity:         0.5,
        });
        material.side = THREE.DoubleSide;
        var mesh = new THREE.Points(geometry, material);
        mesh.frustumCulled = false;
        //TODO: Use groups
        scene.add(mesh);
    }

    function initRenderer() {
        var renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
        var div = document.getElementById('render');
        div.appendChild(renderer.domElement);
        var camera = new THREE.PerspectiveCamera(90, 1, 1, 1000);
        camera.position.z = 256;
        var scene = new THREE.Scene();
        //var dpr = window.devicePixelRatio ? window.devicePixelRatio : 1;
        //renderer.setPixelRatio(dpr);
        renderer.setSize(256, 256)
        camera.aspect = 1.0;
        camera.updateProjectionMatrix();
        return {
            renderer: renderer,
            scene: scene,
            camera: camera,
        }
    }

    document.addEventListener("DOMContentLoaded", function() {
        var renderer, scene, camera;
        var r = initRenderer();
        drawDots(r.scene);
        r.renderer.render(r.scene, r.camera);
    });

</script>

<script type="x-shader/x-vertex" id="rasterVertexShader">

attribute vec3 position;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

void main() {
  vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
  gl_Position = projectionMatrix * mvPosition;;
  gl_PointSize = 64.0;
}
</script>

<script type="x-shader/x-fragment" id="rasterFragmentShader">
void main() {
  gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
</script>
Three.js version
  • [x] r84

First noticed in r78, no data before that point.

Browser
  • [x] Chrome
  • [x] Firefox

Probably more

OS
  • [X] macOS

I believe I have seen this on Linux (Fedora) as well, but that was a while ago and not my computer.

Hardware Requirements (graphics card, VR Device, ...)

I don't believe it's significant, but I am running on MacBook Pro (Retina, 15-inch, Late 2013) while using discrete only graphics NVIDIA GeForce GT 750M.

Most helpful comment

Yeah, with a RawShaderMaterial you're on your own.

All 3 comments

@clawconduce I think it is just for use when you include parts of ShaderChunk/ShaderLib. It's true, there is no reference in RawShaderMaterial & ShaderMaterial. But it is used in Mater

What I found:

If you want to adjust opacity with RawShaderMaterial you should modify alpha channel in gl_FragColor inside your fragment shader

I see, thanks!

I think the docs could use some clarification. For example, "RawShaderMaterial( parameters )

parameters - (optional) an object with one or more properties defining the material's appearance. Any property of the material (including any property inherited from Material and ShaderMaterial) can be passed in here."

I'm not sure the best way to update those, I'd probably just add an exception. I could make the PR if that sounds OK.

I'm a little new to WebGL, so you'll have to excuse my terminology. Does this also mean that a Material's opacity is applied per vertex? If I put 50% opacity on the material, and have 2 overlapping points, where they overlap will the color have >50% opacity?

Yeah, with a RawShaderMaterial you're on your own.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

seep picture seep  ·  3Comments

zsitro picture zsitro  ·  3Comments

danieljack picture danieljack  ·  3Comments

filharvey picture filharvey  ·  3Comments

jack-jun picture jack-jun  ·  3Comments