Цвета в THREE.WebGLRenderTarget с альфа-каналом темнее, чем ожидалось - PullRequest
0 голосов
/ 29 мая 2018

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

У меня проблема с альфа-смешиванием.Цвет, который я получаю, когда альфа = 0,5, темнее, чем ожидалось.

Изображение ниже показывает проблему:

Top: DIV with opacity=0.5; Bottom: WebGL

  • Круг сверху - это то, что я ожидаю.Это получается с помощью HTML DIV с более круглыми углами и непрозрачностью = 0,5
  • . Кружок снизу - это то, что я получаю с шейдером, который визуализирует окружность внутри текстуры.

Я думаю, что что-то упустил!

Часть кода описана ниже.Вы можете найти полный код в следующем jsbin: https://jsbin.com/zukoyaziqe/1/edit?html,js,output

Спасибо за вашу помощь !!

Шейдер:

const texFrag = `
varying vec2 vUv;
void main() {
  vec2 center = vec2(0.5, 0.2);
  float d = length(vUv - center);

  if (d < 0.1) {
    gl_FragColor = vec4(1.0,0.0,1.0,0.5);
  }
  else {
    discard;
  }
}
`;

Текстура:

const makeTexture = (renderer, width, height) => {
  const target   = new THREE.WebGLRenderTarget(width, height, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, type: THREE.FloatType});
  const scene    = new THREE.Scene();
  const camera   = new THREE.PerspectiveCamera(90, 1, 0.1, 100000);
  const geometry = new THREE.PlaneGeometry(2, 2);
  const material = new THREE.ShaderMaterial({
    transparent    : true,
    vertexShader   : simpleVert,
    fragmentShader : texFrag,
  });
  const mesh = new THREE.Mesh(geometry, material);

  camera.position.set(0, 0, 1);
  scene.add(camera);
  scene.add(mesh);

  renderer.render(scene, camera, target, true);

  return target.texture;
}

Основной вид:

const renderer = new THREE.WebGLRenderer({canvas});
const scene    = new THREE.Scene();
const camera   = new THREE.PerspectiveCamera(90, 1, 0.1, 100000);
const geometry = new THREE.PlaneGeometry( 2, 2 );
const material = new THREE.MeshBasicMaterial({
  transparent : true,
  map         : makeTexture(renderer, canvas.width, canvas.height)
});
const mesh = new THREE.Mesh(geometry, material);

1 Ответ

0 голосов
/ 29 мая 2018

Прежде всего, в примере, который вы связали, ваша основная функция вызывается дважды, поэтому два CSS-круга накладываются друг на друга, в результате чего получается менее прозрачный круг.

Затем вы 'повторное рисование круга с цветом (1,0,1,0.5) на пустой цели рендеринга, которая в режиме наложения по умолчанию (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) приводит к цвету (0,5,0,0,5,0,5), который затемиспользуется в качестве текстуры.Если вам нужен оригинальный цвет в вашей текстуре, вы должны отключить альфа-смешение или использовать другой режим наложения.Просто установив transparent в false внутри makeTexture, добьемся цели.

...