Прозрачность Screendoor может использоваться для создания стабильного перекрытия прозрачности между кадрами, но имеет несколько артефактов, которые могут быть нежелательны.Суть этой техники заключается в отбрасывании пикселей в шаблоне пространства экрана в зависимости от того, насколько непрозрачным должен быть объект.Шаблон может быть получен из текстуры или сгенерирован в шейдере.Фрагменты, которые не отброшены, все еще записывают в глубину, и альфа-смешение не используется.
Вот небольшой код для начала работы.
Создание DataTexture с помощьюшаблон дизеринга:
const data = new Float32Array(16);
data[0] = 1.0 / 17.0;
data[1] = 9.0 / 17.0;
data[2] = 3.0 / 17.0;
data[3] = 11.0 / 17.0;
data[4] = 13.0 / 17.0;
data[5] = 5.0 / 17.0;
data[6] = 15.0 / 17.0;
data[7] = 7.0 / 17.0;
data[8] = 4.0 / 17.0;
data[9] = 12.0 / 17.0;
data[10] = 2.0 / 17.0;
data[11] = 10.0 / 17.0;
data[12] = 16.0 / 17.0;
data[13] = 8.0 / 17.0;
data[14] = 14.0 / 17.0;
data[15] = 6.0 / 17.0;
ditherTex = new THREE.DataTexture(data, 4, 4, THREE.LuminanceFormat, THREE.FloatType);
ditherTex.minFilter = THREE.NearestFilter;
ditherTex.magFilter = THREE.NearestFilter;
ditherTex.anisotropy = 1;
ditherTex.wrapS = THREE.RepeatWrapping;
ditherTex.wrapT = THREE.RepeatWrapping;
И некоторый код шейдера для отбрасывания фрагментов по:
// ...
uniform sampler2D ditherTex;
void main() {
// ...
// get the color of the surface and discard pixels based on the dither pattern
vec4 texColor = texture2D(diffuseTex, vUv);
vec4 color = texColor * vec4(color.rgb, opacity);
if(texture2D(ditherTex, gl_FragCoord.xy / 4.0).r > color.a) discard;
// ...
}
Вы захотите установить для текстуры данных униформу ditherTex
, используемую в шейдере,Вы также можете использовать другую текстуру, если вы хотите использовать что-то стилизованное или менее регулярное.
И, наконец, некоторые вещи, которые следует иметь в виду:
Непрозрачность текстуры должнаиспользовать при сравнении с текстурой дизеринга.
Артефакты дверцы экрана могут быть смягчены с помощью некоторых методов сглаживания для смешивания окружающих пикселей.
Material.transparent
должно быть false
.
Поскольку фрагменты не являются смешанными объектами с одинаковой непрозрачностью, они не будут иметь видимого перекрытия.
Надеемся, чтопомогает!Дайте мне знать, если у вас есть другие вопросы.