Cesium官方教程12--材质(Fabric)

原文地址:https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric
介绍
Fabric 是Cesium中基于JSON格式来描述materials的机制。材质描述多边形、折线、椭球等对象的外观特征。
材质可以简单的是覆盖一张图片,或者是条纹或者棋盘图案。使用Fabric 和GLSL,可以从零开始写脚本新建材质,也可以从现有的材质中派生。比如潮湿碎裂的砖块可以使用程序生成的纹理、凹凸贴图和反射贴图来组合。
对象通过material 属性来支持材质效果。当前这些对象是多边形、折线、椭球等(这篇文章写的较早,其实现在已经很多几何体都支持材质了)。

上面,Color是一个内置材质,它表示了包含透明度在内的一个颜色值。Material.fromType是简略写法,完整的Fabric的JSON应该是这样的:

每一个材质包含0或者更多个uniforms,uniform是一种输入参数变量,在创建材质时或者创建材质后修改。比如 , Color有一个 color uniform ,它包含red, green, blue, 和alpha四个部件。

内置材质
Cesium有一些内置材质,应用最广泛的是这两个:

如同上面的 Color 一样,所有的内置材质都可以这么创建。比如:

或者

程序生成的纹理 (Procedural Textures)
程序生成的纹理,他们不依赖于外部图片文件,是通过GPU编程计算的图案,他们可以表示颜色和透明。

基本材质
Base materials represent fine-grain fundamental material characteristics, such as how much incoming light is reflected in a single direction, i.e., the specular intensity, or how much light is emitted, i.e., the emission. These materials can be used as is, but are more commonly combinedusing Fabric to create a more complex material.

折线材质
这只一种只能添加到折线几何体上的材质。

其他材质
还有一些不适合归到其他类的材质

了解更多材质,可以去看下这个 Cesium Materials Plugin.

通用的Uniforms
很多材质都有一个image uniform,它是一个图片访问地址,或者数据URI。
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要求图片有一个通道。我们可以指定渲染的时候从哪些通道(或者什么顺序)从原始图片中读取数据,通过 channel这个字符串uniform来设置。比如,默认Specular材质是从 r读取高光反射参数。不过我们可以如下修改它:

这就是说可以把多个材质的信息放到一个图片里,比如在同一个图片内,用rgb通道存储diffuse值,用a通道存储specular值。也就是说,我们的图片只需要载入一次。
通常材质里有一个repeat uniform,它控制了图片在水平和垂直方向重复了多少次。这个在表面重复贴图的时候很方便:

创建新的材质
使用Fabric,只需要一点点GLSL或者其他材质就可以了。
如果不打算复用材质,那么不要设置type参数。

当在new Cesium.Material时,传入一个不存在的 type类型之后,这个材质将被缓存下来。下次调用 new Cesium.Material 或者 Material.fromType 就会引用缓存里的,就如同我们内置的材质一样,那时候就不需要提供整个Fabric的定义,而仅仅传递 type以及想更改的 uniforms值。

Components
或许最简单有趣的材质就是纯白色散射光:

稍微复杂一点,增加一个高光元素,当视角正对反射光的时候更亮一些,当视角在边上的时候稍微亮一些。

