cesium Material的理解与使用

1.简介

材质Material可以是比较简单的,比如直接将一张图片赋予表面,或者使用条纹状、棋盘状的图案;也可以使用FabricGLSL,重新创建一个新的材质或者组合现有的材质。例如,我们可以通过程序生成的纹理(procedural brick)、凹凸贴图(bump map)和高光贴图(specular map)来生成一个潮湿碎裂的砖块材质。

2. Fabric是什么

Fabric 是Cesium中定义的描述材质Material的JSON 结构体。Material代表了一个物体的外观

 在Cesium中支持赋予材质的图元都有一个material属性。

polygon.material = Material.fromType('Color');

上边这行代码中,Color是一个内置材质属性,代表了单一颜色,包括透明度(alpha)。Material.fromType是一个快捷的方式,完整的Fabric JSON 应该是这样: 

polygon.material = new Cesium.Material({
  fabric : {
    type : 'Color'
  }
});

注意每一种材质(material)都有uniforms属性,uniforms可以在创建材质(material)时或之后设置。 

polygon.material = new Cesium.Material({
  fabric : {
    type : 'Color',
    uniforms : {
      color : new Cesium.Color(1.0, 0.0, 0.0, 0.5)
    }
  }
});

// Change from translucent red to opaque white
polygon.material.uniforms.color = Cesium.Color.WHITE;
 

3内置材质 

Cesium有一些内置的材质,常用的两种为:

所有内置的材质都可以像我们创建颜色那样简单的创建:

 polygon.material = Material.fromType('Image');
polygon.material.uniforms.image = 'image.png';

 也可以这样创建:建议使用fabric的方式

 polygon.material = new Cesium.Material({
  fabric : {
    type : 'Image',
    uniforms : {
      image : 'image.png'
    }
  }
});

 3.1程式化纹理

程式化纹理不直接依赖于图片文件,而是通过GPU计算而来,他们可以设置漫反射(diffuse)和透明度(alpha)

3.2 基础材质

基础材质较为底层,可以设置基础的材质特性,比如某个方向有多少光线被反射(镜面强度)、或者光线发射量等等。这些材质特性通常组合起来使用,从而创建一个复杂的材质。

3.3多段线(polyline)材质 

多段线材质只可以用于线状的物体。

 3.4 其他材质

更多材质参考 https://cesium.com/learn/cesiumjs/ref-doc/Material.html?classFilter=Material

 4 uniform

很多的材质(material)都有image uniform,定义了图片路径或数据路径

polygon.material.uniforms.image = 'image.png';
polygon.material.uniforms.image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC/SURBVDhPrZPRDYQgEEQpjVKuFEvhw0IoxU6QgQwMK+vdx5FsooT3GHdjCM4qZnnnHvvkYoxFi/uvIhwiRCClXFC6v5UQ1uQAsbrkHCLsbaPjFgIzQQc1yUOwu33ePGE3BQUaee2BpjhbP5YUmkAlbNzsAURfBDqJnMIyyv4JjsCCgCnIR32uZUfcJuGBOwEk6bOKhoAADh31EIq3MgFg1mgkE1BA2AoUZoo2iZ3gyqGgmMDC/xWwkfb3/eUd7A1v3kxjNW9taQAAAABJRU5ErkJggg=='
 

一些属性,例如漫反射(diffuse)或法线贴图(NormalMap)的属性,要求图片的每个像素具有RGB三个通道;其他材质属性,例如高光(specular)和透明度(alpha),要求具有一个通道。我们可以指定从纹理图片的那个通道中获取数据,通过channels或者channel来设置。
例如,默认情况下高光specular属性读取r通道,我们可以改变读取的通道: 

polygon.material = new Cesium.Material({
  fabric : {
    type : 'SpecularMap',
    uniforms : {
      image : 'specular.png',
      channel : 'a'
    }
  }
});
 

 允许多个材质从相同的图片中读取数据,例如一张相同的图片即存储了漫反射属性(diffuse)所需的rgb通道,也存储了高光属性(specular)所需的a通道。这样这张图片只会加载一次,节省了资源。

