【Three.js】第十二章 Materials 材质

2023-10-31

12.Materials 材质

介绍

材质用于为几何体的每个可见像素着色。
决定每个像素颜色的算法属于着色器中编写的。编写着色器是 WebGL 和 Three.js 最具挑战性的部分之一,但不要担心;Three.js 有许多带有预制着色器的内置材质。
我们将在以后的课程中探索如何创建我们自己的着色器。现在,让我们使用 Three.js 自带材料。

Setup 设置

启动器不包含任何对象。这是一个很好的机会来修改创建网格的基础知识。

准备我们的场景

为了测试材质,我们应该准备一个可爱的场景并加载一些纹理。
创建由 3 种不同几何体(一个球体、一个平面和一个环面)组成的 3 个网格体,并在所有 3 个几何体上使用相同的 MeshBasicMaterial。是的,您可以在多个网格体上使用一种材质。移动左侧的球体和右侧的环面以将它们分开。
add(...)方法支持一次添加多个对象:

/**
 * Objects
 */
const material = new THREE.MeshBasicMaterial()

const sphere = new THREE.Mesh(
    new THREE.SphereGeometry(0.5, 16, 16),
    material
)
sphere.position.x = - 1.5

const plane = new THREE.Mesh(
    new THREE.PlaneGeometry(1, 1),
    material
)

const torus = new THREE.Mesh(
    new THREE.TorusGeometry(0.3, 0.2, 16, 32),
    material
)
torus.position.x = 1.5

scene.add(sphere, plane, torus)


tick我们现在可以像在动画课上那样在函数上旋转对象:

/**
 * Animate
 */
const clock = new THREE.Clock()

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()

    // Update objects
    sphere.rotation.y = 0.1 * elapsedTime
    plane.rotation.y = 0.1 * elapsedTime
    torus.rotation.y = 0.1 * elapsedTime

    sphere.rotation.x = 0.15 * elapsedTime
    plane.rotation.x = 0.15 * elapsedTime
    torus.rotation.x = 0.15 * elapsedTime

    // ...
}

tick()

你应该看到你的 3 个物体在缓慢旋转。
我们将要发现的材料以许多不同的方式使用纹理。让我们像在纹理课程中所做的那样使用TextureLoader加载一些纹理。
所有纹理图像都位于该/static/textures/文件夹中。现在,我们将加载/static/textures/door/文件夹中的所有门纹理、/static/textures/matcaps/文件夹中的第一个 matcap 纹理和/static/textures/gradients/文件夹中的第一个渐变纹理。
确保在material实例化之前这样做:

/**
 * Textures
 */
const textureLoader = new THREE.TextureLoader()

const doorColorTexture = textureLoader.load('/textures/door/color.jpg')
const doorAlphaTexture = textureLoader.load('/textures/door/alpha.jpg')
const doorAmbientOcclusionTexture = textureLoader.load('/textures/door/ambientOcclusion.jpg')
const doorHeightTexture = textureLoader.load('/textures/door/height.jpg')
const doorNormalTexture = textureLoader.load('/textures/door/normal.jpg')
const doorMetalnessTexture = textureLoader.load('/textures/door/metalness.jpg')
const doorRoughnessTexture = textureLoader.load('/textures/door/roughness.jpg')
const matcapTexture = textureLoader.load('/textures/matcaps/1.png')
const gradientTexture = textureLoader.load('/textures/gradients/3.jpg')

为确保所有纹理都加载良好,您可以使用属性在材质上使用它们map,正如我们在纹理课程中看到的那样。

const material = new THREE.MeshBasicMaterial({ map: doorColorTexture })


到目前为止,我们只使用了 MeshBasicMaterial 它在我们的几何体上应用了统一的颜色或纹理。
如果您在Three.js 文档中搜索“material” ,您会发现有很多我们可以使用的类。让我们都试试看。

网格基础材质

MeshBasicMaterial可能是最“基本”的材质……但是还有很多我们还没有涉及的属性。
您可以在MeshBasicMaterial实例化前,材质参数传入的对象中设置其中的大部分属性,但您也可以直接在实例上更改这些属性:

