Я пытаюсь передать большой объем информации в свой шейдер фрагмента, но я всегда достигаю предела (слишком много текстур привязано, слишком много текстур и т. Д., Массив слишком большой и т. Д.).). Я использую настраиваемый шейдер ThreeJS.обрабатывать большие массивы/текстуры в фрагменте шейдера
У меня есть том объемом 256 * 256 * 256 rgba, который я хочу передать моему шейдеру.
В моем шейдере я хочу сопоставить мировое положение фрагментов с вокселом в этом объеме 256 * 256 * 256.
Есть ли хорошая стратегия для решения такого количества информации? Что было бы лучшим пратисом? Есть ли хорошее обходное решение?
Мой текущий подход заключается в создании 4 различных текстур rgba 2048x2048, содержащих все необходимые мне данные.
Для создания каждого 2048x2048 текстуры, я просто нажать каждую строку каждого ломтика sequencially к большому массиву и разделить этот массив в 2048x2048x4 chuncks, которые мои текстуры:
var _imageRGBA = new Uint8Array(_dims[2] *_dims[1] * _dims[0] * 4);
for (_k = 0; _k < _dims[2]; _k++) {
for (_j = 0; _j < _dims[1]; _j++) {
for (_i = 0; _i < _dims[0]; _i++) {
_imageRGBA[4*_i + 4*_dims[0]*_j + 4*_dims[1]*_dims[0]*_k] = _imageRGBA[4*_i + 1 + 4*_dims[0]*_j + 4*_dims[1]*_dims[0]*_k] = _imageRGBA[4*_i + 2 + 4*_dims[0]*_j + 4*_dims[1]*_dims[0]*_k] = _imageN[_k][_j][_i];//255 * i/(_dims[2] *_dims[1] * _dims[0]);
_imageRGBA[4*_i + 3 + 4*_dims[0]*_j + 4*_dims[1]*_dims[0]*_k] = 255;
}
}
}
Каждая текстура выглядит так:
на стороне шейдера, я пытаюсь отобразить worldposition фрагмент, чтобы реальный цвет от текстуры:
Vertex Shader:
uniform mat4 rastoijk;
varying vec4 vPos;
varying vec2 vUv;
void main() {
vPos = modelMatrix * vec4(position, 1.0);
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
Фрагмент шейдеры:
<script id="fragShader" type="shader">
vec4 getIJKValue(sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3, vec3 ijkCoordinates, vec3 ijkDimensions) {
// IJK coord to texture
float textureSize = 2048.0;
float index = ijkCoordinates[0] + ijkCoordinates[1]*ijkDimensions[0] + ijkCoordinates[2]*ijkDimensions[0]*ijkDimensions[1];
// map index to right 2048 x 2048 slice
float sliceIndex = floor(index/(textureSize*textureSize));
float inTextureIndex = mod(index, textureSize*textureSize);
// get row in the texture
float rowIndex = floor(inTextureIndex/textureSize);
float colIndex = mod(inTextureIndex, textureSize);
// map indices to u/v
float u = colIndex/textureSize;
float v =1.0 - rowIndex/textureSize;
vec2 uv = vec2(u,v);
vec4 ijkValue = vec4(0, 0, 0, 0);
if(sliceIndex == float(0)){
ijkValue = texture2D(tex0, uv);
}
else if(sliceIndex == float(1)){
ijkValue = texture2D(tex1, uv);
}
else if(sliceIndex == float(2)){
ijkValue = texture2D(tex2, uv);
}
else if(sliceIndex == float(3)){
ijkValue = texture2D(tex3, uv);
}
return ijkValue;
}
uniform mat4 rastoijk;
uniform sampler2D ijk00;
uniform sampler2D ijk01;
uniform sampler2D ijk02;
uniform sampler2D ijk03;
uniform vec3 ijkDimensions;
varying vec4 vPos;
varying vec2 vUv;
void main(void) {
// get IJK coordinates of current element
vec4 ijkPos = rastoijk * vPos;
// show whole texture in the back...
vec3 color = texture2D(ijk00, vUv).rgb;
//convert IJK coordinates to texture coordinates
if(int(floor(ijkPos[0])) > 0
&& int(floor(ijkPos[1])) > 0
&& int(floor(ijkPos[2])) > 0
&& int(floor(ijkPos[0])) < int(ijkDimensions[0])
&& int(floor(ijkPos[1])) < int(ijkDimensions[1])
&& int(floor(ijkPos[2])) < int(ijkDimensions[2])){
// try to map IJK to value...
vec3 ijkCoordinates = vec3(floor(ijkPos[0]), floor(ijkPos[1]), floor(ijkPos[2]));
vec4 ijkValue = getIJKValue(ijk00, ijk01, ijk02, ijk03, ijkCoordinates, ijkDimensions);
color = ijkValue.rgb;
}
gl_FragColor = vec4(color, 1.0);
// or discard if not in IJK bounding box...
}
</script>
Это не очень хорошо работает. Теперь я получаю изображение с необычными артефактами (эффект nyquist shannon?). Когда я увеличиваю масштаб, изображение появляется. (хотя и не идеально, некоторые черные точки)
Любые советы помощь будет весьма признателен. Я также планирую сделать некоторые raycasting для объемного рендеринга с использованием этого подхода (очень необходимо в медицинской сфере)
Беста,
ли эта помощь? http://stackoverflow.com/a/23040903/128511 – gman
Это действительно помогает немного да, но я не вижу, как применить это к моей текущей проблеме ... См. обновленный вопрос.Я не знаком с webgl, и я не знаю, имеет ли смысл мой подход. спасибо – Nicolas