我将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无处可见。任何建议都表示赞赏,谢谢!
答案 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的数字。