2012-11-24 67 views
4

我想讓天空盒分配給玩家相機。 當相機移動時(同時天空盒也隨之移動),紋理會被拉伸。 如何擺脫這個?three.js天空盒分配給相機

代碼:

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); 

回答

2

因此,深入挖掘three.js所例子後,我找到了一種方法如何做到這一點。 http://learningthreejs.com/blog/2011/08/15/lets-do-a-sky/已過時。示例中使用的一種方法是使用固定相機將skybox添加到第二個場景中,並渲染兩個場景。看看webgl_materials_cars.html示例。

也因爲我用第三人稱相機分配給角色,我必須從角色相機到天空盒相機得到世界的旋轉。這可以與渲染來完成:

function render(){ 
<...> 
    skyboxCamera.rotation.setEulerFromRotationMatrix(new THREE.Matrix4().extractRotation(camera.matrixWorld), skyboxCamera.eulerOrder); 
    renderer.render(skyboxScene, skyboxCamera); 
    renderer.render(scene, camera); 
<...> 
} 
0

我知道這是一個封閉的問題,但我想提供,不需要額外的場景選擇,爲今後的求職者:通過閱讀

  1. 啓動並按照本教程:http://learningthreejs.com/blog/2011/08/15/lets-do-a-sky/

  2. 現在創建以下着色器(我加了它three.js所ShaderLib,但如果你不想有三個發脾氣的源代碼添加它以外):

    '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;