DataTexture: текстура из массива данных

DataTexture в Three.js представляет собой текстуру, создаваемую напрямую из массива данных. В отличие от стандартных текстур, загружаемых из изображений (TextureLoader), DataTexture позволяет работать с произвольными числовыми значениями пикселей, что делает её крайне полезной для визуализации научных данных, процедурных текстур и вычислительных шейдеров.

Создание DataTexture требует указания:

  • данных — массив типа Uint8Array, Float32Array или Uint16Array;
  • ширины и высоты текстуры;
  • формата пикселя — например, THREE.RGBAFormat или THREE.LuminanceFormat;
  • типа данныхTHREE.UnsignedByteType, THREE.FloatType и т.д.

Простейший пример создания текстуры из массива байтов:

const width = 256;
const height = 256;
const size = width * height * 4; // RGBA
const data = new Uint8Array(size);

for (let i = 0; i < size; i += 4) {
    data[i] = Math.random() * 255;     // R
    data[i + 1] = Math.random() * 255; // G
    data[i + 2] = Math.random() * 255; // B
    data[i + 3] = 255;                 // A
}

const texture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);
texture.needsUpdate = true;

Ключевой момент: необходимо устанавливать needsUpdate = true после изменения данных, иначе текстура не обновится на GPU.


Выбор формата и типа данных

DataTexture поддерживает различные комбинации формата и типа:

  • Формат пикселя (format):

    • THREE.LuminanceFormat — серый оттенок (1 компонент);
    • THREE.RGBFormat — красный, зелёный, синий;
    • THREE.RGBAFormat — полный RGBA;
    • THREE.RedFormat — только один канал (для WebGL2).
  • Тип данных (type):

    • THREE.UnsignedByteType — стандартный диапазон 0–255;
    • THREE.FloatType — значения с плавающей точкой, требуется включение расширения OES_texture_float для WebGL1;
    • THREE.HalfFloatType — половинная точность (16 бит), экономит память;
    • THREE.UnsignedShortType — 16-битное целое без знака.

Важно учитывать, что не все типы и форматы совместимы друг с другом и с конкретными платформами. Например, FloatType в WebGL1 требует наличие расширения OES_texture_float и иногда невозможен без включения фильтров NearestFilter.


Фильтрация и повторение текстуры

Так же, как и обычные текстуры, DataTexture поддерживает фильтры:

texture.minFilter = THREE.NearestFilter;
texture.magFilter = THREE.NearestFilter;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
  • NearestFilter используется для пиксельных текстур, где важно сохранить четкость отдельных значений.
  • LinearFilter сглаживает значения при масштабировании, что подходит для плавных градиентов или визуализации данных.

Применение в шейдерах

DataTexture часто используется как источник данных для шейдеров GLSL, например для генерации процедурных эффектов, шумов, heightmap или lookup-текстур. В шейдере доступ к пикселю осуществляется через texture2D или texture (GLSL версии 3.0):

uniform sampler2D dataTexture;

void main() {
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    vec4 value = texture2D(dataTexture, uv);
    gl_FragColor = vec4(value.rgb, 1.0);
}

Такой подход позволяет полностью контролировать визуализацию на уровне GPU, используя массив данных без промежуточной конвертации в изображение.


Динамическое обновление текстуры

Для динамических сцен, где значения данных меняются каждый кадр, DataTexture обеспечивает быстрый способ обновления:

for (let i = 0; i < data.length; i += 4) {
    data[i] = (data[i] + 1) % 256; // простое обновление R-канала
}
texture.needsUpdate = true;

Важно, что при каждом изменении данных требуется выставлять texture.needsUpdate = true, иначе GPU не синхронизирует массив с текстурой.


Оптимизация и производительность

  • Использовать минимально необходимые типы данных (Uint8Array вместо Float32Array), если точность позволяет.
  • Применять фильтры NearestFilter для экономии ресурсов, если текстура используется для данных, а не визуального сглаживания.
  • Для больших массивов данных стоит использовать THREE.DataTexture2DArray или THREE.DataTexture3D (WebGL2) для хранения объёмных данных.

Особенности WebGL1 и WebGL2

  • WebGL1 ограничен поддержкой float-текстур и 1D/3D массивов. Расширения OES_texture_float и OES_texture_half_float необходимы для текстур с плавающей точкой.
  • WebGL2 расширяет возможности: поддержка 3D текстур, массивов текстур и форматов с одним каналом (RedFormat), что упрощает работу с scientific-данными и compute-подобными задачами.

DataTexture — мощный инструмент для визуализации и вычислений, позволяющий напрямую управлять пиксельными данными на GPU. Комбинация правильного формата, типа данных и фильтрации обеспечивает высокую производительность и гибкость при создании процедурной графики и научной визуализации.