Three.js学习8:基础贴图

一、贴图

贴图 (Texture Mapping),也翻译为纹理映射,"贴图"这个翻译更直观。

贴图,就是把图片贴在 3D 物体材质的表面,让它具有一定的纹理,来为 3D 物体添加细节的一种方法。这使我们能够添加表面细节,而无需将这些细节建模到我们的3D对象中,从而大大精简3D模型的多边形边数,提高模型渲染性能。

二、准备基础代码

在场景里创建一个立方体

为了方便观察效果,还添加了网格辅助轨道控制器

HTML:

html 复制代码
<script type="importmap">
    {
        "imports":{
            "three":"./js/three.module.min.js",
            "addons/":"./js/jsm/"
        }
    }
</script>
<script type="module" src="js/myjs.js"></script>

JS:

javascript 复制代码
import * as THREE from "three";
import { OrbitControls } from "addons/controls/OrbitControls.js";

let winH = window.innerHeight;
let winW = window.innerWidth;
// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color("#cccccc");

// 物体
const geometry = new THREE.BoxGeometry(1,1,1);
const material = new THREE.MeshBasicMaterial({
    color:"#ff3300"
});
const box = new THREE.Mesh( geometry, material );
box.position.set(0,0,0);
scene.add( box );

// grid
const gridHelper = new THREE.GridHelper(10,10);
scene.add( gridHelper);

// 相机
const camera = new THREE.PerspectiveCamera(50, winW/winH, 1, 1000);
camera.position.set(0,5,5);
camera.lookAt(scene.position);

// 渲染器
const renderer  = new THREE.WebGLRenderer();
renderer.setSize( winW, winH );
document.body.appendChild( renderer.domElement );
renderer.render( scene, camera );

// 轨道控制器
const controls = new OrbitControls( camera, renderer.domElement );
controls.update();

// 动画
function animateFun(){
    controls.update();   // 现在动画里更新控制器
    // 渲染
    renderer.render( scene, camera);
    requestAnimationFrame(animateFun);
}
animateFun();

三、纹理贴图示例

纹理贴图用到的是基础材质 THREE.MeshBasicMaterialTHREE.TextureLoader

  • THREE.MeshBasicMaterial :基础材质是不受光照影响,可以直接给物体设置颜色,也可以将图片贴到物体表面。

  • THREE.TextureLoader:纹理加载器。纹理贴图加载器TextureLoaderload() 方法加载一张图片可以返回一个纹理对象Texture纹理对象Texture可以作为模型材质贴图 .map 属性的值。

修订代码,为立方体的材质(meterial) 添加纹理贴图

javascript 复制代码
const texture = new THREE.TextureLoader().load("../images/woods2.jpg");
const material = new THREE.MeshBasicMaterial({
    map:texture
});

这里用的纹理图是:

效果:

四、透明贴图示例

如果贴图要透明,可以设置材质的透明属性 transparent:true;

同时,要准备好 alpha 图片,做 alpha贴图的纹理。

alpha 图片,其实就是一个黑白图,跟 PS 蒙版是一个道理:黑色不可见,白色可见,灰色代表半透明。

这里使用两张素材如下:

修改 meterial 代码如下:(两张纹理图,都要加载进去)。

javascript 复制代码
const texture = new THREE.TextureLoader().load("../images/head1.jpg");
const textureAlpha = new THREE.TextureLoader().load("../images/head2.jpg");
const material = new THREE.MeshBasicMaterial({
    map:texture,           // 纹理贴图
    alphaMap:textureAlpha,  // alpha 贴图
    transparent:true      // 开启透明属性
});

为什么立方体只有一半?

这是因为,纹理渲染面属性值 side 有四个值 :

  • THREE.FrontSide:**默认。**只渲染前面。

  • THREE.BackSide:只渲染后面

  • THREE.DoubleSide:前后面都渲染。

  • THREE.TwoPassDoubleSide:将按前后顺序分两次渲染双面透明材料,以减轻透明伪影。

默认 meterial 的"平面"是只渲染前面,因此立方体转向后,背面的图是看不到的。把 side 属性改为 THREE.DoubleSide 即可。

javascript 复制代码
const material = new THREE.MeshBasicMaterial({
    map:texture,
    transparent:true,
    alphaMap:textureAlpha,
    side: THREE.DoubleSide   // 前后面都渲染。
});

五、环境贴图示例

环境贴图(environment mapping),顾名思义,就是给材质贴上环境的画面。

这个主要让材质反映出周围的画面。比如,在一个草地上,让一个立方体映出草地周围的画面。

1. 给场景添加立方纹理

修改前面的基础结构代码给场景添加立方纹理,把场景设置为一个公园。

javascript 复制代码
// 场景
const scene = new THREE.Scene();
// 给场景添加立方纹理
const cubeTexture = new THREE.CubeTextureLoader().setPath("../texture3/").load([
    "posx.jpg","negx.jpg",
    "posy.jpg","negy.jpg",
    "posz.jpg","negz.jpg"
]);
scene.background = cubeTexture;

这里公园用的素材是官方案例 \examples\textures\cube\Park2 里面的素材。

2. 给材质添加环境贴图

javascript 复制代码
const material = new THREE.MeshBasicMaterial({
    envMap: cubeTexture  // 给材质应用环境贴图:此时的环境的贴图就是立方纹理,所以就使用立方纹理。
});

也可以同时使用纹理贴图和环境贴图。

javascript 复制代码
const material = new THREE.MeshBasicMaterial({
    map:texture,
    envMap: cubeTexture 
});
相关推荐
skywalk816313 分钟前
fastdeploy cpu版本安装,需要什么硬件和软件环境?
人工智能·学习·paddlepaddle
.千余31 分钟前
【Linux】开发工具1
linux·运维·服务器·c语言·学习
爱上好庆祝39 分钟前
学习js第一天(出发新世界)
开发语言·前端·javascript·css·学习·html·ecmascript
码农的小菜园1 小时前
Android的Locale学习笔记
android·笔记·学习
zhangrelay1 小时前
Lubuntu 26.04移动系统使用配置测试记录与引导修复备注
笔记·学习
摇曳的精灵1 小时前
OceanBase学习
学习·oceanbase
星幻元宇VR1 小时前
VR消防安全学习机,数字化消防培训新选择
科技·学习·安全·vr
光影少年2 小时前
高级前端需要学习那些东西?
前端·人工智能·学习·aigc·ai编程
jiayong232 小时前
第 41 课:任务详情抽屉里的快速筛选联动
开发语言·前端·javascript·vue.js·学习
浅念-2 小时前
LeetCode 模拟算法:用「还原过程」搞定编程题的入门钥匙
开发语言·c++·学习·算法·leetcode·职场和发展·模拟