const material = new THREE.MeshBasicMaterial({
    map: doorColorTexture
})

// Equals
const material = new THREE.MeshBasicMaterial()
material.map = doorColorTexture

我们将使用第二种方法,但您可以随意使用。

map 地图

map属性将在几何体表面应用纹理:

material.map = doorColorTexture

color 颜色

color属性将在几何体表面应用统一的颜色。当您直接更改color属性时,您必须实例化一个Color类。您可以使用许多不同的格式:

material.color = new THREE.Color('#ff0000')
material.color = new THREE.Color('#f00')
material.color = new THREE.Color('red')
material.color = new THREE.Color('rgb(255, 0, 0)')
material.color = new THREE.Color(0xff0000)


结合colormap用颜色为纹理着色:

material.map = doorColorTexture
material.color = new THREE.Color('#ff0000')

wireframe 线框

无论相机的距离如何,该wireframe属性都会用 1px 的细线显示构成几何体的三角形:

material.wireframe = true

opacity 不透明度

opacity属性控制透明度,但要正常工作,您应该将transparent属性设置为true以通知 Three.js 此材质现在支持透明度:

material.transparent = true
material.opacity = 0.5

alphaMap 阿尔法地图

现在透明度开始工作了,我们可以使用该alphaMap属性来控制纹理的透明度:

material.transparent = true
material.alphaMap = doorAlphaTexture

side 边

side属性可让您决定面部的哪一侧可见。默认情况下,正面是可见的 ( THREE.FrontSide),但您可以改为显示背面 ( THREE.BackSide) 或同时显示背面 ( THREE.DoubleSide):

material.side = THREE.DoubleSide

您应该看到曲面的的正面和背面。
尽量避免使用**THREE.DoubleSide**因为渲染两侧意味着要渲染两倍以上的三角形。
其中一些属性类似于wireframeopacity可以与其他类型的材料一起使用。我们不会每次都重复这些。

MeshNormalMaterial 网格法线材质

MeshNormalMaterial显示漂亮的紫色、蓝色、绿色,看起来像我们在纹理课程中看到的法线纹理这并非巧合,因为两者都与我们所说的法线有关:

const material = new THREE.MeshNormalMaterial()


法线是在每个顶点中编码的信息,包含面部外侧的方向。如果将这些法线显示为箭头,您会得到从组成几何体的每个顶点出来的直线。

您可以将法线用于许多事情,例如计算如何照亮面部或环境应如何在几何体表面反射或折射。
使用MeshNormalMaterial时,颜色将仅显示法线相对于相机的方向。如果围绕球体旋转,您会发现颜色始终相同,无论您正在查看球体的哪个部分。
虽然您可以使用我们在MeshBasicMaterial中发现的一些属性,例如wireframe、transparent、opacity和side,但您还可以使用一个新属性,称为:flatShading

material.flatShading = true


flatShading将使面变平,这意味着法线不会在顶点之间进行插值。
MeshNormalMaterial可用于调试法线,但它看起来也很棒,您可以像 ilithya 在她的作品集https://www.ilithya.rocks上所做的那样使用它。

MeshMatcap材质

MeshMatcapMaterial是一种很棒的材料,因为它看起来很棒,同时又非常高效。
为了使其工作,MeshMatcapMaterial需要一个看起来像球体的参考纹理。

然后材质将根据相对于相机的法线方向在纹理上拾取颜色。
要设置该参考 matcap 纹理,请使用以下matcap属性:

const material = new THREE.MeshMatcapMaterial()
material.matcap = matcapTexture


网格看起来会被照亮,并且反射光泽,但它只是一个看起来像金属的纹理。
唯一的问题是无论相机方向如何,错觉都是一样的。此外,您无法更新灯光,因为没有灯光。
尝试文件夹上可用的不同纹理/static/textures/matcaps/(只是下面一行之一):

