three.js 细一万倍教程 从入门到精通(三)

目录

五、详解PBR材质纹理

5.1、详解PBR物理渲染

5.2、标准网格材质与光照物理效果

5.3、置换贴图与顶点细分设置

5.4、设置粗糙度与粗糙度贴图

5.5、设置金属度与金属贴图

5.6、法线贴图应用

5.7、如何获取各种类型纹理贴图

5.8、纹理加载进度情况

单张图片加载

多张图片加载

5.9、详解环境贴图

5.10、经纬线映射贴图与HDR

经纬线映射贴图

HDR

六、详解灯光与阴影

6.1、灯光与阴影的关系与设置

6.2、平行光阴影属性与阴影相机原理


五、详解PBR材质纹理

5.1、详解PBR物理渲染

灯光属性:直接照明、间接照明、直接高光、间接高光、阴影、环境光闭塞。

表面属性:基础色、法线、高光、粗糙度、金属度。

5.2、标准网格材质与光照物理效果

案例1:【环境光】照射物体

// 灯光(环境光)
// 参数分别为光的颜色和光的强度
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light)

案例2:【平行光】照射物体

// 直线光源
const directionaLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置光从哪个位置直射
directionaLight.position.set(10, 10, 10);
scene.add(directionaLight)

5.3、置换贴图与顶点细分设置

首先准备一张贴图

黑色还是不动,浅灰格外突出,特别是门把手和两块铁片要突出。

// 导入纹理
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load("./textures/door/color.jpg");
const doorAplhaTexture = textureLoader.load("./textures/door/alpha.jpg");
const doorAoTexture = textureLoader.load("./textures/door/ambientOcclusion.jpg")
// 导入置换贴图
const doorHeightTexture = textureLoader.load("./textures/door/height.jpg")const cubeGeometry = new THREE.BoxGeometry(1, 1, 1, 200, 200);
// 材质
const material = new THREE.MeshStandardMaterial({color: "#ffff00",map: doorColorTexture,alphaMap: doorAplhaTexture,transparent: true,aoMap: doorAoTexture,aoMapIntensity: 1,displacementMap: doorHeightTexture,displacementScale: 0.1 // 默认是1,深浅度,0.1代表稍微突出一点
})
const cube = new THREE.Mesh(cubeGeometry, material);
scene.add(cube);// 灯光(环境光)
// 参数分别为光的颜色和光的强度
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light)

5.4、设置粗糙度与粗糙度贴图

// 添加物体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1, 200, 200);
// 材质
const material = new THREE.MeshStandardMaterial({color: "#ffff00",map: doorColorTexture,alphaMap: doorAplhaTexture,transparent: true,aoMap: doorAoTexture,aoMapIntensity: 1,displacementMap: doorHeightTexture,displacementScale: 0.1,roughness: 0 // 设置粗糙度为0,直接光滑到底
})
const cube = new THREE.Mesh(cubeGeometry, material);
scene.add(cube);// 灯光(环境光)
// 参数分别为光的颜色和光的强度
const light = new THREE.AmbientLight(0xffffff);
scene.add(light)// 直线光源
const directionaLight = new THREE.DirectionalLight(0xffffff);
// 设置光从哪个位置直射
directionaLight.position.set(10, 10, 10);
scene.add(directionaLight)

假如我们想单独设置金属片粗糙,门光滑怎么办?

使用粗糙度贴图

白色代表粗糙度为1,黑色代表粗糙度为0。

5.5、设置金属度与金属贴图

现在我们想让金属片完全像金属,门不用。

准备金属贴图

黑色完全不用金属材质,而白色完全用金属材质。

// 导入纹理
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load("./textures/door/color.jpg");
const doorAplhaTexture = textureLoader.load("./textures/door/alpha.jpg");
const doorAoTexture = textureLoader.load("./textures/door/ambientOcclusion.jpg")
// 导入置换贴图
const doorHeightTexture = textureLoader.load("./textures/door/height.jpg");
// 粗糙度贴图
const doorRoughnessTexture = textureLoader.load("./textures/door/roughness.jpg");
// 金属贴图
const doorMetalnessTexture = textureLoader.load("./textures/door/metalness.jpg");// 添加物体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1, 200, 200);
// 材质
const material = new THREE.MeshStandardMaterial({color: "#ffff00",map: doorColorTexture,alphaMap: doorAplhaTexture,transparent: true,aoMap: doorAoTexture,aoMapIntensity: 1,displacementMap: doorHeightTexture,displacementScale: 0.1,// roughness: 0, // 设置粗糙度为0,直接光滑到底roughnessMap: doorRoughnessTexture,metalness: 1, // 金属度打满metalnessMap: doorMetalnessTexture // 引入金属贴图
})
const cube = new THREE.Mesh(cubeGeometry, material);
scene.add(cube);// 灯光(环境光)
// 参数分别为光的颜色和光的强度
const light = new THREE.AmbientLight(0xffffff);
scene.add(light)// 直线光源
const directionaLight = new THREE.DirectionalLight(0xffffff);
// 设置光从哪个位置直射
directionaLight.position.set(10, 10, 10);
scene.add(directionaLight)

