IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Threejs材质的使用 -> 正文阅读

[游戏开发]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的小伙伴可以给我留言讨论一下效果。感谢。

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:56:56  更:2022-02-22 20:58:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:29:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码