0

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

我的主要 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 我将状态设置为“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 无处可见。任何建议表示赞赏,谢谢!

4

2 回答 2

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 存在并已加载。

于 2015-01-09T17:13:51.513 回答
0

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

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

PerspectiveCamera( fov, aspect, near, far )

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

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

这意味着球体将脱离截锥体并且不可见。

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

于 2015-12-13T23:03:36.080 回答