const matcapTexture = textureLoader.load('/textures/matcaps/2.png')
const matcapTexture = textureLoader.load('/textures/matcaps/3.png')
const matcapTexture = textureLoader.load('/textures/matcaps/4.png')
const matcapTexture = textureLoader.load('/textures/matcaps/5.png')
const matcapTexture = textureLoader.load('/textures/matcaps/6.png')
const matcapTexture = textureLoader.load('/textures/matcaps/7.png')
const matcapTexture = textureLoader.load('/textures/matcaps/8.png')


关于在哪里可以找到 matcaps 纹理,您可以像任何类型的纹理一样在网络上进行简单的搜索。如果不是供个人使用,请确保您有权使用该纹理。还有这个庞大的 matcaps 列表:https

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Three.js】第十二章 Materials 材质 的相关文章

  • JavaScript“类”的规范术语[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 这是一个在 JavaScript 中定义 类 创建它的实例并调用它的方法 函数之一的简单示例 Define a class like this
  • 如何将 UIWebView 中的输入的键盘按钮“返回”更改为“搜索”?

    我有一个简单的 HTML 文件 它将显示在 UIWebView 中 p p
  • 使用 Selenium + JavaScript 或 WebDriverJS 在浏览器中执行 JavaScript

    经过很多天的大量搜索后 我在这里寻求帮助 我们有一个使用 javascript selenium webdriverjs 的设置 我们想要在通过 selenium 打开的浏览器中传递数据 简单来说 我们希望在浏览器中执行任何类型的 Java
  • ExtJs4 Json TreeStore?

    我正在将 ExtJs3 应用程序迁移到 ExtJs4 在 ExtJs3 中 我有一个树网格 它有一个加载器来加载树数据 如下所示 loader new Ext tree TreeLoader dataUrl Department Depar
  • Angular JS - 如何验证数字输入中的位数

    我们想要做的是 有一个仅接受 0 24 的输入 对于时间输入应用程序 这些是用户应该能够输入到输入中的值 0 1 2 3 4 5 6 7 8 9 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
  • javascript 中的类型安全或如何避免很难检测到类型相关的错误

    我来自 Java 世界 即类型安全的世界 现在正在做一些需要使用 JavaScript 进行客户端执行的事情 由于 JS 的非典型化 我有时会遇到很难检测到错误的情况 我想知道是否有任何方法可以提前阻止它 例如 设置诸如 使用典型化 之类的
  • 使用 vue.js 显示 json 结果

    您好 我尝试使用 vue js 显示 json 文件结果 目标是结果将显示在值上 这是我的代码 data return fetchData function var self this self http get api casetotal
  • 如何在 guildMemberAdd 中使用awaitReactions

    当用户连接到我的服务器时 我向他们发送消息 并且我想通过单击反应来继续授权 我怎样才能创建这个 我正在使用以下代码 robot on guildMemberAdd gMembAdd gt gMembAdd send Hi gMembAdd
  • 使用 JS 和 HTML 将当前 URL 插入链接

    所以 我已经阅读了类似的内容 但我仍然找不到更适合我正在做的事情的答案 我正在尝试使用 JS 获取当前页面 URL 并将其附加到社交媒体共享链接 如下所示 a href target blank 使用 Javascript 我成功地将当前
  • 仅返回 JavaScript 字符串中最后一个下划线之前的文本

    如果我有一个像这样的字符串 var str Arthropoda Arachnida Zodariidae Habronestes hunti 如何获取最后一个下划线之前的字符串的第一部分 在这种情况下我只想 Arthropoda Arac
  • 错误:导航器只能包含“屏幕”组件作为其直接子组件

    我是 React Native 新手 收到此错误 但无法解决它 我正在遵循主要的教程反应导航页面 https reactnavigation org docs screen options resolution 但我无法完成它 我将不胜感激
  • 如何从回调函数中获取值

    我对 javascript 比较陌生 并且面临一些困难 我有两个 java 脚本文件 如下所示 我无法获取变量的值条目标题在 getRss 函数内并将其存储在变量内Rss1 标题 and Rss2 标题 创建一个全局变量并将其分配给条目标题
  • 更改导航栏悬停时 div 的背景图像

    我正在开发一个项目 我对 Javascript 很陌生 所以我想知道是否有 Jquery 代码或只是一个关于如何使背景图像在导航菜单悬停时更改的过程 例如将鼠标悬停在链接一上会将 div 的背景图像更改为图像 1 将鼠标悬停在链接二上会将
  • 如何使 Loopback 模型事件起作用?

    我尝试过一个例子http apidocs strongloop com loopback model http apidocs strongloop com loopback model MyModel on changed functio
  • 调整发散堆积条形图以使用通用更新模式

    我一直在使用可用的堆积条形图示例here https bl ocks org mbostock b5935342c6d21928111928401e2c8608使用以下代码 var data month Q1 2016 apples 384
  • 按位非运算符

    为什么要按位运算 0 打印 1 在二进制中 不是0应该是1 为什么 你实际上很接近 在二进制中 不是0应该是1 是的 当我们谈论一位时 这是绝对正确的 然而 一个int其值为0的实际上是32位全零 将所有 32 个 0 反转为 32 个 1
  • ajax - 检查用户名是否存在+如果存在则返回消息

    我试图检查用户想要的用户名是否已被使用 而无需发送表单 基本上是用户名字段的模糊 我遇到了一些麻烦 有几个问题 我有我的输入字段加上js
  • 同步通用分析

    新的Universal Analytics重新引入了同步事件跟踪 https developers google com analytics devguides collection analyticsjs method reference
  • jQuery 存储类型未定义

    我用了一个jQuery 存储 https ui5 sap com api jQuery sap storage存储数据 oStore jQuery sap storage jQuery sap storage Type local oSto
  • 获取不正确的日期,将时间戳转换为新日期

    我正在尝试将时间戳转换为日期 但得到的日期不正确 我正在开发一个使用 Angular 和 Typescript 的项目 我有这样的时间戳 1451642400 2016年1月1日 和1454320800 2016年2月1日 如果我编码 da

随机推荐

  • 阿里云STS获取临时授权

    获取阿里云oss授权 public function sts url https sts aliyuncs com action AssumeRole RoleArn rolearn RoleSessionName client Durat
  • STM32-FreeRTOS源码下载及移植步骤(基于Keil)

    FreeROTS源码获取及基于Stm32移植 获取源码 其实找资料没有那么复杂 官网就是最好的地方了 FreeRTOS的官网是 FreeRTOS官网 当然了 这个网站是全英文的 不过没关系 我们可以简单了解一下 如下图 在这个网页里点击左侧
  • 快速安装最新版Burp Suite Professional

    官网下载链接 https portswigger net burp releases JDK 官方下载 https www oracle com java technologies downloads jdk19 windows 一路默认安
  • 文件的流

    一 文件名词解释 文件 是存贮在某种介质上的 如磁盘 磁带等 并具有文件名的一组有序信息的集合 流设备 大多数的字符设备 如键盘 打印机等 传输的信息均由 一组顺序出现的字符序列组成 文件系统 操作系统对系统的软件资源 不论是应用软件和系统
  • IDEA 项目突然出现异常无法启动时的有效解决办法 ...

    解决方法有效的前提是 项目本身是可以正常启动的 但是因为某些原因无法正常启动 原因包括但不限于以下几种 不小心删除了项目中的文件 导致无法启动 项目很久没更新 更新之后 导致无法启动 项目更新之后出现很多报错信息 导致无法启动 通常做法 根
  • 抖音、快手、B站的广告投放原理

    抖音 快手 B站的广告投放原理 文章目录 抖音 快手 B站的广告投放原理 TOC 文章目录 广告投放原理 编者按 本文来自微信公众号 鸟哥笔记 ID niaoge8 节选自 信息流广告入门 作者 宁阿姨 作者写的挺到位的 相互学习 共同进步
  • Unity网络编程之Photon Server(四)

    前言 上篇我们学习了Unity客户端如何和Photon服务器建立连接 这篇是如何与服务器进行数据的交互 惯例 基于上篇的服务器项目MyGameServer Unity客户端项目进行进一步的学习 客户端与服务器交互流程图解 前面我们有谈到 当
  • MySQL语句优化

    文章目录 1 MySQL的执行顺序 2 基础SQL优化 2 1建表优化 使用varchar代替char 使用 数值 代替 字符串 类型 字段设置为not null 批量插入性能提升 2 2查询优化 select 具体字段 避免在where子
  • 关于Adams View Error MSC_LISENSE_FILE=D:\MSC.......证书错误的解决方案

    首先右键我的电脑 gt 属性 gt 高级系统设置 gt 环境变量 gt 变量名字MSC LICENSE FILE 变量值是lisense dat的地址 在上述操作完成后将lisense dat的名字改为lisense lic
  • String部分方法

    package com javahexin hexin public class string public static void main String args String str dadad String str1 str 判断两
  • 第二十章 Spring5.X bean 的⽣命周期和⼆次处理

    1 Spring bean的 命周期 的init和destroy 法 2 bean的 次加 Spring5 x后置处理器 BeanPostProcessor 什么是BeanPostProcessor 是Spring IOC容器给我们提供的
  • Linux 查看各文件夹大小命令du -h --max-depth=1

    Linux 查看各文件夹大小命令du h max depth 1 du abcDhHklmsSx L lt 符号连接 gt X lt 文件 gt block size exclude lt 目录或文件 gt max depth lt 目录层
  • mysql -n_mysql top n 问题

    日常工作中 经常要查询分组的前几名或查询数据的前几条记录 第5条到第十条 等 TOP N分析法就是通过TOP N算法从研究对象中得到所需的N个数据 并从排序列表中选取最大或最小的N个数据 这就是一个TOP N算法 mysql中用limit
  • (6/300)一阶线性非齐次常微分方程的通解

    一阶线性非齐次常微分方程的通解 首先应该认识方程的形式 dy dx P x y Q x 然后就来思考怎么去解这个方程了 我们最终希望是得到一个y f x 的形式 怎么解呢 先通过线性代数的知识进行引入 求AX b的通解 那么我们先求得A 0
  • MATLAB 信号处理仿真入门实验

    MATLAB 信号处理仿真入门实验 实验目的 熟悉 Matlab 工具的基本用法 掌握 Matlab 代码编写方法 理解序列的离散时间傅里叶变换 理解 DFT 结果的频谱能量泄露 理解 DFT 和 DTFT 的对应关系 理解信号加窗的作用
  • ReactNative入门(一)——环境搭建及第一个RN项目—HelloWorld

    ReactNative入门 本篇以及接下来的几篇有关RN的文章 是默认你对前端相关知识如Node React 以及原生移动端Android可以熟练使用的情况下 最起码达到了解会用的程度 为前提的 不然你就需要先去了学习前端 React为主
  • 图片加载框架-Picasso最详细的使用指南

    写在前面 Android 中有几个比较有名的图片加载框架 Universal ImageLoader Picasso Glide和Fresco 它们各有优点 以前一直用的是ImageLoader 做项目中的图片加载 由于作者宣布ImageL
  • 全国职业技能大赛云计算--高职组赛题卷⑤(容器云)

    全国职业技能大赛云计算 高职组赛题卷 容器云 第二场次题目 容器云平台部署与运维 任务2 基于容器的web应用系统部署任务 15分 任务3 基于容器的持续集成部署任务 15分 任务4 Kubernetes容器云平台部署与运维 15分 本任务
  • 目标检测算法部署网页web端2-点击按钮加载本地图像

    上一篇写了页面的html 目标检测算法部署网页web端1 这篇加个如何点击图像加载按钮 显示在页面上 效果如下 代码如下 b b
  • 【Three.js】第十二章 Materials 材质

    12 Materials 材质 介绍 材质用于为几何体的每个可见像素着色 决定每个像素颜色的算法属于着色器中编写的 编写着色器是 WebGL 和 Three js 最具挑战性的部分之一 但不要担心 Three js 有许多带有预制着色器的内