Альфа в шейдере фрагмента gl_FragColor не работает - PullRequest
2 голосов
/ 13 июня 2019

Я использую Three.js и ShaderMaterial для рисования геометрии точек с помощью шейдера фрагмента.

Я хочу, чтобы у каждой точки был размытый край, но я не могу заставить альфу работать, она просто становится белой.

Я могу отбросить пиксели, когда они полностью прозрачны, чтобы сделать круг, но размытие становится белым, а затем резко обрезается.

Вот что я вижу на экране: What I see on screen

код Three.JS

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

    var points = new THREE.Points(geometry, shaderMaterial);

Фрагмент шейдера:

//translate gl_PointCoord to be centered at 0,0
vec2 cxy = 2.0 * gl_PointCoord - 1.0;

//calculate alpha based on distance from centre
//(I'm doubling it to get a less gradual fade) 
float newAlpha = (1.0-distance(cxy, vec2(0.0,0.0))) * 2.0;

if (newAlpha < 0.01)
{
    //discard pixels that have ~0 alpha
    discard;
}

gl_FragColor = vec4( newR, newG, newB, newAlpha);

Заранее благодарен за любую помощь :) Меня это озадачивает для AGES.

Редактировать: Включение и выключение изображений глубины. Мне кажется, что тест глубины помещает их в правильном порядке?

deepTest false: depthTest:false

deepTest true: depthTest:true

1 Ответ

1 голос
/ 14 июня 2019

В вашем примере JSFiddle есть несколько случаев, когда он сражается сам с собой.Вы пытаетесь установить режим смешивания материала в Three.js, но затем вы переопределяете это с помощью:

var gl = renderer.context;
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

Вы запрашиваете animationFrame, но затем делаете внутри него setTimeout, удаляявсе преимущества использования animationFrame.

Мне удалось кое-что немного улучшить с помощью

blending: THREE.NormalBlending,
transparent: true,
depthWrite: false,
depthTest: true

Исправления можно посмотреть здесь: https://jsfiddle.net/yxj8zvmp/

.... хотя в вашу геометрию передается слишком много атрибутов и униформ, чтобы действительно понять, почему глубина не работает должным образом.Почему вы передаете u_camera, когда у вас уже есть cameraPosition , а ваш атрибут position имеет длину 1?Это похоже на смесь сырого WebGL, сражающегося с Three.js.

...