5.6、法线贴图应用

上一节中虽然体现出了金属的质感,但还不够完美,我们发现在光折射的时候,门和金属片并没有凹凸不平的样子,都是一个平面的感觉。

我们再引入一个凹凸感(法线)的贴图

每个颜色都代表不同的朝向,相同的颜色相同朝向。

5.7、如何获取各种类型纹理贴图

网站:Poliigon - Textures, Models and HDRIs for 3D rendering

我们下载个免费的,解压一下

5.8、纹理加载进度情况

单张图片加载

let event = {}
// 单张纹理图的加载进度(color.jpg)
event.onLoad = function () {console.log("图片加载完成");
}
event.onProgress = function (e) {console.log("图片加载进度", e)
}
event.onError = function (e) {console.log("图片加载出现错误", e)
}// 导入纹理
const textureLoader = new THREE.TextureLoader();
const doorColorTexture = textureLoader.load("./textures/door/color.jpg", event.onLoad, event.onProgress, event.onError);

多张图片加载

let event = {}
event.onLoad = function () {console.log("图片加载完成");
}
event.onProgress = function (url, num, total) {console.log("图片加载路径", url)console.log("图片加载进度", num)console.log("图片总数", total)console.log("图片加载进度百分比", (num / total * 100).toFixed(2))
}
event.onError = function (e) {console.log("图片加载出现错误", e)
}// 设置加载管理器
const loadingManager = new THREE.LoadingManager(event.onLoad, event.onProgress, event.onError);// 导入纹理
const textureLoader = new THREE.TextureLoader(loadingManager);
const doorColorTexture = textureLoader.load("./textures/door/color.jpg");
const doorAplhaTexture = textureLoader.load("./textures/door/alpha.jpg");
const doorAoTexture = textureLoader.load("./textures/door/ambientOcclusion.jpg")
// 导入置换贴图
const doorHeightTexture = textureLoader.load("./textures/door/height.jpg");
// 粗糙度贴图
const doorRoughnessTexture = textureLoader.load("./textures/door/roughness.jpg");
// 金属贴图
const doorMetalnessTexture = textureLoader.load("./textures/door/metalness.jpg");
// 法线贴图
const doorNormalTexture = textureLoader.load("./textures/door/normal.jpg");

5.9、详解环境贴图

// 设置cube纹理加载器
const cubeTextureLoader = new THREE.CubeTextureLoader();
const envMapTexture = cubeTextureLoader.load(["./textures/environmentMaps/1/px.jpg","./textures/environmentMaps/1/nx.jpg","./textures/environmentMaps/1/py.jpg","./textures/environmentMaps/1/ny.jpg","./textures/environmentMaps/1/pz.jpg","./textures/environmentMaps/1/nz.jpg",
]);
const sphereGeometry = new THREE.SphereGeometry(1, 20, 20);
const material = new THREE.MeshStandardMaterial({metalness: 0.7, // 金属材质roughness: 0.1, // 光滑度envMap: envMapTexture, // 导入环境贴图
});
const sphere = new THREE.Mesh(sphereGeometry, material);
scene.add(sphere);

5.10、经纬线映射贴图与HDR

经纬线映射贴图

HDR

import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader'// 加载HDR环境图
const rgbeLoader = new RGBELoader();
rgbeLoader.loadAsync("./textures/hdr/002.hdr").then((texture) => {// 如果不设置映射mapping。则HDR环境图不会动texture.mapping = THREE.EquirectangularReflectionMapping;scene.background = texture;// 设置环境图(物体小球)scene.environment = texture;
});

六、详解灯光与阴影

6.1、灯光与阴影的关系与设置

目标:灯光与阴影

1、材质要满足对光照有反应。

2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;

3、设置光照投射阴影 directionaLight.castShadow = true;

4、设置物体投射阴影 sphere.castShadow = true;

5、设置物体接收阴影 plane.receiveShadow = true;

