Threejs材质的使用

前言:材质就像物体的皮肤,决定几何体的外表。例如:定义一个几何体看起来是否像金属,透明与否,或者显示为线框,得到THREEJS.Mesh对象添加到Threejs渲染的场景中。

创建三维对象主要使用的材质:

MeshBasicMaterial(网格基础材质)可赋予简单颜色
MeshDepthMaterial(网格深度材质)根据摄像机距离进行调色
MeshNormalMaterial(网格法向材质)根据法向量计算物体颜色
MeshLambertMaterial(网格Lambert 材质) 考虑光照影响的材质,用于创建不光亮的物体
MeshPhongMaterial(网格 Phong式材质) 考虑光照影响的材质,用于创建光亮的物体
MeshStandardMaterial(网格标准材质)它能够计算出表面与光线的正确互动关系,从面便 染出的物体看起来更加真实(新)
MeshPhysicalMaterial(网格物理材质)这是MeshPhongMaterial的扩展材质(新)
MeshToonMaterial(网格卡通材质) MeshPhongMaterial的扩展材质,更卡通化
ShadowMaterial(阴影材质)专门用于接收阴影图的特殊材质。在该材质中只有 阴影图像,非阴影部分为完全透明的区域
ShaderMaterial(着色器材质)这种材质允许使用自定义的着色器程序,直接控制顶点的放置方式及像素的着色方式
LineBasicMaterial(直线基础材质)这种材质可以用于THREE.Line(直线)几何体,用来创建着色的直线
LineDashMaterial(虚线材质)

创建出一种虚线的效果 

一、材质的属性

        Three.js 提供了一个材质基类 THREE. Material,它列出了所有的共有属性。这些共有属性分成了三类,如下所示:
基础属性 : 这些属性是最常用的。通过这些属性,可以控制物体的不透明度、是否可见以及如何被引用(通过ID或是自定义名称)。
融合属性 : 每个物体都有一系列的融合属性。这些属性决定了物体如何与背景融合。

高级属性 : 有一些高级属性可以控制底层WebGL上下文对象渲染物体的方式。大多数情况下是不需要使用这些属性的。

基础属性这里就不罗列了,需要可以查看源码

//材质的共有属性
THREE.Material = function () {
    
	Object.defineProperty( this, 'id', { value: THREE.MaterialIdCount ++ } );

	this.uuid = THREE.Math.generateUUID();

	this.name = '';
	this.type = 'Material';

	this.side = THREE.FrontSide;

	this.opacity = 1;
	this.transparent = false;

	this.blending = THREE.NormalBlending;

	this.blendSrc = THREE.SrcAlphaFactor;
	this.blendDst = THREE.OneMinusSrcAlphaFactor;
	this.blendEquation = THREE.AddEquation;

	this.depthTest = true;
	this.depthWrite = true;

	this.polygonOffset = false;
	this.polygonOffsetFactor = 0;
	this.polygonOffsetUnits = 0;

	this.alphaTest = 0;

	this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing 
    //antialiasing gaps in CanvasRenderer

	this.visible = true;

	this.needsUpdate = true;

};

二、THREE.MeshBasicMaterial(网格基础材质)

              MeshBasicMaterial是一种基础材质,不考虑场景中是否有光照影响。一般使用该材质的网格会被渲染成基础几何,也可显示边框使用。

在使用该材质时常用属性通常对以下属性进行调试:

    var meshMaterial = new THREE.MeshBasicMaterial({
            color: 0x7777ff,
            //wireframe : true,                //开启wireframe属性,将模型渲染成线框
            //opacity : 0.01
            //wireframeLinewidth: 20           //测试线宽,看不出变化
            //name : 'Material-1',
            //transparent: true,               //开启透明度
            //opacity : 0.5                    //设置透明度(0-1)
        });

实例 : 

 可通过插件GUI对网格对象属性进行调试,该实例中并未添加光照(不受光照影响)。

三、THREE.MeshDepthMaterial(联合材质)

MeshDepthMaterial材质无法设置对象颜色,通过设置多种材质用以改变物体颜色。该方案又称联合材质。