材质material也可以使用images的repeat属性,控制图片在横向和纵向的重复次数。经常被用于在物体表面的瓦片纹理。

polygon.material = new Cesium.Material({
  fabric : {
    type : 'DiffuseMap',
    uniforms : {
      image : 'diffuse.png',
      repeat : {
        x : 10,
        y : 2
      }
    }
  }
});
 

5.创建一个新的材质

创建一个新的材质,可以通过Fabric、一些GLSL代码,以及其他的材质组合起来。
如果新创建的材质只使用一次,可以不设置Type属性

var fabric = {
   // no type
   // ...rest of fabric JSON
};
polygon.material = new Cesium.Material({
  fabric : fabric
});
 

当使用一个新的材质类型type时,材质会在第一次绘制时缓存,之后的绘制(通过new Cesium.Material或者Material.fromType)就可以直接使用缓存的材质,就像使用内置材质一样,不需要提供完整的Fabric描述,只需要通过type和定义需要使用的uniforms即可。 

var fabric = {
   type : 'MyNewMaterial',
   // ...rest of fabric JSON
};
polygon.material = new Cesium.Material({
  fabric : fabric
});
// ... later calls just use the type.
anotherPolygon.material = Material.fromType('MyNewMaterial');
 

5.1 Components 

可能最简单的使用材质的方式就是直接反射白色

var fabric = {
  components : {
    diffuse : 'vec3(1.0)'
  }
}
 

稍微复杂的例子是添加高光反射属性specular component,这样材料的反射光线在直视的时候最强烈,而在斜视时就变弱。

 {
  components : {
    diffuse : 'vec3(0.5)',
    specular : '0.1'
  }
}

components属性包含了定义材料外观的子属性。每个子属性都是一个GLSL代码片段,比如上面示例代码中的vec(0.5)创建了一个3D向量,3D向量中每个分量都被设置为0.5,。
共有以下几个子属性:

属性名默认值描述
漫反射
diffuse
'vec3(0.0)'漫反射属性是一个三维向量vec3,这个向量定义了光在所有方向上的散射值。
高光
specular
0.0高光属性,使用浮点数定义了单一方向上的反射强度。
光泽度
shininess
1.0镜面反射的光泽度。越高的值创建一个更小、更集中的镜面高光。
法线
normal
材质的法线属性是一个三维向量vec3,定义了视点坐标系下的表面法向量。通常用于法向贴图。默认值是物体表面默认的发现。
自发光
emission
'vec3(0.0)'自发光属性使用三维向量vec3定义,定义了在所有方向上灯光发出的颜色值。默认是vec3(0.0),也就是不发光。
alpha1.0阿法尔通道使用浮点数定义,0.0表示全透,1.0表示不透明。

 总的来说,这些子属性定义了材质的特点,他们是材质material的输出值,同时也是光照系统的输入值。

5.2 Source

source属性通过为czm_getMaterial函数定义GLSL代码的方式,提供了一个更加灵活的定义材质的方式。

struct czm_materialInput
{
    float s;
    vec2 st;
    vec3 str;
    mat3 tangentToEyeMatrix;
    vec3 positionToEyeEC;
    vec3 normalEC;
};

struct czm_material
{
    vec3 diffuse;
    float specular;
    float shininess;
    vec3 normal;
    vec3 emission;
    float alpha;
};

czm_material czm_getMaterial(czm_materialInput materialInput);
 

使用source最简单的方式是每一个属性都直接返回默认值 

czm_material czm_getMaterial(czm_materialInput materialInput)
{
    return czm_getDefaultMaterial(materialInput);
}
 

Fabric定义

{ source : 'czm_material czm_getMaterial(czm_materialInput materialInput) { return czm_getDefaultMaterial(materialInput); }' } 

我们把之前的例子中通过source来实现的: 

