将 Sprite 添加到旋转球体
Adding a Sprite to a Rotating Sphere
我是 three.js 和 webgl 的新手...我正在尝试向这个旋转的球体添加一个 sprite(这是我自己的图像)。我希望我的这个图像无论我旋转到哪里都在球体中保持不变,当然,球体中反射的环境仍然会移动。这是对 MC Escher 的绘画 "Self-Portrait in Reflective Sphere" 的模仿。一切似乎都工作正常,除了我无法让精灵出现。不过,它没有给我任何错误。哦,同样出于某种原因,天空盒环境最初不会加载。我必须单击其中一个控件才能显示它。请帮忙!谢谢!这是我的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<script type = "text/Javascript" src = "../FinalProject/three.min.js"></script>
<script type = "text/Javascript" src = "../FinalProject/OrbitControls.js"></script>
<script type = "text/Javascript" src = "../FinalProject/dat.gui.min.js"></script>
<body>
<script>
var controls, camera, scene, renderer;
var cameraCube, sceneCube;
var textureEquirec, textureCube, textureSphere;
var cubeMesh, sphereMesh;
var sphereMaterial;
//var refract;
init();
animate();
function init()
{
//cameras
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
camera.position.set( 0, 0, 1000 );
cameraCube = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
controls = new THREE.OrbitControls( camera );
controls.minDistance = 500;
controls.maxDistance = 2500;
//scene
scene = new THREE.Scene();
sceneCube = new THREE.Scene();
//lights
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
//textures
var urls = [
"../FinalProject/pos-x.png",
"../FinalProject/neg-x.png",
"../FinalProject/pos-y.png",
"../FinalProject/neg-y.png",
"../FinalProject/pos-z.png",
"../FinalProject/neg-z.png",
];
textureCube = new THREE.CubeTextureLoader().load(urls);
textureCube.format = THREE.RGBFormat;
textureCube.mapping = THREE.CubeReflectionMapping;
var textureLoader = new THREE.TextureLoader();
textureEquirec = textureLoader.load("../FinalProject/environment.jpg");
textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
textureEquirec.magFiler = THREE.LinearFilter;
textureEquirec.minFilter = THREE.LinearMipMapLinearFilter;
textureSphere = textureLoader.load("../FinalProject/metal.jpg");
textureSphere.mapping = THREE.SphericalReflectionMapping;
//materials
var equirectShader = THREE.ShaderLib["equirect"];
var equirectMaterial = new THREE.ShaderMaterial({
fragmentShader: equirectShader.fragmentShader,
vertexShader: equirectShader.vertexShader,
uniforms: equirectShader.uniforms,
depthWrite: false,
side: THREE.BackSide
});
equirectMaterial.uniforms["tEquirect"].value = textureEquirec;
var cubeShader = THREE.ShaderLib["cube"];
var cubeMaterial = new THREE.ShaderMaterial({
fragmentShader: cubeShader.fragmentShader,
vertexShader: cubeShader.vertexShader,
uniforms: cubeShader.uniforms,
depthWrite: false,
side: THREE.Backside
});
cubeMaterial.uniforms["tCube"].value = textureCube;
//Skybox
cubeMesh = new THREE.Mesh(new THREE.BoxGeometry(100, 100, 100), cubeMaterial);
sceneCube.add(cubeMesh);
var geometry = new THREE.SphereGeometry(400.0, 24, 24);
sphereMaterial = new THREE.MeshLambertMaterial({envMap: textureCube});
sphereMesh = new THREE.Mesh(geometry, sphereMaterial);
scene.add(sphereMesh);
//Sprite
var map = new THREE.TextureLoader().load("../FinalProject/MeCutout.png");
var material2 = new THREE.SpriteMaterial({map:map});
var sprite1 = new THREE.Sprite(material2);
sprite1.position.set(128, 24, 24);
scene.add(sprite1);
//renderer
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setFaceCulling(THREE.CullFaceNone);
document.body.appendChild(renderer.domElement);
var params = {
Cube: function () {
cubeMesh.Material = cubeMaterial;
cubeMesh.visible = true;
sphereMaterial.envMap = textureCube;
sphereMaterial.needsUpdate = true;
},
Equirectangular: function () {
cubeMesh.material = equirectMaterial;
cubeMesh.visible = true;
sphereMaterial.envMap = textureEquirec;
sphereMaterial.needsUpdate = true;
},
Refraction: false
};
//GUI
var gui = new dat.GUI();
gui.add(params, 'Cube');
gui.add(params, 'Equirectangular');
gui.open();
window.addEventListener('resize', onWindowResize, false);
}//end function init
function onWindowResize()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
cameraCube.aspect = window.innerWidth / window.innerHeight;
cameraCube.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate()
{
requestAnimationFrame(animate);
render();
controls.update();
}
function render()
{
var timer = -0.0002 * Date.now();
camera.lookAt(scene.position);
cameraCube.rotation.copy(camera.rotation);
renderer.render(sceneCube, cameraCube);
renderer.render(scene, camera);
}
</script>
</body>
</html>
你的精灵就在那里;它只是很小而且被遮挡了。
Three.js Sprites 只是始终对准相机的 1x1 平面。您的球体半径为 400。您创建的精灵几乎不覆盖 1 个像素,并且 (128, 24, 24) 处的变换很好地位于球体内部(不透明)。一些代码如:
sprite1.position.set(550, 24, 24);
sprite1.scale.set(550,550,550);
应该有帮助。
很棒的自画像概念。
我是 three.js 和 webgl 的新手...我正在尝试向这个旋转的球体添加一个 sprite(这是我自己的图像)。我希望我的这个图像无论我旋转到哪里都在球体中保持不变,当然,球体中反射的环境仍然会移动。这是对 MC Escher 的绘画 "Self-Portrait in Reflective Sphere" 的模仿。一切似乎都工作正常,除了我无法让精灵出现。不过,它没有给我任何错误。哦,同样出于某种原因,天空盒环境最初不会加载。我必须单击其中一个控件才能显示它。请帮忙!谢谢!这是我的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<script type = "text/Javascript" src = "../FinalProject/three.min.js"></script>
<script type = "text/Javascript" src = "../FinalProject/OrbitControls.js"></script>
<script type = "text/Javascript" src = "../FinalProject/dat.gui.min.js"></script>
<body>
<script>
var controls, camera, scene, renderer;
var cameraCube, sceneCube;
var textureEquirec, textureCube, textureSphere;
var cubeMesh, sphereMesh;
var sphereMaterial;
//var refract;
init();
animate();
function init()
{
//cameras
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
camera.position.set( 0, 0, 1000 );
cameraCube = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
controls = new THREE.OrbitControls( camera );
controls.minDistance = 500;
controls.maxDistance = 2500;
//scene
scene = new THREE.Scene();
sceneCube = new THREE.Scene();
//lights
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
//textures
var urls = [
"../FinalProject/pos-x.png",
"../FinalProject/neg-x.png",
"../FinalProject/pos-y.png",
"../FinalProject/neg-y.png",
"../FinalProject/pos-z.png",
"../FinalProject/neg-z.png",
];
textureCube = new THREE.CubeTextureLoader().load(urls);
textureCube.format = THREE.RGBFormat;
textureCube.mapping = THREE.CubeReflectionMapping;
var textureLoader = new THREE.TextureLoader();
textureEquirec = textureLoader.load("../FinalProject/environment.jpg");
textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
textureEquirec.magFiler = THREE.LinearFilter;
textureEquirec.minFilter = THREE.LinearMipMapLinearFilter;
textureSphere = textureLoader.load("../FinalProject/metal.jpg");
textureSphere.mapping = THREE.SphericalReflectionMapping;
//materials
var equirectShader = THREE.ShaderLib["equirect"];
var equirectMaterial = new THREE.ShaderMaterial({
fragmentShader: equirectShader.fragmentShader,
vertexShader: equirectShader.vertexShader,
uniforms: equirectShader.uniforms,
depthWrite: false,
side: THREE.BackSide
});
equirectMaterial.uniforms["tEquirect"].value = textureEquirec;
var cubeShader = THREE.ShaderLib["cube"];
var cubeMaterial = new THREE.ShaderMaterial({
fragmentShader: cubeShader.fragmentShader,
vertexShader: cubeShader.vertexShader,
uniforms: cubeShader.uniforms,
depthWrite: false,
side: THREE.Backside
});
cubeMaterial.uniforms["tCube"].value = textureCube;
//Skybox
cubeMesh = new THREE.Mesh(new THREE.BoxGeometry(100, 100, 100), cubeMaterial);
sceneCube.add(cubeMesh);
var geometry = new THREE.SphereGeometry(400.0, 24, 24);
sphereMaterial = new THREE.MeshLambertMaterial({envMap: textureCube});
sphereMesh = new THREE.Mesh(geometry, sphereMaterial);
scene.add(sphereMesh);
//Sprite
var map = new THREE.TextureLoader().load("../FinalProject/MeCutout.png");
var material2 = new THREE.SpriteMaterial({map:map});
var sprite1 = new THREE.Sprite(material2);
sprite1.position.set(128, 24, 24);
scene.add(sprite1);
//renderer
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setFaceCulling(THREE.CullFaceNone);
document.body.appendChild(renderer.domElement);
var params = {
Cube: function () {
cubeMesh.Material = cubeMaterial;
cubeMesh.visible = true;
sphereMaterial.envMap = textureCube;
sphereMaterial.needsUpdate = true;
},
Equirectangular: function () {
cubeMesh.material = equirectMaterial;
cubeMesh.visible = true;
sphereMaterial.envMap = textureEquirec;
sphereMaterial.needsUpdate = true;
},
Refraction: false
};
//GUI
var gui = new dat.GUI();
gui.add(params, 'Cube');
gui.add(params, 'Equirectangular');
gui.open();
window.addEventListener('resize', onWindowResize, false);
}//end function init
function onWindowResize()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
cameraCube.aspect = window.innerWidth / window.innerHeight;
cameraCube.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate()
{
requestAnimationFrame(animate);
render();
controls.update();
}
function render()
{
var timer = -0.0002 * Date.now();
camera.lookAt(scene.position);
cameraCube.rotation.copy(camera.rotation);
renderer.render(sceneCube, cameraCube);
renderer.render(scene, camera);
}
</script>
</body>
</html>
你的精灵就在那里;它只是很小而且被遮挡了。
Three.js Sprites 只是始终对准相机的 1x1 平面。您的球体半径为 400。您创建的精灵几乎不覆盖 1 个像素,并且 (128, 24, 24) 处的变换很好地位于球体内部(不透明)。一些代码如:
sprite1.position.set(550, 24, 24);
sprite1.scale.set(550,550,550);
应该有帮助。
很棒的自画像概念。