Я намагаюся передати "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];
}