Javascript 单个图像skybox的问题
我一直在寻找一种方法来创建一个天空盒使用一个单一的图像作为纹理贴图 我找到了一个UV贴图教程,但结果在框中正平面和负平面的边缘生成了黑线,如图和所示 我的问题是:是什么导致了这些背道而驰?这是仅使用单个图像创建skybox的最佳方法吗 这是我的密码:Javascript 单个图像skybox的问题,javascript,three.js,Javascript,Three.js,我一直在寻找一种方法来创建一个天空盒使用一个单一的图像作为纹理贴图 我找到了一个UV贴图教程,但结果在框中正平面和负平面的边缘生成了黑线,如图和所示 我的问题是:是什么导致了这些背道而驰?这是仅使用单个图像创建skybox的最佳方法吗 这是我的密码: <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>Using an skybox!</title>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Using an skybox!</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"> </script>
<style>
body {margin:0; overflow:hidden}
canvas {width:100%; height:100%}
</style>
</head>
<body>
<div id="threejs"></div>
<script>
var scene, renderer;
var camera, controls;
var width, height;
var light, ambient;
var cube;
init();
function init() {
width = window.innerWidth;
height = window.innerHeight;
loadScene();
loadMeshes();
loadLights();
render();
};
function loadScene() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 2000);
camera.position.z = 15;
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer({antialias:true} );
renderer.setSize(width, height);
renderer.setClearColor(0xdfdfdf);
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
document.getElementById("threejs").appendChild(renderer.domElement);
controls = new THREE.TrackballControls( camera, renderer.domElement);
};
function loadMeshes(){
var boxMap = new THREE.TextureLoader().load('skybox3.jpg');
var material = new THREE.MeshPhongMaterial({
map: boxMap,
side: THREE.BackSide
});
var posx = [new THREE.Vector2(0.5, .666), new THREE.Vector2(0.5, .333),
new THREE.Vector2(0.75, .333), new THREE.Vector2(0.75, .666)];
var negx = [new THREE.Vector2(0, .666), new THREE.Vector2(0, .333),
new THREE.Vector2(0.25, .333), new THREE.Vector2(0.25, .666)];
var posz = [new THREE.Vector2(0.25, .666), new THREE.Vector2(0.25, .333),
new THREE.Vector2(0.5, .333), new THREE.Vector2(0.5, .666)];
var negz = [new THREE.Vector2(0.75, .666), new THREE.Vector2(0.75, .333),
new THREE.Vector2(1 , .333), new THREE.Vector2(1, .666)];
var posy = [new THREE.Vector2(0.25, 1), new THREE.Vector2(0.25, .666),
new THREE.Vector2(0.5, .666), new THREE.Vector2(0.5, 1)];
var negy = [new THREE.Vector2(0.25, .333), new THREE.Vector2(0.25, 0),
new THREE.Vector2(0.5, 0), new THREE.Vector2(0.5, .333)];
var cubeGeometry = new THREE.BoxGeometry(1000, 1000, 1000);
cubeGeometry.faceVertexUvs[0] = [];
cubeGeometry.faceVertexUvs[0][0] = [ posx[0], posx[1], posx[3]];
cubeGeometry.faceVertexUvs[0][1] = [ posx[1], posx[2], posx[3]];
cubeGeometry.faceVertexUvs[0][2] = [ negx[0], negx[1], negx[3]];
cubeGeometry.faceVertexUvs[0][3] = [ negx[1], negx[2], negx[3]];
cubeGeometry.faceVertexUvs[0][4] = [ posy[0], posy[1], posy[3]];
cubeGeometry.faceVertexUvs[0][5] = [ posy[1], posy[2], posy[3]];
cubeGeometry.faceVertexUvs[0][6] = [ negy[0], negy[1], negy[3]];
cubeGeometry.faceVertexUvs[0][7] = [ negy[1], negy[2], negy[3]];
cubeGeometry.faceVertexUvs[0][8] = [ posz[0], posz[1], posz[3]];
cubeGeometry.faceVertexUvs[0][9] = [ posz[1], posz[2], posz[3]];
cubeGeometry.faceVertexUvs[0][10] = [ negz[0], negz[1], negz[3]];
cubeGeometry.faceVertexUvs[0][11] = [ negz[1], negz[2], negz[3]];
cube = new THREE.Mesh(cubeGeometry, material);
scene.add(cube);
};
function loadLights() {
ambient = new THREE.AmbientLight(0xbbbbbb);
light = new THREE.SpotLight(0x5555555);
light.castShadow = true;
light.shadowCameraNear = 8;
light.shadowCameraFar = 400;
light.shadowDarkness = 1;
light.shadowMapWidth = 2048;
light.shadowMapHeight = 2048;
light.position.set(8, 15, 15);
scene.add(ambient);
scene.add(light);
};
function render() {
requestAnimationFrame(render);
controls.update();
renderer.render(scene, camera);
};
window.addEventListener("resize", function() {
width = window.innerWidth;
height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width/height;
camera.updateProjectionMatrix();
});
</script>
使用skybox!
正文{边距:0;溢出:隐藏}
画布{宽度:100%;高度:100%}
var场景,渲染器;
摄像机、控制器;
宽度、高度;
环境光;
var立方;
init();
函数init(){
宽度=window.innerWidth;
高度=窗内高度;
loadScene();
loadmesh();
装载灯();
render();
};
函数loadScene(){
场景=新的三个。场景();
摄像机=新的三视角摄像机(45,宽/高,0.12000);
摄像机位置z=15;
摄像机。注视(场景。位置);
renderer=new THREE.WebGLRenderer({antialas:true});
设置大小(宽度、高度);
renderer.setClearColor(0xdfdfdf);
renderer.shadowMap.enabled=true;
renderer.shadowMapSoft=true;
document.getElementById(“threejs”).appendChild(renderer.doElement);
控件=新的三个.trackball控件(摄影机、渲染器.doElement);
};
函数loadMesh(){
var-boxMap=new THREE.TextureLoader().load('skybox3.jpg');
var材质=新的3.0网格材质({
地图:方块地图,
侧面:三。背面
});
var posx=[新三向量2(0.5.666),新三向量2(0.5.333),
新三矢量2(0.75,333),新三矢量2(0.75,666)];
var negx=[新三个向量2(0.666),新三个向量2(0.333),
新三矢量2(0.25,333),新三矢量2(0.25,666)];
var posz=[新三点矢量2(0.25.666),新三点矢量2(0.25.333),
新三矢量2(0.5,333),新三矢量2(0.5,666)];
var negz=[新三个向量2(0.75.666),新三个向量2(0.75.333),
新三矢量2(1.333),新三矢量2(1.666)];
var posy=[新三个向量2(0.25,1),新三个向量2(0.25,666),
新三矢量2(0.5,666),新三矢量2(0.5,1)];
var negy=[new THREE.Vector2(0.25,333),new THREE.Vector2(0.25,0),
新三矢量2(0.5,0),新三矢量2(0.5,333)];
var cubeGeometry=新的三箱几何体(1000,1000,1000);
容积测量法。面容比[0]=[];
容积测量法。faceVertexUvs[0][0]=[posx[0],posx[1],posx[3];
容积测量法。脸顶点比[0][1]=[posx[1],posx[2],posx[3];
容积测量法。脸顶点vs[0][2]=[negx[0],negx[1],negx[3];
容积测量法。面容比[0][3]=[negx[1],negx[2],negx[3];
容积测量法。脸型[0][4]=[posy[0],posy[1],posy[3];
容积测量法。脸型变异系数[0][5]=[posy[1],posy[2],posy[3];
容积测量法。面部顶点vs[0][6]=[negy[0],negy[1],negy[3];
容积测量法。面部顶点vs[0][7]=[negy[1],negy[2],negy[3];
容积测量法。脸型[0][8]=[posz[0],posz[1],posz[3];
容积测量法。脸型[0][9]=[posz[1],posz[2],posz[3];
容积测量法。脸谱指数[0][10]=[negz[0],negz[1],negz[3];
容积测量法。脸型比[0][11]=[negz[1],negz[2],negz[3];
立方体=新的三个网格(立方计量法,材料);
场景.添加(立方体);
};
函数loadLights(){
环境光=新的三个环境光(0xbbbbbb);
灯光=新的三个聚光灯(0x555);
light.castShadow=true;
light.shadowCameraNear=8;
light.shadowCameraFar=400;
光、影、暗=1;
light.shadowMapWidth=2048;
light.shadowmapeight=2048;
光。位置。设置(8,15,15);
场景。添加(环境光);
场景。添加(灯光);
};
函数render(){
请求动画帧(渲染);
控件更新();
渲染器。渲染(场景、摄影机);
};
addEventListener(“调整大小”,函数(){
宽度=window.innerWidth;
高度=窗内高度;
设置大小(宽度、高度);
camera.aspect=宽度/高度;
camera.updateProjectMatrix();
});
多亏了@WaclawJasper,我发现这是一个纹理过滤问题。因此,我尝试执行“编码填充”来增加到纹理黑色部分的距离,而不是填充图像边框,这是外部编辑它所必需的。这是我对原代码的修改:
var posx = [new THREE.Vector2(0.5, .665), new THREE.Vector2(0.5, .334),
new THREE.Vector2(0.75, .334), new THREE.Vector2(0.75, .665)];
var negx = [new THREE.Vector2(0, .665), new THREE.Vector2(0, .334),
new THREE.Vector2(0.25, .334), new THREE.Vector2(0.25, .665)];
var posz = [new THREE.Vector2(0.25, .665), new THREE.Vector2(0.25, .334),
new THREE.Vector2(0.5, .334), new THREE.Vector2(0.5, .665)];
var negz = [new THREE.Vector2(0.75, .665), new THREE.Vector2(0.75, .334),
new THREE.Vector2(1 , .334), new THREE.Vector2(1, .665)];
var posy = [new THREE.Vector2(0.251, 1), new THREE.Vector2(0.251, .665),
new THREE.Vector2(0.499, .665), new THREE.Vector2(0.499, 1)];
var negy = [new THREE.Vector2(0.251, .334), new THREE.Vector2(0.251, 0),
new THREE.Vector2(0.499, 0), new THREE.Vector2(0.499, .334)];