2015-11-20 2 views
0

Я пытаюсь написать материал шейдера для отображения объектов TREE.Points() с закругленными точками. Я делаю это, контролируя альфа-значение в шейдере фрагментов.Alpha color with ShaderMaterial

Ниже приведена полностью работающая версия моего кода. Я получаю желаемый эффект только окрашивания пикселей внутри круга. Снаружи, однако, я получаю белый цвет вместо цвета фона.

Этот question связан с моим. Я попытался установить material.transparent = true, но это не повлияло.

<html> 
    <head> 
     <title>THREEJS alpha shader</title> 
     <style> 
      body { margin: 0; } 
      canvas { width: 100%; height: 100% } 
     </style> 
     <script type="text/javascript" src="http://threejs.org/build/three.min.js"></script> 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
    </head> 
    <body> 
     <!-- Shaders --> 
     <script type="x-shader/x-vertex" id="vertexshader"> 
      void main() { 
       gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 
       gl_PointSize = 40.0; // pixels 
      } 
     </script> 

     <script type="x-shader/x-fragment" id="fragmentshader"> 
      varying vec4 color; 

      void main() { 
       // radius 
       float r = length(gl_PointCoord - vec2(0.5, 0.5)); 

       if(r < 0.5) { 
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
       } else { 
        gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0); 
       } 
      } 
     </script> 

     <script> 
      var scene = new THREE.Scene(); 
      var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
      var renderer = new THREE.WebGLRenderer(); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      document.body.appendChild(renderer.domElement); 

      var buffer = new Float32Array(3); // single point located at (0, 0, 0) 
      var geometry = new THREE.BufferGeometry(); 
      geometry.addAttribute('position', new THREE.BufferAttribute(buffer,3)); 

      // create shader material 
      var material = new THREE.ShaderMaterial({ 
       vertexShader : $('#vertexshader').text(), 
       fragmentShader : $('#fragmentshader').text(), 
       }); 

      var point = new THREE.Points(geometry, material); 
      scene.add(point); 
      camera.position.z = 2; 

      var render = function() { 
       requestAnimationFrame(render); 
       renderer.render(scene, camera); 
      }; 
      render(); 
     </script> 
    </body> 
</html> 
+2

Ваш принятый ответ заключается не в том, как это сделать в three.js. Вместо того, чтобы устанавливать альфа-значение в ноль, выполните следующее: 'if (length (gl_PointCoord - vec2 (0.5, 0.5))> 0.475) discard;' – WestLangley

+0

В принятом ответе решена проблема включения альфа-смешивания для ShaderMaterial. Однако ваш код помог мне устранить странный рендеринг в углах. Благодарю. –

+1

Вы активируете альфа-смешивание в трёх.js, установив material.transparent = true; – WestLangley

ответ

1

Необходимо включить альфа-смешение в контексте OpenGL. Я не уверен, если есть способ сделать это с помощью three.js, но добавления этих GL команды рендеринга() функция будет достаточно:

var render = function() { 
    var gl = renderer.context; 
    gl.enable(gl.BLEND); 
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 
    requestAnimationFrame(render); 
    renderer.render(scene, camera); 
}; 

Смотрите документацию MDN на blendFunc для немного больше информации о это.