/ / передайте дані масиву в шейдер у triJS - масиви, three.js, webgl, text2d

передавати дані масиву в шейдер у трьох JS-масивах, three.js, webgl, texture2d

Я намагаюся передати "volume._data" моєму фрагменту шейдера в три Дж. Це Float32Array, і він може містити до: 512x512x512x4 елементів.

  var mat = new THREE.ShaderMaterial({
uniforms: {
color: {type: "f", value: 1.0},
ijk: {type: "??", value: volume._data},
dimensions: {type: "vec3", value: volume._dimensions},
ijktoras: {type: "mat4", value: volume._RASToIJK}
},
vertexShader: document.
getElementById("vertShader").text,
fragmentShader: document.
getElementById("fragShader").text
});

Проблема в тому, що я не знаю, якому типу його дати. Або найкращий варіант для передачі 2D текстури?

Моє занепокоєння текстурою полягає в тому, що вона буде занадто великою, щоб передати її шейдеру.

Чи є якесь вирішення для передачі цієї кількості інформації в шейдер?

Моя загальна мета - у фрагменті шейдера -відобразити розташування пікселів на екрані в координаті світу об'єкта. Потім відмітьте координату цього світу на мій об'єм._дані (простір ijk) для відображення на екрані певного кольору.

Дякую, Ніколас

Відповіді:

1 для відповіді № 1

Перевірити https://github.com/mrdoob/three.js/wiki/Uniforms-types для масивів, таких як:

"uFloatArray3" : { type: "fv",  value: [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 ] }, // float array (vec3)

або

"uVec4Array" : { type: "v4v", value: [ new THREE.Vector4( 0.1, 0.2, 0.3, 0.4 ),
new THREE.Vector4( 0.4, 0.5, 0.6, 0.7 ) ] }, // Vector4 array

Ви завжди можете просто упакувати ці дані в прямий масив і використовувати роздільник.

Що стосується того, що ви робите, найкраще передати 3 текстури, кожна 512x512 та отримати доступ до RGBA за свої 4 значення. Це буде не надто повільно, не переживайте над оптимізацією, поки не спробуєте.

Це, звичайно, залежить від того, як ви заповнюєте дані у своєму буфері. Швидший спосіб зробити це через полотно, використовуючи масив пікселів, як описано тут: https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/


0 для відповіді № 2

Відповідь, наданий Flux, є правильною. Для тих із вас, хто намагається скласти об'ємний шейдер, може бути корисним наступне.

Ви можете використовувати одновимірний масив, щоб представити 3d-простір і отримати правильний елемент масиву через нього "s x, y, z -коорди, використовуючи наступний метод.

Координати x, y, z повинні знаходитись у локальному просторі (а не у світі) з початком у 0,0,0. Вам потрібно знати ширину та висоту кожного 2d розділу.

Якщо припустити об'єм вокселя 3x3x3

uniform float[] Voxels;
uniform int Width = 3;
uniform int Height = 3;

float getValueAtVoxel(x,y,z) {
int voxel = (Width * Height * z) + (y * Width) + x;

if (voxel < 0 || voxel >= Voxels.length) {
return 0.0;
}

return Voxels[voxel];
}