components属性包含了 定义了材质外观的子属性。每个子属性是一个GLSL的代码段,比如上面的vec3(0.5) ,它实际创建了一个三维向量,每个分量都设置为 0.5。这里可以访问所有的GLSL函数,包括 mix,cos,texture2D`等等。现在有5种子属性:

综上所述,子属性或者components 定义了材质的特点。他们是材质的输出值,是光照系统的输入值。

代码
提供完整的GLSL代码是一种比前面 components 更灵活的方式。通过自定义czm_getMaterial函数,返回材质的各个分量。代码如下:

最简单的实现就是返回每个分量的默认值。

Fabric 这么定义:
{
source : ‘czm_material czm_getMaterial(czm_materialInput materialInput) { return czm_getDefaultMaterial(materialInput); }‘
}
下面的示例代码,只设置了diffuse和 specular分量的值:

source相对 components更加繁琐,但是更灵活,比如定义一些公用的函数,共享每个分量的计算过程等等。有个原则就是优先使用components属性,除非明确需要实现 czm_getMaterial函数。也就是说 components的子属性实际也是实现czm_getMaterial函数。而两种方式下,我们都可以访问GLSL 的内置函数和Cesium提供的GLSL函数(functions), 变量(uniforms), and 常量(constants)(链接已失效)。
材质输入
materialInput 变量在source和 components属性中都可以配置。它具有下面的字段,用来计算材质分量:


把纹理坐标的st值显示出来的简单方法:

类似的,查看视点坐标下的法向量,只需要 把materialInput.normalEC 设置到 diffuse 分量上。
除此之外,在materialInput里,可以访问uniforms变量,包括Cesium 提供的内置变量 uniforms 和 材质设置的uniforms变量。比如,我们可以设置自定义的Color材质,依据一个color 变量来设置diffuse和alpha 。

Fabric中,uniform属性的子属性是GLSL中的uniform变量名 ,也是 new Material和 Material.fromType返回中JavaScript的对象属性名。子属性的值也是GLSL中uniform变量的值。(这块意思就是说uniform下的属性和值在GLSL的GPU环境和js的内存环境中一致的)。
可以通过一个自定义的 image变量来实现材质的DiffuseMap :


上面代码里,‘czm_defaultImage‘是一个1x1的图片。前面说过,这个值可以是一个图片URL地址或者 数据URI。比如用户可以使用我们自定义的OurDiffuseMap 材质,这么来设置纹理:

也有一个内置的立体贴图:czm_defaultCubeMap。GLSL 标准的uniform变量类型float, vec3, mat4都是支持的。Uniform数组还不支持,但是已经在计划内 roadmap。
材质的合并
至此,我们可以使用内置的材质,可以通过设置材质的components来自定义 ,或者实现完整的GLSL代码source来自定义。我们还可以通过继承已有的材质来新建材质。
Fabric 有个materials属性,它的每个子属性也是Fabric材质。他们的材质可以可以在 components 或者source 中引用。比如一个塑料材质可以通过 DiffuseMap和SpecularMap两个材质的合并来模拟。

这个材质的diffuse和specular 都是从其他材质中提取的。子属性的名字叫diffuseMaterial 和specularMaterial(根据类型 DiffuseMap和SpecularMap创建的材质。不要搞混 类型 和 实例对象的名称,在 components 和source 属性中,子材质通过名称访问,因为他们都是一个czm_material 结构,所以可以访问.diffuse和 .specular分量。
基于这个Fabric材质,可以这么用我们的材质:

Fabric 格式
Fabric 是基于JSON 格式的格式定义。这格式定义里详细描述了Fabric的属性和子属性,包括 type, materials, uniforms, components, 和 source等。那里面有一些JSON的格式示例,但是没有必要去看。
对于一些严格要求的Fabric文件,可以使用一些类似 JSV的工具去验证Fabric格式。
渲染流水线中的材质
Polygon, PolylineCollection, Ellipsoid, CustomSensorVolume等几何体 已经 和材质系统集成。大部分用户只需要简单的设置material就可以了。可是,用户还是想实现自己的材质渲染代码。直接了当的去做就行了。
在渲染阶段,材质就是一段GLSL函数czm_getMaterial 和 一些uniform变量。片段着色器需要构造一个 czm_MaterialInput结构,然后调用czm_getMaterial方法,把获得的 czm_material 结果传递给光照处理函数去计算图元颜色。
在JavaScript代码里,这些对象应该有一个 material属性。当这个属性变换的时候,update 函数应该把材质的GLSL代码转为对象的片段着色器代码,并且把对象和材质的uniform变量合并起来。

原文地址:http://blog.51cto.com/14117342/2327186

时间: 2024-08-29 21:09:50

Cesium官方教程12--材质(Fabric)的相关文章

Cesium官方教程13--Cesium和Webpack

原文地址:https://cesiumjs.org/tutorials/cesium-and-webpack/Cesium 和 WebpackWebpack是非常强大非常流行的JavaScript 模块打包工具.它可以让开发人员以一种简单直观的 require 方式去加载各种页面需要的文件,极大的方便了开源人员对代码和资源文件进行结构化设计.当编译的时候,它会跟踪代码依赖性,把所有的模型打包到浏览器可以直接加载的一个或者多个bundles中.在这个教程的前一半,我们创建一个简单的web项目,学会

Cesium官方教程8-- 几何体和外观效果

原文地址:https://cesiumjs.org/tutorials/Geometry-and-Appearances/几何体和外观效果(Geometry and Appearances)这篇教程会教大家学习Primitive API中支持的几何体和外观效果.这篇教程并不是面向Cesium的普通用户,主要讨论Cesium的高级知识,包括自定义三角网(mesh),形状(shape),体(volume)以及他们的外观.如果你是初学者,建议先学下这篇教程.Cesium可以使用Entity创建不同的几

Cesium官方教程11--建模人员必读

原文地址:https://cesium.com/blog/2014/12/15/gltf-tips-for-artists/这篇文章是Branden Coker, an artist from AGI 写的,他是 AGI 的一个艺术家,做过很多事情,包括 为追踪圣诞老人项目建模.感谢3dben 编写的Blender和3DS Max建模建议.Cesium使用面向web的glTF 格式三维模型,同时提供了一个 dae在线转gltf的工具, 把dae和它纹理拖放到这个工具里,就能获得一个glTF格式的

Cesium官方教程10--高级粒子特效

原文地址:https://cesiumjs.org/tutorials/Particle-Systems-More-Effects-Tutorial/高级粒子系统特效这篇教程学习更多的效果,包括天气和火箭推进器.如果没有学习过粒子系统基础知识,请学习这篇教程 粒子系统介绍 .天气下雪下雨 最开始下雪的教程是来自 追踪圣诞老人项目里的实现.步骤我们即将介绍如何做下雪效果,然后怎么把下雪变为下雨效果.我们将给每个粒子添加雪花图片,然后在updateParticle函数里定义每个粒子的移动属性和其他动

Cesium官方教程9--粒子系统

原文地址:https://cesiumjs.org/tutorials/Particle-Systems-Tutorial/ 粒子系统介绍这篇教程带你学习Cesium的粒子相关API,比如如何在你的项目里添加烟,火,火花等特效.什么是粒子系统?粒子系统是一种图形学技术,用来模拟复杂的物理效果.粒子系统是由一堆很小的图片组成,看起来就像一些复杂的"含糊不清(fuzzy)"对象,就像火.烟.天气.或者 ×××.这些复杂效果其实是通过控制每一个独立的粒子的初始位置.速度.生命周期等属性来完成

Cesium官方教程5--地形图层

原文地址:https://cesiumjs.org/tutorials/Terrain-Tutorial/Cesium支持渐进流式加载和渲染全球高精度地形,并且包含海.湖.河等水面效果.相对2D地图,山峰.山谷等其他地形特征的更适宜在这种3D地球中展示.地形数据集是巨大的,通常都是GB或者TB级别.在普通3D引擎中,使用底层图形API去高效实现地形数据的可视化需要做很多事情.幸好,Cesium已经完成了这个体力活,而我们只需要写几行代码.快速开始从一个示例开始吧.打开Sandcastle中的 H

Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译

本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官方教程The Profiler window翻译 Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译 Unity性能优化(3)-官方教程Optimizing garbage collection in Uni

C#程序员整理的Unity 3D笔记(二十):2D Toolkit之官方教程《Whack a Mole》

在上篇博客中,简单整理了一下Unity Native 2D功能:<C#程序员整理的Unity 3D笔记(十九):Unity 3D的Native 2D>. 本文开始学习2D商用比较广泛的2D Toolkit插件. 2D Toolkit插件在2D中的地位,犹如UI中NGUI对Unity GUI一样:虽然官方原生的2D还不错,但这是最近1年新版本才有的功能,2年前Unity 2D的王道还是得用插件的,故<2D Toolkit>就成了目前商业不错的选择. 在上周刚开始看的时候,就给自己提了

Cesium中级教程10 - CesiumJS and webpack

Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ webpack是打包JavaScript模块流行且强大的工具.它允许开发人员以直观的方式构造代码和assets,并使用简单的require语句根据需要加载不同类型的文件.构建时,它将跟踪代码依赖关系,并将这些模块打包到浏览器加载的一个或多个包中. 在本教程的前半部分,我们从头开始建立了简单的Web应用程序使用webpack,然后覆盖后续步骤集成Cesium np