// 通过FABRIC 定义
{
    components : {
        diffuse : 'vec3(0.5)',
        specular : '0.1'
    }
}

// 通过source
{
    source:`
        czm_material czm_getMaterial(czm_materialInput materialInput)
    {
        czm_material m = czm_getDefaultMaterial(materialInput);
        m.diffuse = vec3(0.5);
        m.specular = 0.5;
        return m;
    }`
}
 

使用source代替components的方式代码量更加多,但也会更加灵活,包括可以为不同的组件公用相同的计算逻辑和函数。一个经验法则是在大多数情况下使用components,除非需要用到czm_getMaterial的灵活性。在底层实现上,components子属性也是通过czm_getMaterial来实现的。在这两种方式下,我们都可以用到GLSLCesium提供的内置的函数、变量、常量等。 

5.3 Input 

materialInput变量在sourcecomponents属性中都是有效的,materialInput具有以下参数字段

名称类型描述
**s**float一维纹理坐标
**st**vec2二维纹理坐标
**str**vec3三维纹理坐标。> 注意:一维、二维、三维纹理坐标之间并不一定分量相同,不能保证str.st == st and st.s == s。例如,对于一个椭圆体,一维纹理坐标s可能是从底部到顶部,二维纹理坐标st是经纬度坐标,三维纹理坐标是沿着坐标轴的包围盒。

|
**tangentToEyeMatrix** | mat3 | 片元切线空间到视点坐标系的转换矩阵,通常用于法线贴图和凹凸贴图中。 |
**positionToEyeEC** | vec3 | 在视点坐标系下从片元到视点的向量,用于反射、折射等等。值大小表示从片元到视点的距离。 |
**normalEC** | vec3 | 片元在视点坐标系下单位化后的发现了,用于凹凸贴图、反射、折射等。 |

一个使用二维纹理坐标st的简单材质使用如下:

{components : {diffuse : 'vec3(materialInput.st, 0.0)'}
}

同样的我们可以设置materialInput.normalECdiffuse,以在视点坐标系下法线的可视化。
除此之外,对于materialInput,材质还可以使用uniform变量,不管是Cesium内置的uniforms还是材质特定的uniforms
例如,我们可以实现我们自己的Color材质,基于color uniform设置diffuse以及alpha属性。

{type : 'OurColor',uniforms : {color : new Color(1.0, 0.0, 0.0, 1.0)},components : {diffuse : 'color.rgb',alpha : 'color.a'}
}

Fabric中,uniform属性的子属性也是**GLSL**中的uniforms的名称,以及使用new Material以及Material.fromType中的返回的**JavaScript**对象。子属性的值也是uniform的值(对于标量及向量)。
我们可以通过image uniform实现我们自己的diffuseMap属性

{type : 'OurDiffuseMap',uniforms : {image : 'czm_defaultImage'},components : {diffuse : 'texture2D(image, materialInput.st).rgb'}
}

在上面代码中,'czm_defaultImage'是一个1x1占位符图像,也可以使用图像URL或数据URL来指定纹理图像。例如,用户可以这样来创建一个OurDiffuseMap

polygon.material = Material.fromType('OurDiffuseMap');
polygon.material.uniforms.image = 'diffuse.png';

还有一个立方图占位符 czm_defaultCubeMap。支持标准的GLSLuniform 类型,floatvec3mat4等等。Uniform数组还不支持。

5.4组合材质

到目前为止,我们可以使用内置材质,或者创建我们自己的材质。我们也可以从现有的材质中创建材质(递归),形成材质的层次结构。

材质Fabric具有materials属性,这个materials属性的子属性的值都是一个材质Fabric,也就是一种材质。这些materials可以在componentssource属性中引用。例如,一个代表塑料的材质可以通过设置diffuseMapspecularMap来实现。

{type : 'OurMappedPlastic',materials : {diffuseMaterial : {type : 'DiffuseMap'},specularMaterial : {type : 'SpecularMap'}},components : {diffuse : 'diffuseMaterial.diffuse',specular : 'specularMaterial.specular'}
};

