ThreeJS, Ionic, AngularJS -> 无法使天空盒出现

ThreeJS, Ionic, AngularJS -> Cannot make SkyBox Appear

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

我的主要 index.html 有一个 body:

<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 我将状态设置为 'threeJs',然后显示我的旋转立方体。我的 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 无处可见。任何建议表示赞赏,谢谢!

1 - 为您的天空盒设置负比例似乎很可疑。

2 - 您是否尝试了不同的球体大小值?也许它在截锥体之外。

3 - 您可以尝试设置

side = THREE.DoubleSide 

在你的天空盒上 material。

另外,为什么要设置 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 存在并已加载。

这个问题我也遇到过一次,因为忘记了这个,其实很简单

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

PerspectiveCamera( fov, aspect, near, far )

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

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

意味着 Sphere 将在 frustrum 之外并且不可见。

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