【ThreeJS基础教程-材质纹理篇】3.2 初识基础网格材质MeshStandardMaterial

学习ThreeJS的捷径

本段内容会写在0篇以外所有的,本人所编写的Threejs教程中

对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久

如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS

  1. 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
  2. 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
  3. 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
    http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
    https://www.wellyyss.cn/ 跃焱邵隼
    http://www.wjceo.com/ 暮志未晚
    这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处

了解材质的基本知识

【ThreeJS基础教程-初识Threejs】1.4.1 更好的视觉效果-使用材质与灯光
在这一篇中,我们提到了标准网格材质MeshStandardMaterial(以下均简称为Standard材质) ,但是仅仅只是在MeshBasicMaterial(以下均简称为Basic材质)的基础上,做了受灯光影响的效果,在后面的学习中,我们又粗略的使用了 transparent和opacity为模型添加透明效果和设置透明度,以及用wireframe来让模型变成线框模式,那么,关于纹理我们还能做什么样的操作呢?

材质继承关系

查阅Threejs文档后,我们发现,几乎所有的材质,都会继承一个Material的类,这个类为所有材质的超类,所以在查阅相关文档时,不仅要查阅对应的材质的文档,还要查阅超类Material的文档

常用的通用材质属性

以下为笔者从文档中提取出的常用和易理解的属性,其余属性将在threejs进阶教程中提及

超类材质的官方文档

属性名默认值官方说明笔者备注
alphaTest0如果不透明度低于此值则不渲染该材质alphaTest常用于处理png贴图的渲染透明错误,特殊情况下也可以用于处理一些透明物体的显示与隐藏,下方演示了aplhaTest的基本用法
depthTesttrue是否在渲染此材质时启用深度测试
depthWritetrue渲染此材质是否对深度缓冲区有任何影响这两个属性都设置为false的时候,渲染的图形将无视位置始终被渲染在屏幕最前方,下面演示了禁用深度写入和深度测试的基本用法
needsUpdatefalse指定需要重新编译材质当你的材质发生大的改变时,比如说更换纹理贴图,修改混合属性后,将它设置为true,当渲染一次后,这个值会恢复为false,用于提醒渲染器这个材质发生了改变
transparentfalse定义此材质是否透明
opacity1.0材质透明度opacity和transparent一般成对出现,transparent设置为false的时候opacity不生效,必须先允许材质透明后,材质才能透明
sideTHREE.FrontSide定义要渲染哪一面,正面背面或两者在之前的BufferGeometry篇里提到,这里渲染的正面,为geometry的面片的面法线方向的面,THREE.Backside为面法线方向的背面,THREE.DoubleSide为双面渲染,下方演示了side的基本用法
visibletrue材质是否可见用于控制部分材质的物体可见与不可见,比如说你的场景用了N个同样材质的物体,你想让这些物体同时消失,一种方法是把这些物体丢进组,然后让组visible = false,另一种方法就是material.visible设置材质不可见

alphaTest的验证和应用

如下代码,当设置到alphaTest大于opacity时,本次材质不会被渲染,下列代码不会有任何结果,但是设置alphaTest < opacity时,box将会出现

    function addMesh(){
        let geometry = new THREE.BoxGeometry(1,1,1);
        let material = new THREE.MeshBasicMaterial({
            alphaTest:0.5,
            opacity:0.4,
            transparent:true,
            color:0xffffff * Math.random()
        });

        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }

alphaTest常用于处理透明度错误,比如说部分纹理贴图使用的是png,并且存在部分透明通道,那么我们可以稍微设置一点alphaTest的值来让透明部分不渲染即可

depthTest和depthWrite应用

当我们不开启深度测试时,物体的渲染就是正常的谁在前渲染谁

    function addMesh(){
        let geometry = new THREE.BoxGeometry(1,1,1);
        let material = new THREE.MeshBasicMaterial({
            color:0xffffff * Math.random(),
            // depthTest:false
        });
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }

效果,注意看,此时我们的网格辅助线,一部分被方块遮挡,这是正常的谁距离近谁在前方的渲染模式
在这里插入图片描述
当设置了禁用深度测试和深度写入后

	//在材质中修改depthTest和depthWrite为false即可
        let material = new THREE.MeshBasicMaterial({
            color:0xffffff * Math.random(),
            depthTest:false,
            depthWrite:false,
        });

在这里插入图片描述
我们的方块就无论如何都在网格辅助线前面

关闭这两个属性,用于创建一些始终在最前方的物体,以及对物体设置透视效果

这两个值笔者在使用时,一般是成对出现,两个都设置为false即可

渲染哪一面Side