上边这段代码中,components属性中有漫反射diffuse以及镜面反射specular属性,他们从材质的materials属性中提取数值。命名为diffuseMaterial及 specularMaterial的子属性(通过类型DiffuseMapSpecularMap创建,不要混淆了名称——实例——类型(也可以叫类))。在componentssource属性中,子属性可以通过字段名来访问,就像他们是czm_material结构体,因此在上面代码中通过.diffuse.specular字段可以访问。

鉴于这一点,我们的材质material可以像其他材质material一样被使用。

6、渲染管线中的材质(使用GLSL自定义材质)

几何对象包括 PolygonPolylineCollectionEllipsoidCustomSensorVolume,等,都与材质系统整合以支持材质。大多数用户只需简单设置他们所需的材质属性即可,但对于想用书写自定义渲染代码的用户,可能也需要与材质系统结合。

从渲染的角度,材质是GLSL 函数,czm_getMaterial,以及uniforms的组合。片元着色器需要构造一个czm_MaterialInput,调用czm_getMaterial函数,之后将计算的czm_material结果传递给lighting函数,以计算片元着色器颜色。

在JavaScript中,对象应该有一个公共的material属性。当这个属性变化时,update函数应该将材质中的GLSL源预置到几何对象的片元着色器中,并且组合几何对象和材料的uniforms

var fsSource =this.material.shaderSource +ourFragmentShaderSource;this._drawUniforms = combine([this._uniforms, this.material._uniforms]);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/22622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-input实现后缀图标和clearable的兼容,调整el-input clearable与自定义图标展示位置问题

背景:常见的输入框存在两个图标的展示效果都是清空在前搜索或其他图标在后 常见以及最终实现效果(清空图标在前,搜索图标在后) BUG以及el-input默认效果 问题排查 通过控制台审查元素能够发现,默认的效果是自定义图标…

基于C#的计算机与安捷伦34970A通信方法

概述 安捷伦34970A采集数据,34970A支持RS232接口,但是如果直接用winform自带的seriaport类基本是没必要使用的,安捷伦等仪表通讯需要用到VISA的库。 库的获取 1. 是德科技的IO Library. 2. NI下载NI-VISA. 两者用法接近. 代码如下 using…

WLAN基础-WLAN安全

目录 一、引言二、WLAN安全威胁三、WLAN安全防御机制四、WLAN常用接入认证方式五、总结 一、引言 随着无线网络的广泛应用,WLAN(无线局域网)因其灵活性和便利性成为越来越多用户和企业首选的接入方式。然而,由于无线通信开放的传…

【动手学深度学习】多层感知机之暂退法研究详情

目录 🌊1. 研究目的 🌊2. 研究准备 🌊3. 研究内容 🌍3.1 多层感知机暂退法 🌍3.2 基础练习 🌊4. 研究体会 🌊1. 研究目的 防止过拟合:权重衰减和暂退法都是用来控制模型的复杂…

基于springboot实现疫情信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现疫情信息管理系统演示 摘要 近年来,信息化管理行业的不断兴起,使得人们的日常生活越来越离不开计算机和互联网技术。首先,根据收集到的用户需求分析,对设计系统有一个初步的认识与了解,确定疫情信息…

【C++题解】1392 - 回文偶数?

问题:1392 - 回文偶数? 类型:for循环 题目描述: 小明发现有一类数非常有趣,他们正过来读和反过来读是一样的,比如:121、202、383 等,小明给这类数起了一个名字,叫做回文…

【Python】 将日期转换为 datetime 对象在 Python 中

基本原理 在 Python 中,处理日期和时间的库是 datetime,它提供了广泛的功能来处理日期和时间。datetime 模块中有一个 datetime 类,它可以用来表示日期和时间。有时,我们可能会遇到需要将日期字符串转换为 datetime 对象的情况&a…

《绝区零》测试开启,揭开了米哈游海外战略意图