// 圆
const sphereGeometry = new THREE.SphereGeometry(1, 20, 20);
const material = new THREE.MeshStandardMaterial();
const sphere = new THREE.Mesh(sphereGeometry, material);
// 投射阴影
sphere.castShadow = true;
scene.add(sphere);// 创建平面
const planeGeometry = new THREE.PlaneGeometry(10, 10);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 接收阴影
plane.receiveShadow = true;
scene.add(plane);// 直线光源
const directionaLight = new THREE.DirectionalLight(0xffffff, 0.5);
// 设置光从哪个位置直射
directionaLight.position.set(10, 10, 10);
// 设置该平行光会产生动态阴影
directionaLight.castShadow = true;
scene.add(directionaLight);// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true;
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

6.2、平行光阴影属性与阴影相机原理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468654.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Java][算法 滑动窗口]Day 02---LeetCode 热题 100---08~09

第一题 无重复字符串的最长子串 思路 其实就是在字符串S中 找到没有重复的最长子串的长度 这道题的难点就是在于如何判断最长并且无重复 首先 最长长度 可以使用变量max记录保存 再者 判断有无重复 最简单的方法就是 暴力遍历法 即对于每次找的子串都再次寻找遍历…

【JAVA WEB】JavaScript--函数 作用域 对象

目录 函数 语法格式 示例 定义没有参数列表,也没有返回值的一个函数 定义一个有参数列表 ,有返回值的函数 关于参数个数 函数表达式 作用域 作用域链 对象 基本概念 创建对象 1.使用 字面量 创建对象 2.使用new Object()创建对象 3.使…

SNMP 简单网络管理协议、网络管理

目录 1 网络管理 1.1 网络管理的五大功能 1.2 网络管理的一般模型 1.3 网络管理模型中的主要构件 1.4 被管对象 (Managed Object) 1.5 代理 (agent) 1.6 网络管理协议 1.6.1 简单网络管理协议 SNMP 1.6.2 SNMP 的指导思想 1.6.3 SNMP 的管理站和委托代理 1.6.4 SNMP…

【Zigbee课程设计系列文章】Zigbee开发环境搭建

【Zigbee课程设计系列文章】Zigbee开发环境搭建 前言IAR 下载安装Z-Stack协议栈安装 🎊项目专栏:【Zigbee课程设计系列文章】(附详细使用教程完整代码原理图完整课设报告) 前言 👑由于无线传感器网络(也即…

C语言——枚举类型

📝前言: 在之前的文章中我们已经讲解了自定义类型中的结构体类型和联合体类型,现在我们再充分学习一下C语言中的枚举类型: 1,什么是枚举类型 2,枚举类型的定义和变量的声明 3,对变量进行赋值 &a…

[计算机网络]---网络编程套接字

前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、基础知识…

Android Graphics 图像显示系统 - 开篇

“ 随着学习的不断深入和工作经验的积累,欲将之前在博客中整理的Android Graphics知识做进一步整理,并纠正一些理解上的错误,故开设Graphics主题系列文章 ” 序言 由于工作需要,也源于个人兴趣,终于下决心花时间整理一…

【前端设计】炫酷导航栏

欢迎来到前端设计专栏&#xff0c;本专栏收藏了一些好看且实用的前端作品&#xff0c;使用简单的html、css语法打造创意有趣的作品&#xff0c;为网站加入更多高级创意的元素。 html <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

车载诊断协议DoIP系列 —— DoIP APP车辆识别和声明请求报文

车载诊断协议DoIP系列 —— DoIP APP车辆识别和声明请求报文 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江…

Boost.Asio-使用Boost.Asio和OpenWeatherMap API获取天气的简单示例

OpenWeatherMap API是一个提供天气数据的开放接口&#xff0c;可以通过该接口获取全球范围内的实时天气。 1.获取OpenWeatherMap API的密钥 去官网https://openweathermap.org注册后&#xff0c;自主生成密钥&#xff0c;如图 2.获取用的代码(方法1) #include "stdafx.h&…

BFS与DFS初级练习(排列数字,n-皇后,走迷宫)

BFS与DFS初步了解 DFS&#xff08;深度优先搜索&#xff09;和BFS&#xff08;广度优先搜索&#xff09;是两种常用的图遍历算法。 DFS是一种递归的搜索算法&#xff0c;它从起始节点开始&#xff0c;沿着路径依次访问与当前节点相邻的未访问节点&#xff0c;直到无法继续访问…

[NSSRound#17 Basic]WEB

1.真签到 看robots.txt 密码先base32再base64得到md5加密的密文&#xff0c;在线解得到密码为Nss hint用16进制转字符串&#xff0c;提示新生赛遇到过 是一个敲击码加密 账号是ctfer,登录之后源码提示在F111n4l.php 要求nss参数若比较等于732339662&#xff0c;但是不能是数…