最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Three JS transparancy with ShaderMaterial - Stack Overflow

programmeradmin11浏览0评论

I'm drawing two geometries next to each other and have them rotate. The problem is that the first drawn one is obstructing the second one, where transparency should take effect. The two objects should have the same transparency, regardless of who was drawn first. That's why blending is turned on and depth test is off. Here are the images:

Both geometries are point cloud using THREE.ShaderMaterial as followed:

var shaderMaterial = new THREE.ShaderMaterial({
                uniforms: uniforms,
                attributes: attributes,
                vertexShader: document.getElementById('vertexshader').textContent,
                fragmentShader: document.getElementById('fragmentshader').textContent,
                blending: THREE.NormalBlending,
                depthTest: false,
                transparent: true
            });

where

// attributes
attributes = {
                size: { type: 'f', value: null },
                alpha: { type: 'f', value: [] },
                customColor: { type: 'c', value: null }
            };

 // uniforms
uniforms = {
             color: { type: "c", value: new THREE.Color(0x00ff00) },
             texture: { type: "t", value: THREE.ImageUtils.loadTexture("../textures/sprites/circle.png") }
            };

and

<script type="x-shader/x-vertex" id="vertexshader">
        attribute float alpha;
        attribute float size;
        attribute vec3 customColor;        
        varying float vAlpha;
        varying vec3 vColor;
        void main() {
        vAlpha = alpha;
        vColor = customColor;
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_PointSize =  size * ( 120.0 / length( mvPosition.xyz ));
        gl_Position = projectionMatrix * mvPosition;
        }
    </script>
<script type="x-shader/x-fragment" id="fragmentshader">
        uniform vec3 color;
        uniform sampler2D texture;
        varying float vAlpha;
        varying vec3 vColor;
        void main() {
        gl_FragColor = vec4( vColor, vAlpha );
        gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
        }
    </script>

I'm drawing two geometries next to each other and have them rotate. The problem is that the first drawn one is obstructing the second one, where transparency should take effect. The two objects should have the same transparency, regardless of who was drawn first. That's why blending is turned on and depth test is off. Here are the images:

Both geometries are point cloud using THREE.ShaderMaterial as followed:

var shaderMaterial = new THREE.ShaderMaterial({
                uniforms: uniforms,
                attributes: attributes,
                vertexShader: document.getElementById('vertexshader').textContent,
                fragmentShader: document.getElementById('fragmentshader').textContent,
                blending: THREE.NormalBlending,
                depthTest: false,
                transparent: true
            });

where

// attributes
attributes = {
                size: { type: 'f', value: null },
                alpha: { type: 'f', value: [] },
                customColor: { type: 'c', value: null }
            };

 // uniforms
uniforms = {
             color: { type: "c", value: new THREE.Color(0x00ff00) },
             texture: { type: "t", value: THREE.ImageUtils.loadTexture("../textures/sprites/circle.png") }
            };

and

<script type="x-shader/x-vertex" id="vertexshader">
        attribute float alpha;
        attribute float size;
        attribute vec3 customColor;        
        varying float vAlpha;
        varying vec3 vColor;
        void main() {
        vAlpha = alpha;
        vColor = customColor;
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_PointSize =  size * ( 120.0 / length( mvPosition.xyz ));
        gl_Position = projectionMatrix * mvPosition;
        }
    </script>
<script type="x-shader/x-fragment" id="fragmentshader">
        uniform vec3 color;
        uniform sampler2D texture;
        varying float vAlpha;
        varying vec3 vColor;
        void main() {
        gl_FragColor = vec4( vColor, vAlpha );
        gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
        }
    </script>
Share Improve this question asked Jan 18, 2015 at 15:41 Eyal ShachamEyal Shacham 1391 gold badge1 silver badge7 bronze badges 10
  • Try material.alphaTest = 0.5. If that does not work, can you provide a simple live link? – WestLangley Commented Jan 18, 2015 at 16:59
  • Where do I add the material.alphaTest = 0.5 to? – Eyal Shacham Commented Jan 18, 2015 at 17:29
  • 2 Sorry. Since you are are using ShaderMaterial, you have to handle that yourself: if ( gl_FragColor.a < 0.5 ) discard; – WestLangley Commented Jan 18, 2015 at 17:39
  • Thanks, but this change just discards some vertices, making the object more see-thru like as the point cloud objects are less 'crowded'. – Eyal Shacham Commented Jan 18, 2015 at 22:37
  • Where would I host it? Do you know of a site where I can upload the code? Thanks! – Eyal Shacham Commented Jan 24, 2015 at 18:54
 |  Show 5 more comments

1 Answer 1

Reset to default 14

Example code with 2 textures, but can be made to work with one as well:

<script id="fragmentShaderLoader" type="x-shader/x-fragment">
        uniform float percent;

        uniform sampler2D texture1;
        uniform sampler2D texture2;

        varying vec2 vUv;

        void main() {
            gl_FragColor = texture2D( texture1, vUv);
            vec4 tex2 = texture2D( texture2, vUv );
            if(tex2.a - percent < 0.0) {
                gl_FragColor.a = 0.0;
                //or without transparent = true use
                //discard; 
            }

        }

    </script>

    <script id="vertexShaderLoader" type="x-shader/x-vertex">
        varying vec2 vUv;

        void main()
        {
            vUv = uv;

            vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
            gl_Position = projectionMatrix * mvPosition;
        }
    </script>

Then for init:

uniformsMove = {
                    percent: { type: "f", value: 1.0 },
                    texture1: { type: "t", value: (new THREE.TextureLoader()).load( "govr/loader-test.png" ) },
                    texture2: { type: "t", value: (new THREE.TextureLoader()).load( "govr/loader-mask2.png" ) } 
                };

            material = new THREE.ShaderMaterial( {
                uniforms: uniformsMove,
                vertexShader: document.getElementById( 'vertexShaderLoader' ).textContent,
                fragmentShader: document.getElementById( 'fragmentShaderLoader' ).textContent

            } );
material.transparent = true;
发布评论

评论列表(0)

  1. 暂无评论