纹理(texture)

为什么要用贴图:为了压缩数据和节省运算资源,如果直接扫描3D物体,就有特别多的面
减少渲染的面,仍然保证较高的还原度
 
纹理都是基于图片的,覆盖在几何体的表面,根据UV来覆盖
 
透明贴图: 黑白色 黑色透明,白色不透明
置换贴图: 顶点根据颜色上下移动
      黑色的凹进去 白色最突出 灰色一般突出
                   实际上移动顶点实现效果 默认突出程度为 1,门的大小也是1。如果长宽高为1 就太突出了,细分度越高 突出的越规则
 
法线贴图:定义光线的反射。 顶点不会移动,不需要很多顶点,所以性能较好
       法线贴图和粗糙度贴图 没啥相关,粗糙度只是看起来的样子和 反射没有关系
       法线才和反射有关 门的各个部分 反射情况应该不同
 
环境遮挡贴图:添加假阴影 都是假的,需要第二组uv贴图
                        看起来图片的各个地方不同 白色区域不变深色区域遮挡 需要第二组uv变量
 
环境纹理 周围的内容 贴在 金属球面上
 
设置周围的环境
scene.background 给场景添加背景 但是 没有贴图,没有光照也可以,下面的必须要有光
scene.environment 给所有的物体添加默认的环境贴图
 
MeshStandardMaterial 必须要设置 金属度和粗糙度
 
mapping
texture.mapping = THREE.EquirectangularReflectionMapping // 修改纹理映射 否则当做一张图片
 
HDR图 不是分成6个面
类似 一个球 然后展开成一张图
HDR处理: 多个图不同的曝光程度,就有更多的细节 然后合成一张图
这样的图片质量比较高 RGBELoader 加载器加载图片
图片比较大 一般异步加载
因为它并不是6张图,所以需要手动告诉 mapping 映射
经纬映射贴图 相当于被一个圆柱包裹的圆球
 
金属贴图:主要用于金属 金属可能比较粗糙
用来反射光的,显示金属的部分,可以明显看出各个地方对光的反射不同,可以看出后面是什么东西
除了金属的部门其他地方都是黑色的,所以这些地方的反射不起作用
就需要配合粗糙度贴图一起使用
 
粗糙度贴图:
roughness 为0 表示足够光滑,可以直接发生反射
如果单独设置某一位置 的粗糙度,就可以使用此贴图
 
也可以自定义贴图
 
PBR原则:主要是金属度和粗糙度
模拟生活中产生真实的效果
 
如何加载图片 在webpack中可以当作模块引入
也可以直接放在 /public 目录下 根目录访问 名称也不会被修改
image.onload 也可以使用 addEventListener
我们不能直接使用 image 对象 我们需要将其转化为 纹理对象
会被转化成 另一种 GPU友好的格式(format)
const texture = new Texture(image) 如果此时image没有加载完
texture.needsUpdate = true 在加载完的地方写上即可
背后就是这么干的
 
也可以使用TextureLoader 来创建Texture 里面还可以写 加载错误的处理
loader.load(url, successFunc, onprogress, error)
 
loadingManage.onStart/onLoaded/onProgress/onError
 
UV 展开
纹理是怎么贴到 几何体上的,就是根据UV
每个顶点都必须在正方形的坐标
attribute里面的uv坐标就是用于定位texture
3d软件上或者自定义图形 需要自己设置UV
 
贴图变换
repeat / center / offset
变换 repeat wrapS / wrapT 镜像的repeat一般是 偶数
offset 左下移动 作用于整个纹理,而不是repeat的小部分
rotation 旋转 默认是左下角为旋转中心
center 设置旋转中心
 
mip mapping 技术原理
创造一个一半大小的texture版本,再一半大小的版本,直到1*1大小的版本
这些texture将被送到GPU
 
单一纹理 幸运的是我们不会出现这种情况
如果纹理是长方形的,就会找出最大正方形
 
为什么GPU需要这些不同版本的texture
取决于我们能看到多少像素,这就是我们很近看纹理很模糊的原因
因为如果很小的几何体尺寸,我们不需要用到那么大的纹理去包裹
所以我们用的是很小的版本,这就是模糊的原因
minFilter 用于纹理的像素 小于渲染的像素,用于缩小物体时得到非常小的照片 6个值,这个时候使用的纹理就没必要使用那么大的纹理了,所有大的图片信息都挤在小块地方
NearestFilter 下面的几个都差不多,主要差别是第一个 放大也会很清晰
LinearFilter
NearestMipmapNearestFilter
NearMipLinearFilter
LinearMipNearestFilter
LinearMipmapLinearFilter 默认 区别在于模糊程度
因为很大的物体你在缩小的后,不需要看的很清楚
只需要放大的时候看的清楚就可以了,比较符合日常 性能不好
因为需要生成很多的小版本
 
当图片不是足够大的时候,放大物体,会显得模糊
当我们使用NearestFilter 我们不需要 mipMaping
不但得到更小的版本 colorMap.generateMipmaps = false 在设置minFilter之前
 
magFilter 放大的足够大时,显示会被拉伸 显示的非常模糊
很小的时候,不需要看的很清楚
NearestFilter 就会变得很清晰 性能好 不管是min/mag,因为不需要 mip Mapping
但是不太符合常规
LinearFilter 因为很小的物体,你也不需要看的很清楚
 
colorTexture.magFilter = THREE.NearestFilter // 当原始图片很小的时候,显示清楚的设置
colorTexture.minFilter = THREE.NearestFilter // 当原始图片很大的时候,显示清楚的设置
怎么理解:当一个很小的物体 需要放大显示清楚的时候 怎么显示清楚
当一个很大的物体 需要缩小显示的时候 512 / 256 / 128 / 64 / 32 尺寸不断缩小 所显示的样子 该怎么显示
 
 
the weight 尽可能用小的图片
this size 尺寸 应该尽可能小 这样就可以尽快加载处理 这对GPU有好处
this data
jpg 压缩大 更小
png 压缩小 更大 还有一种格式大小特别小basis
可以对图片进行压缩 在tinyPng.com网站上
 
因为要mip mapping 所以尽量 大小是 2的次方,这样才不会resize你的图片
才能正常 mip mapping,这就造成的额外时间的浪费
自动生成的mipmapping增加了必须存储的像素数。大概是原图片的2倍
512*512 / 1024*1024 / 512*2048
如果不是 会尽量 扩展到2的次方大小
 
当你想用一张图片,代替color和alpha2个贴图的话,最好使用png,因为 jpg不支持透明度,png支持 transparent
因为你可以合并不同的数据到一个texture中,通过使用红绿蓝和alpha

蓝(边框) 红(image) 绿(阴影)

地形项目 也可以类似这样做
 
当你使用法线贴图,最好使用 png,因为要反应各个地方的反射
数据要精确
 
substance3d.com designer 创建自己的texture
 
quixel bridge 虚幻引擎
 
 
posted @ 2023-04-10 16:23  escapist  阅读(165)  评论(0编辑  收藏  举报