3

スカイボックスをプレーヤーのカメラに割り当てようとしています。カメラが移動すると(スカイボックスも一緒に移動します)、テクスチャが引き伸ばされます。これを取り除く方法は?

コード:

var textureCube = THREE.ImageUtils.loadTextureCube( urls );
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderUtils.lib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;

cubematerial = new THREE.ShaderMaterial({
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: shader.uniforms,
    depthWrite: false,
    side: THREE.BackSide
});
skyBox = new THREE.Mesh(new THREE.CubeGeometry(1000,1000,1000), cubematerial);
camera.add(skyBox);
4

2 に答える 2

2

そこで、Three.jsの例を掘り下げた後、これを行う方法を見つけました。http://learningthreejs.com/blog/2011/08/15/lets-do-a-sky/は古くなっています。例で使用される方法は、固定カメラを使用して2番目のシーンにスカイボックスを追加し、両方のシーンをレンダリングすることです。webgl_materials_cars.htmlの例を見てください。

また、キャラクターに割り当てられた3人称カメラを使用しているため、キャラクターカメラからスカイボックスカメラへの世界回転を取得する必要があります。これは、レンダリング時に次の方法で実行できます。

function render(){
<...>
    skyboxCamera.rotation.setEulerFromRotationMatrix( new THREE.Matrix4().extractRotation( camera.matrixWorld ), skyboxCamera.eulerOrder );
    renderer.render(skyboxScene, skyboxCamera);
    renderer.render(scene, camera);
<...>
}
于 2012-11-25T00:00:19.817 に答える
1

私はそれが閉じた質問であることを知っていますが、将来の探求者のために、追加のシーンを必要としない代替案を提供したいと思います。

  1. このチュートリアルを読んで従うことから始めます:http://learningthreejs.com/blog/2011/08/15/lets-do-a-sky/

  2. 次に、次のシェーダーを作成します(three.js ShaderLibに追加しましたが、3つのソースコードで調整したくない場合は、外部に追加します)。

    'skybox': {
    
    uniforms: { "tCube": { type: "t", value: null },
                "tFlip": { type: "f", value: -1 } },
    
    vertexShader: [
    
        "varying vec3 vWorldPosition;",
    
        THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
    
        "void main() {",
    
        "   vec4 worldPosition = modelMatrix * vec4( position, 1.0 );",
        "   vWorldPosition = worldPosition.xyz;",
    
        "   gl_Position = projectionMatrix * modelViewMatrix * vec4( position + cameraPosition, 1.0 );",
    
            THREE.ShaderChunk[ "logdepthbuf_vertex" ],
    
        "}"
    
    ].join("\n"),
    
    fragmentShader: [
    
        "uniform samplerCube tCube;",
        "uniform float tFlip;",
    
        "varying vec3 vWorldPosition;",
    
        THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
    
        "void main() {",
    
        "   gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",
    
            THREE.ShaderChunk[ "logdepthbuf_fragment" ],
    
        "}"
    
    ].join("\n")
    

    }、

  3. 次のようにスカイボックスを作成します。

        // urls is a list of textures to use
    var cubemap = THREE.ImageUtils.loadTextureCube(urls); 
    cubemap.format = THREE.RGBFormat; 
    
    var shader = THREE.ShaderLib['skybox']; // init the skybox shader we created above
    shader.uniforms['tCube'].value = cubemap; // apply textures to shader
    
    // create shader material
    var skyBoxMaterial = new THREE.ShaderMaterial( {
      fragmentShader: shader.fragmentShader,
      vertexShader: shader.vertexShader,
      uniforms: shader.uniforms,
      depthWrite: false,
      side: THREE.BackSide
    });
    
    // create skybox mesh
    var skybox = new THREE.Mesh(
      new THREE.CubeGeometry(1000, 1000, 1000),
      skyBoxMaterial
    );
    
            // THIS IS IMPORTANT! or the skybox will get culled after you move the camera too far..
    skybox.frustumCulled = false;
    
于 2014-05-26T13:47:55.390 に答える