为了让效果更明显,这里我们使用相机灯,来增强Standard材质的渲染效果

如果材质不受光照影响,设置渲染哪一面也没有明显的效果

  function init(){
        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({
            alpha:true,
            antialias:true
        });
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);
        camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.01,50000);
        camera.position.set(10,10,10);
        orbitControls = new OrbitControls(camera,renderer.domElement);
        let helper = new THREE.GridHelper(50,10);
        scene.add(helper);
		//添加相机灯
        camera.add(new THREE.PointLight());
        scene.add(camera);

    }
    function addMesh(){
        let geometry = new THREE.BoxGeometry(1,1,1);
        let material = new THREE.MeshStandardMaterial({
            color:0xffffff * Math.random(),
            side:THREE.BackSide
        });
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }

上述代码渲染的效果
在这里插入图片描述
当我们转动视角时,发现,原本正对我们的面,现在均变成了透明,而背对我们的面被渲染了出来

FrontSide 就是正常我们使用材质时,看到的效果
BackSide 是我们只能看到模型的背面,一般用于制作案例时用Box快速做一个小房间效果
DoubleSide 是两个面都会渲染,当你把相机拉入到设置了FrontSide的物体中,你会发现物体竟然就消失了,而当你把相机拉入到设置了BackSide的物体中,你会发现你是处于物体内部的,而DoubleSide是综合了两者后的效果

DoubleSide常用于渲染一些单面片但是要两面都显示的物体,比如说简单的树木花草,单面片的玻璃墙面等等

常用的Standard材质属性

属性名默认值官方说明笔者备注
color白色0xffffff材质的颜色标注是材质颜色,其实是当颜色贴图map为null时渲染的颜色,如果颜色贴图map不为null,则这里的颜色会与颜色贴图map的颜色叠加
mapnull颜色贴图简单说就是最基本的贴图,当你的map不为null时,颜色应设置为白色以防止颜色叠加出现颜色错误问题
metalness0材质与金属的相似度Standard材质的核心之一,基本上好看的效果都要依赖调节这个属性和下方的roughness,下面演示了metalness的基本用法
metalnessMapnull金属度贴图简单说就是用一张贴图来控制金属度,而不用metalness来控制,此贴图一般由建模师提供
roughness1.0材质的粗糙程度StandardMaterial的核心之一,下面演示了roughness的基本用法
roughnessMapnull粗糙度贴图简单说就是用一张贴图来控制粗糙度,而不用roughness来控制,此贴图一般由建模师提供
wireframefalse将几何体渲染为线框简称线框模式,线框模式用于查看模型的点线信息,一般用于检查模型或给模型添加基本的边线,在文档中还有三条关于wireframe的属性,wireframeLinecap,wireframeLineJjoin,wireframeLineWidth,都是在wireframe为true时生效

修改颜色Color

我们是可以在创建material的时候,直接通过写16进制数字或者css颜色代码来修改它的颜色的,但是,后续我们要更改颜色时,则不能这样写

    function addMesh(){
        let geometry = new THREE.BoxGeometry(1,1,1);
        let material = new THREE.MeshStandardMaterial({
            color:0xffffff * Math.random()
        });
        //错误的颜色修改方式
        material.color = 0xff0000;
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }

上述写法会导致物体变成一团黑,因为Standrad材质的Color是THREE.Color对象

正确的颜色修改方式

	//这里的参数可以为16进制数字,基本css颜色样式
    material.color = new THREE.Color(0xff0000);

metalness和roughness的组合效果

这里我们以官方案例为例
在这里插入图片描述
当roughness为0时,此时材质的反光效果达到最佳

在这里插入图片描述
当roughness为0,metalness最高时,物体效果最接近不锈钢金属

在这里插入图片描述
细微调节后,颜色为白色,metalness为 0.288,roughness为0时,物体效果最接近陶瓷

在这里插入图片描述

开启transparent,透明度设置为0.68,metalness设置为0.593时,此时物体最接近白色玻璃

一般关于材质的属性,我们都是会借助lil.gui或者dat.gui,或者自定义gui来调整,0.1的差距就可能让物体显示效果出现差别,所以这里从来没有固定值

以上的代码极其简单,理解上述两个属性比在代码中使用更为重要

        let material = new THREE.MeshStandardMaterial({
            color:0xffffff * Math.random(),
            roughness:0.5,
            metalness:0.5
        });

roughness和metalness这两个值基本可以调节出任何我们想要的基本物体效果

同时,standardMaterial还提供了众多可以再提升物体效果的属性,这些属性将在下一篇展开讲解

下一篇预告

MeshStandardMaterial进阶

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值