创建方案: 

 //Math.ceil()  “向上取整”, 即小数部分直接舍去,并向正数部分进1
               //Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值
              var cubeSize = Math.ceil(3 + (Math.random() * 3));  //cubeSize随机 3 4 5 6
                var boxGeometry = new THREE.BoxGeometry(cubeSize,cubeSize,cubeSize);
                var meshDepthMaterial = new THREE.MeshDepthMaterial();
                var meshBasicMaterial = new THREE.MeshBasicMaterial({
                    color: controls.color,
                    transparent: true,
         //材质融合MultiplyBlending将前景色与背景色(MeshDepthMaterial渲染的方块)相乘
                    blending: THREE.MultiplyBlending
                });
                //混合材质创建网格
                //顺序不要放错
                var cube = new THREE.SceneUtils.createMultiMaterialObject(boxGeometry,[meshBasicMaterial,meshDepthMaterial]);
                //将第一种材质对象缩小,解决闪光现象
                //闪光现象 : 当一个物体作用在另一个物体上时,并且有一个物体是透明的,存在这种现象
                cube.children[1].scale.set(0.99, 0.99, 0.99);
                cube.castShadow = true;

                // position the cube randomly in the scene
                //Math.round()  “四舍五入”, 该函数返回的是一个四舍五入后的的整数
                cube.position.x = -60 + Math.round((Math.random() * 100));
                cube.position.y = Math.round((Math.random() * 10));
                cube.position.z = -100 + Math.round((Math.random() * 150));

                scene.add(cube);

一般项目建模型时经常使用联合材质,概念要清晰。感兴趣的话可以自己测试一下,注意可能会出现闪光,个人理解是两个Mesh没有重合好。解决的话需要缩小一个即可。

四、THREE.MeshLambertMaterial(网格Lambert 材质) 

        MeshLambertMaterial(常用)用于创建暗淡不光亮的表面。而且会对场景中的光源产生反应。MeshLambertMaterial材质的独有属性搭配基础属性适用于多种场景。

        MeshLambertMaterial材质的常用属性:

color材质的环境色(会与环境光颜色相乘)
emissive(自发光)并非光源,在暗处也可见

创建方式:

var meshMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});

展示效果:

五、THREE.MeshPhongMaterial(网格 Phong式材质) 

           MeshPhongMaterial可以创建光亮的材质,与MeshLambertMaterial属性基本一样,不同的是通过MeshPhongMaterial可以实现高光效果。该材质下的模型既可以模拟金属质感的物体,还可以模拟塑料质感的物体。

MeshPhongMaterial材质的常用属性:

color材质的环境色(会与环境光颜色相乘)
emissive(自发光)并非光源,在暗处也可见
specular(高光颜色)指定该材质的光亮程度及高光部分颜色
shiness(高光度)镜面高光的清晰程度(默认30)光滑度高的表面清晰度高

 创建方案:

var material = new THREE.MeshPhongMaterial({
            color:  0x7777ff
        });

 常用属性方式:

 var controls = new function (){
            this.transparent = false;
            this.opacity = 1;
            this.visible = true;
            this.ambient = 0x0c0c0c;
            //材质自身颜色不受光照影响
            this.emissive = material.emissive.getHex();
            //高光  即可模仿塑料质感  又可模仿金属质感
            this.specular = material.specular.getHex();
            //高光部分轮廓的清晰程度
            this.shininess = material.shininess;
            //对应的对象那一面有材质
            this.side = "front";
            //材质的环境光
            this.color = material.color.getStyle();

            this.wrapAround = false;
            this.wrapR = 1;
            this.wrapG = 1;
            this.wrapB = 1;

            this.selectedMesh = "cube";
        }

测试效果:建议对比MeshLambertMaterial材质进行测试。

简单测试感觉没啥区别。高光效果暂时没找到运用的demo。后续测试

六、 THREE.ShaderMaterial(着色器材质)

        THRFE.ShaderMaterial是Threejs库中最通用、最复杂的材质之一。通过自己定制的着色器,直接在WebGL环境中运行。着色器可以将Threejs中的JavaScript网格转换为屏幕上的像素。通过这些自定义的着色器,可以明确地指定对象如何渲染,以及如何覆盖或修改Threejs库中的默认值。

        THREE.ShaderMaterial有一些我们已经见过的可以设置的属性。Three.js传人这些属性的所有信息,但是仍然必须在自己的着色器程序中处理这些信息。

着色器时使用类似与C语言的GLSL语言编写的(应该是OpenES 着色语言)

部分代码:


