【Three.js基础学习】6.Textrue

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

这段时间没有继续学习,因为清明前公司有个项目把我调到别的项目组帮忙,紧急开发静态页面到甲方展示,上周六加到周三,有点烦躁!还是复习一下纹理的内容 ,以及three.js中各种IPA的应用概念。

课程要点:

    1.关于纹理的概念:

    METALNESS:金属性创建反射等

    normal:法线纹理 与光照有关

    AMBIENT OCCLUSION : 灰度图像,伪阴影

    ROUGHNESS :粗糙度  与光的消失有关

    纹理遵循原则: PBR原则,  物理的渲染(Physically Based Rendering)的缩写

    PBR:主要与金属性和粗糙度有关

    2.如何加载纹理

    TextureLoader // 纹理加载器

    需要了解纹理加载的进度?

    LoadingManager //    加载管理器 用于管理纹理加载的进度,或状态

    方法:onStart  onLoad  onProgress  onError

    3.uv展开

    概念:纹理放到几何体上不是随机的,坐标什么的都是有人定好的

    uv展开之后 会有uv坐标 2*2

    这里可以用缓冲几何体,展示 BoxBufferGeometry()

    4.当我们生成纹理,放到材质之后

    有很多的方法去设置纹理

    5.过滤和MIP映射

    概念:如果我们放大画面,近距离看我们的立方体,会发现纹理是模糊的,这种发生的现象就是

    MIP会发生空间映射,举个例子:GPU对我们的立方体纹理,生成一般的宽高的图片,然后不断重复下去,直到最小值

    6.两种算法 缩小过滤器,放大过滤器实现MIP (在纹理中)

    minFilter , 默认参数是线性,mipmap,线性滤镜

    magFilter ,

    用法: minFilter =  THREE.NearestFilter


 

    THREE.NearestFilter

    THREE.LinearFilter

    THREE.NearestMipmapNearestFilter

    THREE.NearestMipmapLinearFilter

    THREE.LinearMipmapNearestFilter(default)

    THREE.LinearMipmapLinearFilter

    7.纹理格式和优化

    三件事情:纹理的权重,文件的权重,图像的大小,就是分辨率;以及该纹理的数据

    前提:

    文件的大小:最好更小,更好; 可以通过图片压缩来得到更小的图片 如:TinyPNG

    尺寸:GPU能力有限,需要调整纹理,尽可能的小的纹理

    数据:数据存储在像素中,我们需要精确的方向,jpg:有损的,png:数据无损的

    难点在于找到纹理格式和分辨率的正确组合,不然会有很糟糕的性能,画面等

    8.纹理的网站

    poliigon.com

    3dtexture.me

    arroway-textures.ch

    9.制作纹理

    ps    Substance Designer

    补充:

    你可能会看到我写一些类似PlaneBufferGeometry的东西,而不是PlaneGeometry.

    从Three.js的第125个版本开始,那些“缓冲区”几何图形被“非缓冲区”几何图形所取代,你应该在编写它们时去掉Buffer部分。

一、代码

import * as THREE from 'three'
import './style.css'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'



/* 
    Texttures
*/
const LoadingManager = new THREE.LoadingManager()
// LoadingManager.onStart = ()=>{
//     console.log('onStart')
// }
// LoadingManager.onLoad = ()=>{
//     console.log('onLoad')
// }
// LoadingManager.onProgress = ()=>{
//     console.log('onProgress')
// }
// LoadingManager.onError = ()=>{
//     console.log('onError')
// }

const textureLoader = new THREE.TextureLoader(LoadingManager)
const colorTexture = textureLoader.load('/textures/checkerboard-8x8.png')
// const colorTexture = textureLoader.load('/textures/door/color.jpg')
const alphaTexture = textureLoader.load('/textures/door/alpha.jpg')
const heightTexture = textureLoader.load('/textures/door/height.jpg')
const normalTexture = textureLoader.load('/textures/door/normal.jpg')
const ambientOcclusionTexture = textureLoader.load('/textures/door/ambientOcclusion.jpg')
const metalnessTexture = textureLoader.load('/textures/door/metalness.jpg')
const roughnessTexture = textureLoader.load('/textures/door/roughness.jpg')


// colorTexture.repeat.x = 2 // repeat 重复属性
// colorTexture.repeat.y = 3
// // colorTexture.wrapS = THREE.RepeatWrapping // 重复s ,会发现向左,重复复制
// // colorTexture.wrapT = THREE.RepeatWrapping // 重复t ,会发现向左,重复复制
// colorTexture.wrapS = THREE.MirroredRepeatWrapping // 重复s ,会发现向左,重复复制
// colorTexture.wrapT = THREE.MirroredRepeatWrapping // 重复t ,会发现向左,反转复制

// colorTexture.offset.x = 0.5 // 偏移量
// colorTexture.offset.y = 0.5

