ThreeJS,Ionic,AngularJS - >无法让SkyBox出现

时间:2015-01-09 16:52:06

标签: angularjs three.js ionic

我将ThreeJS与Ionic和Angular框架结合使用。我已经按照Ionic教程获得了一个旋转的立方体,我已经创建了一个代码来为我的场景添加一个skyBox,但我根本无法让它出现,我也不知道为什么。

我的主要index.html有一个正文:

<body ng-app="ionicApp">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
<ion-nav-bar class="bar-positive">
</ion-nav-bar>

<ion-tabs class="tabs-positive">

    <ion-tab icon="ion-home" ui-sref="home">
        <ion-nav-view name="home">

        </ion-nav-view>
    </ion-tab>

    <ion-tab icon="ion-help" ui-sref="threeJs">
        <ion-nav-view name="help">
        </ion-nav-view>
    </ion-tab>

</ion-tabs>

<ion-nav-view></ion-nav-view>

因此,使用angular-ui-router我将状态设置为&#39; threeJs&#39;然后显示我的旋转立方体。我的路由的html是这样的:

<ion-view title="ThreeJS">
<ion-content padding="true" id="canvas">
    <three-js-canvas></three-js-canvas>
</ion-content>

<script type="application/x-glsl" id="sky-vertex">
varying vec2 vUV;

void main() {
    vUV = uv;
    vec4 pos = vec4(position, 1.0);
    gl_Position = projectionMatrix * modelViewMatrix * pos;
}

<script type="application/x-glsl" id="sky-fragment">
uniform sampler2D texture;
varying vec2 vUV;

void main() {
    vec4 sample = texture2D(texture, vUV);
    gl_FragColor = vec4(sample.xyz, sample.w);
}

three-js-canvas是我为处理我的threeJS内容而创建的自定义指令。它的代码如下:

angular.module('ionicApp').directive('threeJsCanvas', function () {
    'use strict';
    console.log("hi");
    return {
        restrict: 'E',
        link: function (scope, element, attr) {
            var scene,
                camera,
                renderer,
                geometry,
                material,
                cube;

            function initCube() {
                scene = new THREE.Scene();
                camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

                renderer = new THREE.WebGLRenderer();
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setClearColor(0xFFFFFF, 0);
                element[0].appendChild(renderer.domElement);

                var geometryCube = new THREE.BoxGeometry(1, 1, 1),
                    materialCube = new THREE.MeshBasicMaterial({
                        color: 0x00ff00
                    });
                cube = new THREE.Mesh(geometryCube, materialCube);
                scene.add(cube);
            }

            function initSky() {
                var sphereGeometry = new THREE.SphereGeometry(3000, 60, 40),
                    uniforms = {
                        texture: {
                            type: 't',
                            value: THREE.ImageUtils.loadTexture('img/lowres.jpg')
                        }
                    },

                    sphereMaterial = new THREE.ShaderMaterial({
                        uniforms: uniforms,
                        vertexShader: document.getElementById('sky-vertex').textContent,
                        fragmentShader: document.getElementById('sky-fragment').textContent
                    });
                console.log(document.getElementById('sky-vertex').textContent);
                var skyBox = new THREE.Mesh(sphereGeometry, sphereMaterial);
                skyBox.scale.set(-1, 1, 1);
                skyBox.rotation.order = 'XYZ';
                skyBox.renderDepth = 1000.0;
                scene.add(skyBox);
            }

            function render() {
                requestAnimationFrame(render);
                cube.rotation.x += 0.1;
                cube.rotation.y += 0.1;
                camera.position.z = 5;
                renderer.render(scene, camera);
            }
            initCube();
            initSky();
            render();
        }
    };
});

当我点击我的按钮以路由到我的threeJS状态时,我只需要一个漂亮的旋转立方体和一个空白的白色背景,我的skyBox无处可见。任何建议都表示赞赏,谢谢!

2 个答案:

答案 0 :(得分:1)

1 - 为你的天空盒设置负比例似乎非常可疑。

2 - 您是否尝试过不同的球体尺寸值?也许它不在截头体中。

3 - 您可以尝试设置

side = THREE.DoubleSide 
天空盒材料上的

另外,为什么要设置renderDepth?不应该是必要的。

以下是一些肯定有效的天空盒代码:

function doSkyDome() {
    var skyGeometry = new THREE.SphereGeometry(5000,50,50);
    var texture;
    texture = THREE.ImageUtils.loadTexture('textures/sky.png');

    var skyMaterial = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide });
    _skyBox = new THREE.Mesh( skyGeometry, skyMaterial );
    _skyBox.material.fog = false;
    _skyBox.position.set(0,0,0);
    _skyBox.rotation.x = Math.PI/4;
    _scene.add( _skyBox );
}

当然,请确认您的lowres.jpg存在且已加载。

答案 1 :(得分:0)

我偶尔会遇到这个问题,因为我忘了这个,这很简单。

正如Threejs文档中所述,PerspectiveCamera具有以下参数:

PerspectiveCamera( fov, aspect, near, far )

您使用的FAR为1000,然后在此处向球体添加3000半径:

var sphereGeometry = new THREE.SphereGeometry(3000, 60, 40)

意味着Sphere将不在frustrum范围内且不可见。

所以你有两个选择,减少SphereGeometry半径,或者将PerspectiveCamera FAR参数增加到大于3000的数字。