加载模型

新版本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. 【241027-论文阅读】DGraph: A Large-Scale Financial Dataset for Graph Anomaly Detection

    DGraph: A Large-Scale Financial Dataset for Graph Anomaly Detection DGragh是一个用于图异常检测(gragh anomaly d ...

  2. c++时间形式转换

    https://cplusplus.com/reference/ctime/ 先放上官方文档. ctime类里,有很多转换时间格式的方法,下面只举例将UTC时间,转换为字符串的代码. ‌‌Unix时间 ...

  3. esp8266+MQTT+DHT11(温湿度计) platformio

    esp8266 + MQTT + DHT11(温湿度计) 连线 #include <Arduino.h> #include <ESP8266WiFi.h> #include & ...

  4. leetcode 740 删除并获得点数

    740 删除并获得点数 题意 给你一个整数数组 nums ,你可以对它进行一些操作. 每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数.之后,你必须删除 所有 等于 n ...

  5. PHP Excel Word 文件转 HTML输出

    ob_end_clean(); $filePath = './123.xls'; //$filePath = './123.docx'; $savePath = './123.html'; //这里记 ...

  6. 5.3 Linux Vim三种工作模式

    通过前面的学习我们知道,Linux 系统中所有的内容都以文件的形式进行存储,当在命令行下更改文件内容时,常会用到文本编辑器. 我们首选的文本编辑器是 Vim(至于为什么,可查看<Vi和Vim之间 ...

  7. UE4纯C++实现游戏快捷栏

    要想创建一个游戏中的快捷栏我们往往通过以下几步来实现(目录导航): 1.创建UI:我们首先需要有在游戏视口中添加一个快捷栏UI界面,以供玩家看到自身的快捷栏. 2.物品读取:其次有了界面之后我们需要往 ...

  8. 使用tensorboard可视化模型

    Tensorboard是TF自带的可视化工具.它可以让我们从各个角度观察与修改模型,比如观察模型在训练时的loss动态变化曲线而无需在迭代完毕后再画图.绘制神经网络的结构图.调节超参数等.下面以最简单 ...

  9. golang读取文件

    golang 按行读取文件 file, err := os.Open("app-2019-06-01.log") if err != nil { log.Fatal(err) } ...

  10. sqlite3之基础

    最近在用Python借助于pySimpleGui做一个桌面小工具, 奉行小巧,简单的宗旨, 使用了本地数据库sqlite3来进行本地数据的存储 参考: 官网: https://www.sqlite.o ...