加载模型

新版本cesium加载3DTiles代码如下,后续效果只修改CustomShader内内容

//加载楼栋白膜
let tileset
try {
tileset = await Cesium.Cesium3DTileset.fromUrl(
mapUrl + "/map/shijiazhuang/tileset.json"
);
viewer.scene.primitives.add(tileset);
} catch (error) {
console.error(`Error creating tileset: ${error}`);
} let customShader = new Cesium.CustomShader({ /** 定义shader */ })
tileset.customShader = customShader

效果一:纯渐变色



let customShader = new Cesium.CustomShader({
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
material.diffuse = vec3(0.0, 1.0-positionMC.y*0.005, 1.0-positionMC.y*0.0015);
}`
})

效果二:根据高度显示不同的贴图

其中有个疑惑,当if (positionMC.y > 200.0)时,才能在建筑物十几米高度处显示不同的贴图。

可目前建筑物高度是十几米、海拔高度是八十米,这里的200,对不上绝对高度,也对不上相对高度,不知道这里为何是这样,可自行多修改一些值,找到合适的



let customShader = new Cesium.CustomShader({
// lightingModel: Cesium.LightingModel.UNLIT,
// lightingModel: Cesium.LightingModel.PBR,
//设置变量,由顶点着色器传递给片元着色器
varyings: {
v_normalMC: Cesium.VaryingType.VEC3,
v_st: Cesium.VaryingType.VEC3
},
//外部传给顶点着色器或者片元着色器
uniforms: {
u_texture: {
value: new Cesium.TextureUniform({
url: mapUrl + "/assets/1.png"
}),
type: Cesium.UniformType.SAMPLER_2D
},
u_texture1: {
value: new Cesium.TextureUniform({
url: mapUrl + "/assets/2.png"
}),
type: Cesium.UniformType.SAMPLER_2D
}
},
//贴纹理
//顶点着色器
//将法向量从顶点着色器设置变量传给片元着色器
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
v_normalMC = vsInput.attributes.normalMC;
v_st=vsInput.attributes.positionMC ;
}`,
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
//这里是设置要贴图的图片的尺寸,设置小了会重复
float width = 10.0;
float height = 7.0;
vec3 rgb;
//这是是设置了屋顶的颜色,当和法向量平行时,就是屋顶,这里设置0.95,相当于垂直,建筑物四周开始贴图
if (dot(vec3(0.0, 1.0, 0.0), v_normalMC) > 0.95) {
material.diffuse = vec3(0.65, 0.65, 0.65);
} else {
float textureX = 0.0;
float dotYAxis = dot(vec3(0.0, 0.0, 1.0), v_normalMC);
// cos(45deg) 约等于 0.71,这里是建筑物四周的向量与法向量会大于四十五度夹角
if (dotYAxis > 0.71 || dotYAxis < -0.71) {
//x代表的是前后面
textureX = mod(positionMC.x, width) / width;
} else {
//z代表的是左右面
textureX = mod(positionMC.z, width) / width;
}
float textureY = mod(positionMC.y, height) / height;
//我这里是根据建筑物高度贴了两张不同的图片
if (positionMC.y > 200.0) {
rgb = texture(u_texture, vec2(textureX, textureY)).rgb;
} else {
rgb = texture(u_texture1, vec2(textureX, textureY)).rgb;
} material.diffuse = rgb;
}
}`
})

效果三:纯渐变色+动态光圈



let customShader = new Cesium.CustomShader({
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
material.diffuse = vec3(0.0, 1.0-positionMC.y*0.005, 1.0-positionMC.y*0.0015); float _baseHeight = 180.0; // 物体的基础高度,需要修改成一个合适的建筑基础高度
float _heightRange = 60.0; // 高亮的范围(_baseHeight ~ _baseHeight + _heightRange) 默认是 0-60米
float _glowRange = 120.0; // 光环的移动范围(高度) float vtxf_height = fsInput.attributes.positionMC.y - _baseHeight;
float vtxf_a11 = fract(czm_frameNumber / 360.0) * 3.14159265 * 2.0; //此处括号内分母为移动速度
float vtxf_a12 = vtxf_height / _heightRange + sin(vtxf_a11) * 0.1;
material.diffuse *= vec3(vtxf_a12, vtxf_a12, vtxf_a12); float vtxf_a13 = fract(czm_frameNumber / 360.0); //此处括号内分母为移动速度,数值越大,速度越慢
float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
float vtxf_diff = step(0.01, abs(vtxf_h - vtxf_a13)); // 0.1 为高亮光条的范围(粗细)
material.diffuse += material.diffuse * (1.0 - vtxf_diff);
}`
})