原标题:《绝区零》公测,米哈游希望用一个成熟平台迎接《绝区零》的诞生 易采游戏网6月5日消息:随着《绝区零》公测日期的逐渐迫近,身为米哈游的忠实拥趸,对于这款新作怀揣着无尽期待。作为中国二次元游戏行业的领军企业…

Linux系统Docker部署Apache Superset并实现远程访问详细流程

目录 前言 1. 使用Docker部署Apache Superset 1.1 第一步安装docker 、docker compose 1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透,实现公网访问 3. 设置固定连接公网地址 前言 作者简介: 懒大王敲代码&#xff0…

校园外卖系统的技术架构与实现方案

随着校园生活的日益现代化,外卖需求在高校学生群体中迅速增长。为了满足这一需求,校园外卖系统应运而生。本文将详细探讨校园外卖系统的技术架构及其实现方案,帮助读者了解这一系统的核心技术与实现路径。 一、系统概述 校园外卖系统主要包…

上海亚商投顾:深成指、创业板指均涨超1%,电力股午后集体走强

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 沪指昨日低开后震荡反弹,深成指、创业板指均涨超1%,黄白二线依旧分化。电力、电网股午…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于保守度自适应优化的综合能源系统鲁棒灵活性评估》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

目标检测——铁轨表面缺陷数据集(一)

引言 亲爱的读者们,您是否在寻找某个特定的数据集,用于研究或项目实践?欢迎您在评论区留言,或者通过公众号私信告诉我,您想要的数据集的类型主题。小编会竭尽全力为您寻找,并在找到后第一时间与您分享。 …

python中操作文件的实践(2)

上一篇我总结了python对于文件操作的一些常用方法,这一篇主要记录对文件操作的一些常用方法 1.将文件中的内容进行替换 import os with open(python1.txt,encodingutf-8) as f1,\open(python1_bak.txt,encodingutf-8,modew) as f2:for line in f1:new_lineline.re…

目标检测——叶片计数数据集

引言 亲爱的读者们,您是否在寻找某个特定的数据集,用于研究或项目实践?欢迎您在评论区留言,或者通过公众号私信告诉我,您想要的数据集的类型主题。小编会竭尽全力为您寻找,并在找到后第一时间与您分享。 …

R语言绘图 --- 桑基图(Biorplot 开发日志 --- 5)

「写在前面」 在科研数据分析中我们会重复地绘制一些图形,如果代码管理不当经常就会忘记之前绘图的代码。于是我计划开发一个 R 包(Biorplot),用来管理自己 R 语言绘图的代码。本系列文章用于记录 Biorplot 包开发日志。 相关链接…

VUE3 学习笔记(14):VUE3 组合式API与传统选项式API用法

VUE3相较VUE2的亮点很多,作为后端开发置于前端最大的感受就是组合式API(之前采用的是选项式API);它使得整体更简洁易用,但值得提醒的是官方并未强制要求二选一,尽管如此在同一个项目中还是不要出现两种写法。 选项式AP…

【通知】上市公司嵌入式工程师带队授课,成品展示~~

1,成品展示: 2,产品需求: 设计一款无线CAN转发器,由若干个终端组成,若干个终端之间可以将接收到的CAN数据通过无线的方式转发出去,在复杂的条件下,传输距离不低于200m。 该CAN转发器…

vscode+latex设置跳转快捷键

安装参考 https://blog.csdn.net/Hacker_MAI/article/details/130334821 设置默认recipe ctrl P 打开设置,搜索recipe 也可以点这里看看有哪些配置 2 设置跳转快捷键

IIC信号质量测试、时序测试详解

IIC 时序图 信号质量测试 1、vIL: 低输入电平。 2、vIH: 高输入电平。 3、vhys: 施密特触发器输入的滞后。 4、vOL1: VDD>2V时&#xff0c;低电平输出电压&#xff08;漏极开路或集电极开路&#xff09;。 5、vOL3: VDD<2V时&#xff0c;低电平输出电压&#xff08;漏极开…