1、效果
通过循环 texture 的offset 属性值,可以实现,类似字幕的运动,以及箭头的线性流动等效果
2、示例地址
https://ithanmang./threejs/home/201810/20181030/01-texture-offset%E5%81%8F%E7%A7%BB.html
3、相关属性
该示例使用的是平面网格,然后加上材质贴图,设置纹理重复覆盖THREE.RepeatWrapping
然后循环渲染纹理的偏移量
3.1、wrapS/wrapT
纹理水平和垂直方向的平铺方式,分别对应 uv 贴图的uv属性,详细查看文档Texture 纹理常量
3.1.1、Wrapping Modes 模式
THREE.RepeatWrapping
THREE.ClampToEdgeWrapping
THREE.MirroredRepeatWrapping
THREE.RepeatWrapping :重复包裹
THREE.ClampToEdgeWrapping :纹理的最后一个像素延伸到网格的边缘,默认值
THREE.MirroredRepeatWrapping :纹理镜像重复
3.1、offset
是一个 vector2 变量,单个纹理的偏移量
3.2、repeat
一个Vector2 变量,纹理在 uv 方向上的重复次数,若大于1 则需要设置wrapS/wrapT 属性值为THREE.RepeatWrapping / THREE.MirroredRepeatWrapping
4、实现方法
4.1、创建纹理
texture = new THREE.TextureLoader().load('../../textures/arrows/arrow-right.png');
4.2、设置uv重复包裹方式
textur.wrapS = THREE.RepeatWrapping;
texture.wrapT=THREE.RepeatWrapping;
4.3、设置重复次数
texture.repeat.x = 10;
texture.repeat.y =1;
x 方向重复,10 次,y 方向默认值为1
4.4、创建 Mesh 并设置纹理贴图
var planeGeometry = new THREE.PlaneGeometry(200, 10);
var plane = new THREE.MeshBasicMaterial();
plane.color = new THREE.Color(0x00ff00);
plane.map = texture;
plane.transparent = true;
plane.side = THREE.DoubleSide;
4.5、循环设置纹理偏移量 offset
texture.offset.x += 0.001;
上面是x 方向,循环移动
4.6、效果
5、示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="../../../three.png">
<title>纹理offset偏移</title>
<style>
body {
margin: 0;
overflow: hidden; /* 溢出隐藏 */
}
#loading {
position: fixed;
top: 50%;
left: 50%;
color: #FFFFFF;
font-size: 20px;
margin-top: -30px;
margin-left: -40px;
}
</style>
<script src="../../libs/build/three-r93.js"></script>
<script src="../../libs/examples/js/Detector.js"></script>
<script src="../../libs/examples/js/libs/dat.gui.min.js"></script>
<script src="../../libs/examples/js/libs/stats.min.js"></script>
<script src="../../libs/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<p id="loading">loading......</p>
<script>
var scene, camera, renderer, controls, guiControls;
var stats = initStats();
/* 场景 */
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x050505);
}
/* 相机 */
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, -300);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
/* 渲染器 */
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/* 灯光 */
function initLight() {
scene.add(new THREE.AmbientLight(0x0c0c0c));
var spotLight1 = new THREE.SpotLight(0xffffff);
spotLight1.position.set(-400, -400, -400);
var spotLight2 = new THREE.SpotLight(0xffffff);
spotLight2.position.set(400, 400, 400);
scene.add(spotLight1);
scene.add(spotLight2);
}
/* 控制器 */
function initControls() {
/* 地图控件 */
controls = new THREE.OrbitControls(camera, renderer.domElement);
/* 属性参数 */
}
/* 调试插件 */
function initGui() {
guiControls = new function () {
};
var gui = new dat.GUI();
}
/* 场景中的内容 */
var texture_left;
var texture_up;
function initContent() {
texture_left = new THREE.TextureLoader().load('../../textures/arrows/arrow-right.png');
texture_up = new THREE.TextureLoader().load('../../textures/arrows/arrow-up.png');
texture_left.wrapS = THREE.RepeatWrapping;
texture_left.wrapT=THREE.RepeatWrapping;
texture_up.wrapS = THREE.RepeatWrapping;
texture_up.wrapT = THREE.RepeatWrapping;
texture_left.repeat.x = 10;
texture_left.repeat.y =1;
texture_up.repeat.x = 20;
texture_up.repeat.y =2;
var planeGeometry = new THREE.PlaneGeometry(200, 10);
var plane_left = new THREE.MeshBasicMaterial();
plane_left.color = new THREE.Color(0x00ff00);
plane_left.map = texture_left;
plane_left.transparent = true;
plane_left.side = THREE.DoubleSide;
var plane_up = new THREE.MeshBasicMaterial();
plane_up.color = new THREE.Color(0x00ff00);
plane_up.map = texture_up;
plane_up.transparent = true;
plane_up.side = THREE.DoubleSide;
var plane_left = new THREE.Mesh(planeGeometry, plane_left);
plane_left.translateY(10);
scene.add(plane_left);
var plane_up = new THREE.Mesh(planeGeometry, plane_up);
plane_up.translateY(-10);
scene.add(plane_up);
removeLoading();
}
/* 移除加载元素 */
function removeLoading() {
document.getElementById('loading').style.display = 'none';
}
/* 性能插件 */
function initStats() {
var stats = new Stats();
document.body.appendChild(stats.domElement);
return stats;
}
/* 窗口变动触发 */
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/* 数据更新 */
function update() {
stats.update();
controls.update();
// 设置纹理偏移
texture_left.offset.x -= 0.02;
texture_up.offset.y -= 0.02;
}
/* 初始化 */
function init() {
initScene();
initCamera();
initRender();
initLight();
initControls();
initContent();
initGui();
/* 监听事件 */
window.addEventListener('resize', onWindowResize, false);
}
/* 循环渲染 */
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
update();
}
/* 初始加载 */
(function () {
init();
animate();
})();
</script>
</body>
</html>
1、效果
通过循环 texture 的offset 属性值,可以实现,类似字幕的运动,以及箭头的线性流动等效果
2、示例地址
https://ithanmang./threejs/home/201810/20181030/01-texture-offset%E5%81%8F%E7%A7%BB.html
3、相关属性
该示例使用的是平面网格,然后加上材质贴图,设置纹理重复覆盖THREE.RepeatWrapping
然后循环渲染纹理的偏移量
3.1、wrapS/wrapT
纹理水平和垂直方向的平铺方式,分别对应 uv 贴图的uv属性,详细查看文档Texture 纹理常量
3.1.1、Wrapping Modes 模式
THREE.RepeatWrapping
THREE.ClampToEdgeWrapping
THREE.MirroredRepeatWrapping
THREE.RepeatWrapping :重复包裹
THREE.ClampToEdgeWrapping :纹理的最后一个像素延伸到网格的边缘,默认值
THREE.MirroredRepeatWrapping :纹理镜像重复
3.1、offset
是一个 vector2 变量,单个纹理的偏移量
3.2、repeat
一个Vector2 变量,纹理在 uv 方向上的重复次数,若大于1 则需要设置wrapS/wrapT 属性值为THREE.RepeatWrapping / THREE.MirroredRepeatWrapping
4、实现方法
4.1、创建纹理
texture = new THREE.TextureLoader().load('../../textures/arrows/arrow-right.png');
4.2、设置uv重复包裹方式
textur.wrapS = THREE.RepeatWrapping;
texture.wrapT=THREE.RepeatWrapping;
4.3、设置重复次数
texture.repeat.x = 10;
texture.repeat.y =1;
x 方向重复,10 次,y 方向默认值为1
4.4、创建 Mesh 并设置纹理贴图
var planeGeometry = new THREE.PlaneGeometry(200, 10);
var plane = new THREE.MeshBasicMaterial();
plane.color = new THREE.Color(0x00ff00);
plane.map = texture;
plane.transparent = true;
plane.side = THREE.DoubleSide;
4.5、循环设置纹理偏移量 offset
texture.offset.x += 0.001;
上面是x 方向,循环移动
4.6、效果
5、示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="../../../three.png">
<title>纹理offset偏移</title>
<style>
body {
margin: 0;
overflow: hidden; /* 溢出隐藏 */
}
#loading {
position: fixed;
top: 50%;
left: 50%;
color: #FFFFFF;
font-size: 20px;
margin-top: -30px;
margin-left: -40px;
}
</style>
<script src="../../libs/build/three-r93.js"></script>
<script src="../../libs/examples/js/Detector.js"></script>
<script src="../../libs/examples/js/libs/dat.gui.min.js"></script>
<script src="../../libs/examples/js/libs/stats.min.js"></script>
<script src="../../libs/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<p id="loading">loading......</p>
<script>
var scene, camera, renderer, controls, guiControls;
var stats = initStats();
/* 场景 */
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x050505);
}
/* 相机 */
function initCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 0, -300);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
/* 渲染器 */
function initRender() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/* 灯光 */
function initLight() {
scene.add(new THREE.AmbientLight(0x0c0c0c));
var spotLight1 = new THREE.SpotLight(0xffffff);
spotLight1.position.set(-400, -400, -400);
var spotLight2 = new THREE.SpotLight(0xffffff);
spotLight2.position.set(400, 400, 400);
scene.add(spotLight1);
scene.add(spotLight2);
}
/* 控制器 */
function initControls() {
/* 地图控件 */
controls = new THREE.OrbitControls(camera, renderer.domElement);
/* 属性参数 */
}
/* 调试插件 */
function initGui() {
guiControls = new function () {
};
var gui = new dat.GUI();
}
/* 场景中的内容 */
var texture_left;
var texture_up;
function initContent() {
texture_left = new THREE.TextureLoader().load('../../textures/arrows/arrow-right.png');
texture_up = new THREE.TextureLoader().load('../../textures/arrows/arrow-up.png');
texture_left.wrapS = THREE.RepeatWrapping;
texture_left.wrapT=THREE.RepeatWrapping;
texture_up.wrapS = THREE.RepeatWrapping;
texture_up.wrapT = THREE.RepeatWrapping;
texture_left.repeat.x = 10;
texture_left.repeat.y =1;
texture_up.repeat.x = 20;
texture_up.repeat.y =2;
var planeGeometry = new THREE.PlaneGeometry(200, 10);
var plane_left = new THREE.MeshBasicMaterial();
plane_left.color = new THREE.Color(0x00ff00);
plane_left.map = texture_left;
plane_left.transparent = true;
plane_left.side = THREE.DoubleSide;
var plane_up = new THREE.MeshBasicMaterial();
plane_up.color = new THREE.Color(0x00ff00);
plane_up.map = texture_up;
plane_up.transparent = true;
plane_up.side = THREE.DoubleSide;
var plane_left = new THREE.Mesh(planeGeometry, plane_left);
plane_left.translateY(10);
scene.add(plane_left);
var plane_up = new THREE.Mesh(planeGeometry, plane_up);
plane_up.translateY(-10);
scene.add(plane_up);
removeLoading();
}
/* 移除加载元素 */
function removeLoading() {
document.getElementById('loading').style.display = 'none';
}
/* 性能插件 */
function initStats() {
var stats = new Stats();
document.body.appendChild(stats.domElement);
return stats;
}
/* 窗口变动触发 */
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/* 数据更新 */
function update() {
stats.update();
controls.update();
// 设置纹理偏移
texture_left.offset.x -= 0.02;
texture_up.offset.y -= 0.02;
}
/* 初始化 */
function init() {
initScene();
initCamera();
initRender();
initLight();
initControls();
initContent();
initGui();
/* 监听事件 */
window.addEventListener('resize', onWindowResize, false);
}
/* 循环渲染 */
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
update();
}
/* 初始加载 */
(function () {
init();
animate();
})();
</script>
</body>
</html>
|