提示

效果三的动态光线效果的有效代码,移动至效果二,也可两种效果叠加显示;同理高亮效果也可叠加展示

let customShader = new Cesium.CustomShader({
// lightingModel: Cesium.LightingModel.UNLIT,
// lightingModel: Cesium.LightingModel.PBR,
//设置变量,由顶点着色器传递给片元着色器
varyings: {
v_normalMC: Cesium.VaryingType.VEC3,
v_st: Cesium.VaryingType.VEC3
},
//外部传给顶点着色器或者片元着色器
uniforms: {
u_texture: {
value: new Cesium.TextureUniform({
url: mapUrl + "/assets/1.png"
}),
type: Cesium.UniformType.SAMPLER_2D
},
u_texture1: {
value: new Cesium.TextureUniform({
url: mapUrl + "/assets/2.png"
}),
type: Cesium.UniformType.SAMPLER_2D
}
},
//贴纹理
//顶点着色器
//将法向量从顶点着色器设置变量传给片元着色器
vertexShaderText: `
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) {
v_normalMC = vsInput.attributes.normalMC;
v_st=vsInput.attributes.positionMC ;
}`,
//片元着色器
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
vec3 positionMC = fsInput.attributes.positionMC;
//这里是设置要贴图的图片的尺寸,设置小了会重复
float width = 10.0;
float height = 7.0;
vec3 rgb;
//这是是设置了屋顶的颜色,当和法向量平行时,就是屋顶,这里设置0.95,相当于垂直,建筑物四周开始贴图
if (dot(vec3(0.0, 1.0, 0.0), v_normalMC) > 0.95) {
material.diffuse = vec3(0.65, 0.65, 0.65);
} else {
float textureX = 0.0;
float dotYAxis = dot(vec3(0.0, 0.0, 1.0), v_normalMC);
// cos(45deg) 约等于 0.71,这里是建筑物四周的向量与法向量会大于四十五度夹角
if (dotYAxis > 0.71 || dotYAxis < -0.71) {
//x代表的是前后面
textureX = mod(positionMC.x, width) / width;
} else {
//z代表的是左右面
textureX = mod(positionMC.z, width) / width;
}
float textureY = mod(positionMC.y, height) / height;
//我这里是根据建筑物高度贴了两张不同的图片
if (positionMC.y > 200.0) {
rgb = texture(u_texture, vec2(textureX, textureY)).rgb;
} else {
rgb = texture(u_texture1, vec2(textureX, textureY)).rgb;
} material.diffuse = rgb; //此处以下为光线效果
float _baseHeight = 180.0; // 物体的基础高度,需要修改成一个合适的建筑基础高度
float _glowRange = 120.0; // 光环的移动范围(高度) float vtxf_height = fsInput.attributes.positionMC.y - _baseHeight; float vtxf_a13 = fract(czm_frameNumber / 360.0); //此处括号内分母为移动速度,数值越大,速度越慢
float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
float vtxf_diff = step(0.01, abs(vtxf_h - vtxf_a13)); // 0.1 为高亮光条的范围(粗细)
material.diffuse += material.diffuse * (1.0 - vtxf_diff);
}
}`
})

Cesium中3DTiles使用CustomShader着色器渲染的更多相关文章

  1. WebGL着色器渲染小游戏实战

    项目起因 经过对 GLSL 的了解,以及 shadertoy 上各种项目的洗礼,现在开发简单交互图形应该不是一个怎么困难的问题了.下面开始来对一些已有业务逻辑的项目做GLSL渲染器替换开发. 起因是看 ...

  2. OpenGL笔记(五) 着色器渲染(以Android为例)

    一.Android平台上下文环境的创建及初始化 1. 首先实例化Android上下文环境,即EGL的初始化. bool EGLCore::init(EGLContext sharedContext) ...

  3. OpenGl中使用着色器的基本步骤及GLSL渲染简单示例

    OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...

  4. 【Cesium 颜狗初步】fabric 材质定义与自定义着色器实践

    fabric 材质定义:着色器实践 1. 示例代码 贴到沙盒里就可以运行: var viewer = new Cesium.Viewer("cesiumContainer"); v ...

  5. Unity 渲染教程(二):着色器基础

    转载:https://www.jianshu.com/p/7db167704056 这是关于渲染基础的系列教程的第二部分.这个渲染基础的系列教程的第一部分是有关矩阵的内容.在这篇文章中我们将编写我们的 ...

  6. Unity3d之Shader编程:子着色器、通道与标签的写法 & 纹理混合

    一.子着色器 Unity中的每一个着色器都包含一个subshader的列表,当Unity需要显示一个网格时,它能发现使用的着色器,并提取第一个能运行在当前用户的显示卡上的子着色器. 我们知道,子着色器 ...

  7. 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解

    最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...

  8. OpenGL之shader着色器的应用,三色渐变的三角形

    学习自: https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/#_7 首先放一张效果图: 本次教程,将着色器单独定 ...

  9. OpenGL着色器入门简介

    说明:本文翻译自LearnOpengl经典教程,OpenGL着色器基础介绍的比较通俗易懂,特总结分享一下! 为什么要使用着色器?我们知道,OpenGL一般使用经典的固定渲染管线来渲染对象,但是随着Op ...

  10. LearnOpenGL学习笔记(二)——着色器简单理解

    着色器在OpenGL中发挥着重要作用,它就像一个画笔,将输入的数据流,转为数学坐标,再将三维坐标变成二维坐标(针对我们现在用的二维显示器,全息显示器肯是三维的),再把二维坐标实际的像素点位置(这里面肯 ...

随机推荐

  1. 5.5 Vim移动光标命令汇总

    Vim 文本编辑器中,最简单的移动光标的方式是使用方向键,但这种方式的效率太低,更高效的方式使用快捷键. Vim 移动光标常用的快捷键及其功能如下面各表所示,需要注意的是,表中所有的快捷键都在命令模式 ...

  2. php 5.4 var_export的改进

    用 var_export 来将数据存储到 php 配置文件里的时候,发现var_export转出来的变量定义还是 array()这种形式,不能转为[],所以自己写个函数来转换一下,代码如下: < ...

  3. Http状态码502常见原因及排错思路

    Http状态码502常见原因及排错思路 502表示Bad Gateway.当Nginx返回502错误时,通常表示Nginx作为代理服务器无法从上游服务器(如:我们的后端服务器地址)获取有效的响应.导致 ...

  4. 根据多选下拉框选中的结果,循环输出选中的标签<el-cascader>;对象数组由二维变成一维

    下面的图是要实现的交互图,根据<el-cascader>中v-model绑定的数据,再去下拉框出书数据中进行比对输出 v-model绑定的数据是一个二维数组,是这样的一组数据 [[1,12 ...

  5. word 文档签章控件生成的签章批量删除

    某个签章工具的word插件缺少批量插入签章的功能.同时,发现在投标工具中可以使用导出生成pdf时批量签章的功能.现在需要移除先前手动操作生成的多个签章,有如下发现-- 1.对少量签章,可以先选中签章右 ...

  6. Ubuntu使程序脱离终端运行

    应用场景: 远程登陆Linux服务器运行模型训练代码,如果关闭本地终端则服务器代码中断运行!目标操作:在本地终端运行服务器代码,当关闭终端时代码能够继续在服务器上运行,且再次打开终端连接服务器时能找回 ...

  7. 体验 DORIS 安装

    1.概述 doris 是 百度提供一个MPP架构的分析性数据库. 下面介绍一下如何安装doris . 2.下载 我用的是centos 7.5 的虚拟器. https://doris.apache.or ...

  8. 开源 - Ideal库 - Excel帮助类,ExcelHelper实现(四)

    书接上回,前面章节已经实现Excel帮助类的第一步TableHeper的对象集合与DataTable相互转换功能,今天实现进入其第二步的核心功能ExcelHelper实现. 01.接口设计 下面我们根 ...

  9. E. Photoshoot for Gorillas

    题意 给定一个整数 \(T\),代表共有\(T\)组测试用例,对于每组测试用例: 给定四个整数 \(n,m,k和w(1 \leq n,m \leq 2 * 10^5, 1 \leq w \leq n ...

  10. Qt/C++音视频开发75-获取本地有哪些摄像头名称/Qt内置函数方式

    一.前言 在需要打开本地摄像头的场景中,有个需求绕不开,那就是如何获取本地有哪些摄像头设备名称,这样可以提供下拉框给用户选择,不然你让用户去填设备名,你觉得用户会知道是啥,他会操作吗?就算你提供了详细 ...