【发布时间】:2017-03-07 18:04:18
【问题描述】:
我正在尝试在 WebGL 中使用 3D 纹理,但由于它目前不受本地支持,因此我不得不使用 2D 图像的技巧。它由 64 张图片组成,每张图片大小为 64px x 64px(总共 64x4096)。我想发布一个链接,但我在 SO 上没有足够的 xp(真的吗?),你仍然可以在下面的小提琴中找到文件 url。
我使用了solution by gman 以及我自己的(最近的邻居)。在这两种情况下,当我使用倾斜投影 (capture) 时,我都会遇到 灰色条纹伪影 的奇怪渲染问题。
当投影倾斜时,条纹/短划线似乎出现在切片之间,并且根据相机位置,它们不会以相同的频率出现。这就是我考虑渲染问题而不是采样问题的原因。
有谁知道如何摆脱这些文物?是否有一些内置的 OpenGL ES 东西可以启用/禁用?
这是着色器代码:
<!-- FRAGMENT SHADER -->
<script id="fragment_shader1_custom3" type="x-shader/x-fragment">
uniform sampler2D texture;
uniform float imageIndex;
varying vec4 worldCoord;
varying vec2 vUv;
// 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);
}
void main( void ) {
// the position within the shader
vec2 shaderPos = vUv;
// if outside the texture cube, use a yellow color
if(worldCoord.x < 0.0 || worldCoord.x >= 1.0 || worldCoord.y < 0.0 || worldCoord.y >= 1.0 || worldCoord.z < 0.0 || worldCoord.z >= 1.0){
gl_FragColor = vec4(1.0, 1.0 , 0.0, 1.0);
}else{
vec3 chunkPosition = vec3(worldCoord.x, worldCoord.y, worldCoord.z);
// 63.0 instead of 64.0 to avoid a edge situation
gl_FragColor = sampleAs3DTexture(texture, chunkPosition, 63.0, 64.0, 1.0);
}
}
</script> <!-- END FRAGMENT SHADER -->
<!-- VERTEX SHADER -->
<script id="vertexShader_custom1" type="x-shader/x-vertex">
varying vec2 vUv;
varying vec4 worldCoord;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
worldCoord = modelMatrix * vec4( position, 1.0 );
}
</script> <!-- END VERTEX SHADER -->
请注意,我使用的是 ThreeJS。 感谢您的帮助。
【问题讨论】:
-
我设法摆脱了工件。在我的情况下效果很好,但不是真正的通用修复 ``` var texture = new THREE.TextureLoader().load(texFile); texture.magFilter = THREE.NearestFilter; texture.minFilter = THREE.NearestFilter; ```
-
在加载时尝试调整纹理的设置。您想禁用一些对 2D 纹理效果很好但在 3D 上会出现问题的功能。我会先尝试将 .magFilter 设置为 THREE.NearestFilter。顺便说一句,由于跨站点安全性,小提琴无法正常工作。
-
哦,我看到你试过了,而且效果很好,甚至在我写评论之前。很好。
-
哦,那是 minFilter,而不是 magFilter 出了问题,你是对的
-
@Arnaud 谢谢!顺便说一句,我不知道交叉起源,我发现 imgur 正在为此工作,你对未来还有其他建议/替代方案吗?
标签: three.js textures webgl shader 3d-texture