// colorTexture.rotation = Math.PI / 4 // 二维方向上面旋转 想一个立方体,以左下角为点,旋转
// colorTexture.center.x = 0.5 //想象一个圆圈,中间十字,右边点往上向左旋转
// colorTexture.center.y = 0.5 //想象一个圆圈,中间十字,右边点往上向左旋转

// 使用最小过滤器到最近过滤器时,不需要默认MIP,可以关掉 获取性能
colorTexture.generateMipmaps = false
colorTexture.minFilter = THREE.NearestFilter
colorTexture.magFilter =  THREE.NearestFilter

/**
 * Base
 */
// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()



/**
 * Object
 */
const geometry = new THREE.BoxBufferGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ map:colorTexture })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

/**
 * Sizes
 */
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

/**
 * Camera
 */
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.x = 1
camera.position.y = 1
camera.position.z = 1
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

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

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

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

二、知识点

1.复习一下

上述代码中主要用到的是scene,camera,controls,material,mesh,geometry,render,texture

其中需要配合js进行监听resize 屏幕的尺寸变化,同时获取屏幕的尺寸进行自适应;需要配合requestAnimationFrame进行回调;但是由于camera,也需要自适应更新,需要在监听中执行这个方法updateProjectionMatrix,同时需要渲染器重新触发。

// 屏幕自适应
window.addEventListener('resize',()=>{
     // Update sizes
     sizes.width = window.innerWidth
     sizes.height = window.innerHeight

       // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
 
})

2.Texture

概念:我们需要了解一些纹理的概念,

   METALNESS:金属性创建反射等

   normal:法线纹理 与光照有关

   AMBIENT OCCLUSION : 灰度图像,伪阴影

   ROUGHNESS :粗糙度  与光的消失有关

上述概念根据我的理解应该是各种物体表面的颜色,说实话看到这有点蒙!

2.1 PBR原则 

关于这个原则 纹理遵循原则: PBR原则,  物理的渲染(Physically Based Rendering)的缩写

PBR 主要和金属性和粗糙度

2.2 如何加载纹理

TextureLoader  // 纹理加载器   设想一种场景就是我有了立方体,但是它需要皮肤 (图片需要自己找)

用法:


// 纹理 Textrue
const textureLoader = new THREE.TextureLoader(LoadingManager)
const colorTexture = textureLoader.load('/textures/checkerboard-8x8.png')
const material = new THREE.MeshBasicMaterial({map:colorTexture})

我想知道纹理加载的进度怎么办

LoadingManager // 纹理加载状态

onStart,onLoad,onProgress,onError

我可以设置一些关于纹理的设置

// 关于纹理位置 旋转等属性的操作
// colorTexture.repeat.x = 2
// colorTexture.repeat.y = 2
// colorTexture.wrapS = THREE.RepeatWrapping // 重复s
// colorTexture.wrapT = THREE.RepeatWrapping

// colorTexture.offset.x = 0.5 //偏移量
// colorTexture.offset.y = 0.5

// colorTexture.rotation = Math.PI / 4 // 二维方向上面旋转
// colorTexture.center.x = 0.5  
// colorTexture.center.y = 0.5

2.3 uv展开

    概念:纹理放到几何体上不是随机的,坐标什么的都是有人定好的

    uv展开之后 会有uv坐标 2*2

    这里可以用缓冲几何体,展示 BoxBufferGeometry()

    4.当我们生成纹理,放到材质之后

    有很多的方法去设置纹理

2.4 过滤和MIP映射

    概念:如果我们放大画面,近距离看我们的立方体,会发现纹理是模糊的,这种发生的现象就是

    MIP会发生空间映射,举个例子:GPU对我们的立方体纹理,生成一般的宽高的图片,然后不断重复下去,直到最小值

2.5 缩小过滤器,放大过滤器实现MIP (在纹理中)
 

    minFilter , 默认参数是线性,mipmap,线性滤镜

    magFilter 

colorTexture.generateMipmaps = false
colorTexture.minFilter = THREE.NearestFilter
colorTexture.magFilter =  THREE.NearestFilter

让我们换一个图,看一下没有设置和设置之后的显示

可以看到设置之后会更清晰,物体如刀削般锋利!

2.6 纹理格式和优化

   三件事情:纹理的权重,文件的权重,图像的大小,就是分辨率;以及该纹理的数据

    前提:

    文件的大小:最好更小,更好; 可以通过图片压缩来得到更小的图片 如:TinyPNG

    尺寸:GPU能力有限,需要调整纹理,尽可能的小的纹理

    数据:数据存储在像素中,我们需要精确的方向,jpg:有损的,png:数据无损的

    难点在于找到纹理格式和分辨率的正确组合,不然会有很糟糕的性能,画面等

补充:

    你可能会看到我写一些类似PlaneBufferGeometry的东西,而不是PlaneGeometry.

    从Three.js的第125个版本开始,那些“缓冲区”几何图形被“非缓冲区”几何图形所取代,你应该在编写它们时去掉Buffer部分。


总结

容易忘,都是英文单词,还是要多练习!不然根本不知道用什么方法,只能百度。

  • 29
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值