<script id="fragment-shader-6" type="x-shader/x-fragment">


    uniform float time;
    uniform vec2 resolution;


    void main( void )
    {

    vec2 uPos = ( gl_FragCoord.xy / resolution.xy );//normalize wrt y axis
    //suPos -= vec2((resolution.x/resolution.y)/2.0, 0.0);//shift origin to center

    uPos.x -= 1.0;
    uPos.y -= 0.5;

    vec3 color = vec3(0.0);
    float vertColor = 2.0;
    for( float i = 0.0; i < 15.0; ++i )
    {
    float t = time * (0.9);

    uPos.y += sin( uPos.x*i + t+i/2.0 ) * 0.1;
    float fTemp = abs(1.0 / uPos.y / 100.0);
    vertColor += fTemp;
    color += vec3( fTemp*(10.0-i)/10.0, fTemp*i/10.0, pow(fTemp,1.5)*1.5 );
    }

    vec4 color_final = vec4(color, 1.0);
    gl_FragColor = color_final;
    }

</script>

着色器测试效果:

 七、 THREE.LineBasicMaterial(直线基础材质)

基础属性:      

color该属性定义线的颜色。如果指定了vertexColors,这个属性就会被忽略 
linewidth该属性定义线的宽度 
vertexColors设置成THREEVertexColors值,就可以给每个顶点指定一种颜色

创建方案: 

 var material = new THREE.LineBasicMaterial({

            opacity: 1,
            linewidth: 0.1,
            vertexColors: THREE.VertexColors
        });

实例效果:

 还可以通过LineDashMaterial(虚线材质)产生虚线效果:

        lines.computeLineDistances();    
        var material = new THREE.LineDashedMaterial({
            vertexColors: true,
            color: 0xcccccc,
            dashSize: 0.1,  //虚线段的长度
            gapSize: 0.6,   //虚线段间隔的宽度
            scale: 1
        });
        var line = new THREE.Line(lines, material);
        line.position.set(25, -30, -60);
        scene.add(line);

必须强调的是:调用computeLineDistanceO(用来计算线段顶点之间的距离)。如果不这么做,间隔就不会正确地显示。

八、总结


        Threejs提供了很多材质用于给几何体指定皮肤。从简单的THREE.MeshBasicMaterial到复杂的 THREE.ShaderMaterial,通过THREE.ShaderMaterial可以提供自己的顶点着色器和着色器程序。材质共享很多基础属性。如果你知道如何使用一种材质,可能也知道如何使用其他材质。注意,不是所有的材质都对场景中的光源做出反应。如能希望一个材质计算光照的影响,如果希望一个材质计算光照的影响,应该尽量使用准材质THREE.MeshStandardMatcrial。而当你需要更多控制时,可以考虑使用THRE MeshPhysicalMaterial、THREE.MeshPhongMaterial或 THREE.MeshLambertMaterial。 仅仅从代码确定某种材质属性的效果是非常困难的。通常,使用dat.GUI控制面板来试验这些性是一个不错的方法。
        同样的是,材质的大部分属性都可以在运行时修改。但是有一些属性(例如 side)不能在运行时修改。如果你要修改这些属性的值,需要将needsUpdate属性设置为 true。要了解运行时哪些属性可以修改,哪些不属性不能修改,

       最新的两种材质测试属性测试效果在简单的场景并不能体现出来。有dmeo的小伙伴可以给我留言讨论一下效果。感谢。

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Three.js中,可以通过设置材质来控制物体的外观和光照效果。根据提供的引用内容,有几种常见的材质设置可以用于汽车模型和镜子模型。 对于汽车模型,可以使用MeshPhysicalMaterial和MeshStandardMaterial来定义不同部分的材质属性。例如,可以使用MeshPhysicalMaterial来定义汽车的表面反光材质,可以设置参数如下: - color: 使用十六进制颜色值来定义材质的颜色。 - metalness: 定义材质的金属性程度。 - roughness: 定义材质的粗糙度。 - clearcoat: 定义清漆的厚度。 - clearcoatRoughness: 定义清漆的粗糙度。 - sheen: 定义材质的光泽度。 类似地,可以使用MeshPhysicalMaterial和MeshStandardMaterial来定义汽车的玻璃材质和细节材质,可以根据需要设置相应的参数。 对于镜子模型,可以使用Reflector模块来创建镜子的效果。可以设置镜子的参数,如: - clipBias: 定义镜子的裁剪偏差。 - textureWidth: 定义镜面纹理的宽度。 - textureHeight: 定义镜面纹理的高度。 - color: 定义镜面的颜色。 根据需求,可以根据提供的引用内容中的示例代码来设置具体的材质参数和位置,以实现所需的效果。 总结起来,通过设置MeshPhysicalMaterial和MeshStandardMaterial可以定义汽车的不同部分的材质属性,而使用Reflector模块可以创建镜子的效果。可以根据需要设置相应的参数来达到所需的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值