Текстура 3d в webgl / three.js с использованием 2D текстурного обходного пути?
-
21-12-2019 - |
Вопрос
Я хотел бы использовать некоторые трехмерные текстуры для объектов, которые я рендурирую в WebGL.В настоящее время я использую следующий метод в шейдере фрагмента, как предложено на WebGL и отличия OpenGL :
// tex is a texture with each slice of the cube placed horizontally across the texture.
// texCoord is a 3d texture coord
// size is the size if the cube in pixels.
vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
float sliceSize = 1.0 / size; // space of 1 slice
float slicePixelSize = sliceSize / size; // space of 1 pixel
float sliceInnerSize = slicePixelSize * (size - 1.0); // space of size pixels
float zSlice0 = min(floor(texCoord.z * size), size - 1.0);
float zSlice1 = min(zSlice0 + 1.0, size - 1.0);
float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
float s0 = xOffset + (zSlice0 * sliceSize);
float s1 = xOffset + (zSlice1 * sliceSize);
vec4 slice0Color = texture2D(tex, vec2(s0, texCoord.y));
vec4 slice1Color = texture2D(tex, vec2(s1, texCoord.y));
float zOffset = mod(texCoord.z * size, 1.0);
return mix(slice0Color, slice1Color, zOffset);
}
.
Решение
кажется относительно прямым.Если вы хотите пойти вниз по изображению, вам придется вычислять координату текстуры v
, которая выбирает вправо ROW для вашего среза.Для этого вам нужно знать, сколько рядов есть в текстуре и сколько ломтиков на ряд
// tex is a texture with each slice of the cube placed in grid in a texture.
// texCoord is a 3d texture coord
// size is the size if the cube in pixels.
// slicesPerRow is how many slices there are across the texture
// numRows is the number of rows of slices
vec2 computeSliceOffset(float slice, float slicesPerRow, vec2 sliceSize) {
return sliceSize * vec2(mod(slice, slicesPerRow),
floor(slice / slicesPerRow));
}
vec4 sampleAs3DTexture(
sampler2D tex, vec3 texCoord, float size, float numRows, float slicesPerRow) {
float slice = texCoord.z * size;
float sliceZ = floor(slice); // slice we need
float zOffset = fract(slice); // dist between slices
vec2 sliceSize = vec2(1.0 / slicesPerRow, // u space of 1 slice
1.0 / numRows); // v space of 1 slice
vec2 slice0Offset = computeSliceOffset(sliceZ, slicesPerRow, sliceSize);
vec2 slice1Offset = computeSliceOffset(sliceZ + 1.0, slicesPerRow, sliceSize);
vec2 slicePixelSize = sliceSize / size; // space of 1 pixel
vec2 sliceInnerSize = slicePixelSize * (size - 1.0); // space of size pixels
vec2 uv = slicePixelSize * 0.5 + texCoord.xy * sliceInnerSize;
vec4 slice0Color = texture2D(tex, slice0Offset + uv);
vec4 slice1Color = texture2D(tex, slice1Offset + uv);
return mix(slice0Color, slice1Color, zOffset);
return slice0Color;
}
.
Вот фрагмент
Не связан с StackOverflow