当前位置:   article > 正文

Threejs材质的使用_this.three.mesh

this.three.mesh

前言:材质就像物体的皮肤,决定几何体的外表。例如:定义一个几何体看起来是否像金属,透明与否,或者显示为线框,得到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上下文对象渲染物体的方式。大多数情况下是不需要使用这些属性的。

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

  1. //材质的共有属性
  2. THREE.Material = function () {
  3. Object.defineProperty( this, 'id', { value: THREE.MaterialIdCount ++ } );
  4. this.uuid = THREE.Math.generateUUID();
  5. this.name = '';
  6. this.type = 'Material';
  7. this.side = THREE.FrontSide;
  8. this.opacity = 1;
  9. this.transparent = false;
  10. this.blending = THREE.NormalBlending;
  11. this.blendSrc = THREE.SrcAlphaFactor;
  12. this.blendDst = THREE.OneMinusSrcAlphaFactor;
  13. this.blendEquation = THREE.AddEquation;
  14. this.depthTest = true;
  15. this.depthWrite = true;
  16. this.polygonOffset = false;
  17. this.polygonOffsetFactor = 0;
  18. this.polygonOffsetUnits = 0;
  19. this.alphaTest = 0;
  20. this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing
  21. //antialiasing gaps in CanvasRenderer
  22. this.visible = true;
  23. this.needsUpdate = true;
  24. };

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

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

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

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

实例 : 

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

三、THREE.MeshDepthMaterial(联合材质)

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

创建方案: 

  1. //Math.ceil() “向上取整”, 即小数部分直接舍去,并向正数部分进1
  2. //Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值
  3. var cubeSize = Math.ceil(3 + (Math.random() * 3)); //cubeSize随机 3 4 5 6
  4. var boxGeometry = new THREE.BoxGeometry(cubeSize,cubeSize,cubeSize);
  5. var meshDepthMaterial = new THREE.MeshDepthMaterial();
  6. var meshBasicMaterial = new THREE.MeshBasicMaterial({
  7. color: controls.color,
  8. transparent: true,
  9. //材质融合MultiplyBlending将前景色与背景色(MeshDepthMaterial渲染的方块)相乘
  10. blending: THREE.MultiplyBlending
  11. });
  12. //混合材质创建网格
  13. //顺序不要放错
  14. var cube = new THREE.SceneUtils.createMultiMaterialObject(boxGeometry,[meshBasicMaterial,meshDepthMaterial]);
  15. //将第一种材质对象缩小,解决闪光现象
  16. //闪光现象 : 当一个物体作用在另一个物体上时,并且有一个物体是透明的,存在这种现象
  17. cube.children[1].scale.set(0.99, 0.99, 0.99);
  18. cube.castShadow = true;
  19. // position the cube randomly in the scene
  20. //Math.round() “四舍五入”, 该函数返回的是一个四舍五入后的的整数
  21. cube.position.x = -60 + Math.round((Math.random() * 100));
  22. cube.position.y = Math.round((Math.random() * 10));
  23. cube.position.z = -100 + Math.round((Math.random() * 150));
  24. 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)光滑度高的表面清晰度高

 创建方案:

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

 常用属性方式:

  1. var controls = new function (){
  2. this.transparent = false;
  3. this.opacity = 1;
  4. this.visible = true;
  5. this.ambient = 0x0c0c0c;
  6. //材质自身颜色不受光照影响
  7. this.emissive = material.emissive.getHex();
  8. //高光 即可模仿塑料质感 又可模仿金属质感
  9. this.specular = material.specular.getHex();
  10. //高光部分轮廓的清晰程度
  11. this.shininess = material.shininess;
  12. //对应的对象那一面有材质
  13. this.side = "front";
  14. //材质的环境光
  15. this.color = material.color.getStyle();
  16. this.wrapAround = false;
  17. this.wrapR = 1;
  18. this.wrapG = 1;
  19. this.wrapB = 1;
  20. this.selectedMesh = "cube";
  21. }

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

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

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

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

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

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

部分代码:

  1. <script id="fragment-shader-6" type="x-shader/x-fragment">
  2. uniform float time;
  3. uniform vec2 resolution;
  4. void main( void )
  5. {
  6. vec2 uPos = ( gl_FragCoord.xy / resolution.xy );//normalize wrt y axis
  7. //suPos -= vec2((resolution.x/resolution.y)/2.0, 0.0);//shift origin to center
  8. uPos.x -= 1.0;
  9. uPos.y -= 0.5;
  10. vec3 color = vec3(0.0);
  11. float vertColor = 2.0;
  12. for( float i = 0.0; i < 15.0; ++i )
  13. {
  14. float t = time * (0.9);
  15. uPos.y += sin( uPos.x*i + t+i/2.0 ) * 0.1;
  16. float fTemp = abs(1.0 / uPos.y / 100.0);
  17. vertColor += fTemp;
  18. color += vec3( fTemp*(10.0-i)/10.0, fTemp*i/10.0, pow(fTemp,1.5)*1.5 );
  19. }
  20. vec4 color_final = vec4(color, 1.0);
  21. gl_FragColor = color_final;
  22. }
  23. </script>

着色器测试效果:

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

基础属性:      

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

创建方案: 

  1. var material = new THREE.LineBasicMaterial({
  2. opacity: 1,
  3. linewidth: 0.1,
  4. vertexColors: THREE.VertexColors
  5. });

实例效果:

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

  1. lines.computeLineDistances();
  2. var material = new THREE.LineDashedMaterial({
  3. vertexColors: true,
  4. color: 0xcccccc,
  5. dashSize: 0.1, //虚线段的长度
  6. gapSize: 0.6, //虚线段间隔的宽度
  7. scale: 1
  8. });
  9. var line = new THREE.Line(lines, material);
  10. line.position.set(25, -30, -60);
  11. 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的小伙伴可以给我留言讨论一下效果。感谢。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/96075
推荐阅读
相关标签
  

闽ICP备14008679号