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 的数字。
我将 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 的数字。