2016-10-25 5 views
1

WebGLで3Dテクスチャを使用しようとしていますが、現状ではサポートされていないので、2D画像でトリックする必要があります。 64枚の画像で構成され、それぞれ64枚×64枚(合計64枚×40枚)です。私はリンクを掲示したいと思ったが、私は十分にxpを持っていなかった(真剣に?)、依然としてあなたはフィドルのファイルURLを見つけることができない。webgl 2Dテクスチャの3Dテクスチャ、レンダリングの問題がある

私は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 --> 

Here is the fiddle:ここ

は、シェーダコードです。

私はThreeJSを使用しています。 ご協力いただきありがとうございます。

+0

私はアーティファクトを取り除くことができます。私の場合はうまく動作しますが、実際には一般的な修正ではありません。 '' ' var texture = new THREE.TextureLoader()。load(texFile); texture.magFilter = THREE.NearestFilter; texture.minFilter = THREE.NearestFilter; '' ' –

+0

テクスチャを読み込むときに、テクスチャの設定を調整しようとします。 2Dテクスチャでうまくいくいくつかの機能は無効にしたいが、3D上では問題になるだろう。最初に.magFilterをTHREE.NearestFilterに設定しようとします。 サイト間のセキュリティのために、フィドルは機能していません。 – Arnaud

+0

ああ、私はあなたが試してみると、それは私のコメントを書いた前であってもうまくいきました。良い。 – Arnaud

答えて

1

jsコードでTHREE.TextureLoader()を使用してテクスチャを読み込んだ後、解決策がtexture.minFilter = THREE.NearestFilterに設定されていました。このため、質問にjsコードを追加し、これは、stackoverflowでこの質問に足を踏み入れる将来のユーザーを助けるかもしれません)。

ストライプの説明:ピクセルがスライスを変更するプレーンの1つに近い場合、変数sliceZがジャンプします。ピクセルが複数のテクセルをカバーする状況になります。ピクセルの一部はあるv座標にあり、ピクセルの一部は、(下の画像に到達するために)テクスチャの64ピクセルに対応する量だけ大きいav座標にあることに注意してください。/私の推測は、機械はあなたのピクセルが64テクスチャピクセルのv-スパンをカバーしていると信じているので、それらのピクセルの平均値をとります(これは.minfilterのデフォルトのミップマップ設定であらかじめ計算されています)。

関連する問題