当前位置: 首页 > news >正文

Cesium深入浅出之shadertoy篇

引言

要学好 Cesium,先学好 shader,但如果你还不知道 shadertoy,那你可能要错失一个亿。

大家好,懒人回归!我看了一下,距离上一次更新居然有一年半之久!好吧,像我这么懒的估计运营个啥都不会长久,所以第N次下定决心,勤奋起来,加油!

初入 shadertoy,看着上面那眼花缭乱的效果,着实让我震惊,没想到看着不起眼的着色器语言居然能那么强大,做个材质是最小儿科的,做个酷炫的视频都不在话下,更夸张的是居然有人能用它做个游戏。当时就萌生一个想法,这么牛的效果咱能不能抄~啊不~是借鉴到 Cesium 当中呢?

预期效果

在 Cesium 中,使用着色器语言的主要有后期处理、材质样式等地方。着色器主要分为顶点着色器和片元着色器,其中后期处理主要是写片元着色器,材质样式可以写顶点着色器和片元着色器,而材质要写材质着色器,其实也是一种片元着色器,只是主函数名称有所差异。上一篇文章我们刚好讲了 Cesium 自定义材质的入门,那么今天我们就使用材质的方式来移植 shadertoy 的代码吧。

实现原理

Cesium 的材质类是 Cesium.Material,上一篇文章已经详细讲过了,这里不赘述了,有需要的请移步《Cesium深入浅出之自定义材质》。另外也可以参考官网沙盒中的 Material with Custom GLSL。

其实移植的过程并不复杂,因为毕竟 glsl 是相通的,核心代码基本复用,无非是将两个平台的不同标准修改一下即可。下面我们以一个具体示例来做一下试试吧。

具体实现

先从 shadertoy 上找一个案例,我觉得这个流动炫彩的还不错,简单几行代码就出来很棒的效果。试想一下把它做成一个立体的光幕或者是电子围墙,逼格一定很高吧。

案例代码主要分为两个部分,Common 和 Image,顾名思义 Common 中会写一些通用的函数之类的,而 Image 是主要的实现。这里我们把原始代码也贴一下。

着色器输入
uniform vec3      iResolution;           // viewport resolution (in pixels)
uniform float     iTime;                 // shader playback time (in seconds)
uniform float     iTimeDelta;            // render time (in seconds)
uniform float     iFrameRate;            // shader frame rate
uniform int       iFrame;                // shader playback frame
uniform float     iChannelTime[4];       // channel playback time (in seconds)
uniform vec3      iChannelResolution[4]; // channel resolution (in pixels)
uniform vec4      iMouse;                // mouse pixel coords. xy: current (if MLB down), zw: click
uniform samplerXX iChannel0..3;          // input channel. XX = 2D/Cube
uniform vec4      iDate;                 // (year, month, day, time in seconds)
Common
vec2 stanh(vec2 a) {return tanh(clamp(a, -40.,  40.));
}
Image
// -13 thanks to Nguyen2007 ⚡void mainImage( out vec4 o, vec2 u )
{vec2 v = iResolution.xy;u = .2*(u+u-v)/v.y;    vec4 z = o = vec4(1,2,3,0);for (float a = .5, t = iTime, i; ++i < 19.; o += (1. + cos(z+t)) / length((1.+i*dot(v,v)) * sin(1.5*u/(.5-dot(u,u)) - 9.*u.yx + t)))  v = cos(++t - 7.*u*pow(a += .03, i)) - 5.*u, // use stanh here if shader has black artifacts//   vvvvu += tanh(40. * dot(u *= mat2(cos(i + .02*t - vec4(0,11,33,0))),u)* cos(1e2*u.yx + t)) / 2e2+ .2 * a * u+ cos(4./exp(dot(o,o)/1e2) + t) / 3e2;o = 25.6 / (min(o, 13.) + 164. / o) - dot(u, u) / 250.;
}

可以看到核心的代码实现非常简单,反倒是着色器输入那块看着挺复杂,其实这些参数大部分是关于 shadertoy 场景设置的,无须太过关心,我们只做必要的转换。我们先来看看这些参数主要是做什么的吧。

  • iResolusion:视口分辨率,以像素为单位。不过这个参数是 vec3 类型的,长和宽,还有高?本案例的分辨率是 640 x 360。
  • iTime:着色器播放的时间,以秒为单位。
  • iTimeDelta:渲染时间,以秒为单位。
  • iFrameRate:着色器帧率。每秒播放多少帧,也就是 fps。
  • iFrame:着色器播放帧。当前播放到第几帧,这个可以用作动态材质。
  • iChannelTime:通道播放时长,以秒为单位。
  • iChannelResolusion:通道分辨率,以像素为单位。
  • iMouse:鼠标像素坐标。xy 标示鼠标坐标,zw 标示鼠标按键状态。上面提到过的着色器做游戏就要用到它,毕竟只有能交互的才叫游戏,不能交互的只能叫视频。
  • iChanel:输入通道。
  • iDate:日期(年、月、日、时间)。

通常,我们都要用到 iResolusion 这个参数,因为图像计算是依赖于分辨率的,还有就是 iFrame,是通过帧让图像动起来。OK,现在开启改造之旅!

主体结构

的主函数是 mainImage,通过上一篇文章我们知道 Cesium 的材质主函数是 czm_getMaterial。

czm_material czm_getMaterial(czm_materialInput materialInput)
{czm_material material = czm_getDefaultMaterial(materialInput);// Write code here.return material;
}
内部实现

这个案例中 shadertoy 的参数用到了 iResolusion 和 iTime,因此要对其进行处理。输出参数 o 是 vec4 类型的,其中 xyz 对应 material.diffuse,w 对应 material.alpha。

uniform float time;czm_material czm_getMaterial(czm_materialInput materialInput) {czm_material material = czm_getDefaultMaterial(materialInput);vec2 st = materialInput.st;// iTime 通过 uniform 传值进来。float iTime =  time;// iResolution 主要是做分辨率修正的,我们可以忽略它。vec2 v; // vec2 v = iResolution.xy;vec2 u = st * .2; // vec2 u = .2 * (st + st - v) / v.y;    vec4 o;vec4 z = o = vec4(1, 2, 3, 0);for (float a = .5, t = iTime, i; ++i < 19.; o += (1. + cos(z + t))/ length((1. + i * dot(v, v)) * sin(1.5 * u / (.5 - dot(u, u)) - 9. * u.yx + t))){v = cos(++t - 7.*u*pow(a += .03, i)) - 5.*u, u += tanh(40. * dot(u *= mat2(cos(i + .02*t - vec4(0,11,33,0))), u) * cos(1e2*u.yx + t)) / 2e2+ .2 * a * u+ cos(4./exp(dot(o,o)/1e2) + t) / 3e2;}o = 25.6 / (min(o, 13.) + 164. / o) - dot(u, u) / 250.;material.diffuse = o.xyz;material.alpha = o.w * 2.;return material;
}

运行测试,效果如下:

怎么说呢,效果差异就挺大的吧,毕竟是不同的平台吧,不能要求那么高,如果想要达到和 shadertoy 平台一样的效果估计还得做些优化吧,不过那不在本次探讨范围之内。

小结

本篇暂且写到这,但并不是到此为止,随便找的例子,效果并不是太好,后续可能会找些更好的例子更新上来。最后,欢迎到 854943530 部落来。


文章转载自:

http://3zlU2rfY.zwndt.cn
http://x0xpxQre.zwndt.cn
http://AW4YbPru.zwndt.cn
http://z6XwkJrn.zwndt.cn
http://rfyvZA4i.zwndt.cn
http://KCsk3c61.zwndt.cn
http://5lcChtfz.zwndt.cn
http://LQBsOSfO.zwndt.cn
http://DYEnE3Tb.zwndt.cn
http://2qI0dRan.zwndt.cn
http://XAeqmvgS.zwndt.cn
http://LIPCbkJv.zwndt.cn
http://vEry3EVH.zwndt.cn
http://yTXeHEBw.zwndt.cn
http://vAkptkQH.zwndt.cn
http://j2AGVTCr.zwndt.cn
http://8pHFeM5O.zwndt.cn
http://DzlVpv1c.zwndt.cn
http://OYmCHkYW.zwndt.cn
http://0VHfkhyN.zwndt.cn
http://eHuyxCed.zwndt.cn
http://Y77R8QAr.zwndt.cn
http://KGldRq0y.zwndt.cn
http://xLNnJU9O.zwndt.cn
http://dhskKXnr.zwndt.cn
http://3KoRjHr0.zwndt.cn
http://na2lL52a.zwndt.cn
http://fheoXsFV.zwndt.cn
http://Kkqvw6d7.zwndt.cn
http://T5t47Vb5.zwndt.cn
http://www.dtcms.com/a/378510.html

相关文章:

  • LoRaWAN网关支持双NS的场景有哪些?
  • BigVGAN:探索 NVIDIA 最新通用神经声码器的前沿
  • SpringTask和XXL-job概述
  • 软考系统架构设计师之软件维护篇
  • 从CTF题目深入变量覆盖漏洞:extract()与parse_str()的陷阱与防御
  • 第五章:Python 数据结构:列表、元组与字典(二)
  • Flow Matching Guide and Code(3)
  • 内存泄漏一些事
  • 嵌入式学习day47-硬件-imx6ul-LED、Beep
  • 【数据结构】队列详解
  • C++/QT
  • GPT 系列论文1-2 两阶段半监督 + zero-shot prompt
  • 昆山精密机械公司8个Solidworks共用一台服务器
  • MasterGo钢笔Pen
  • 【算法--链表】143.重排链表--通俗讲解
  • 数据库的回表
  • 《Learning Langchain》阅读笔记13-Agent(1):Agent Architecture
  • MySQL索引(二):覆盖索引、最左前缀原则与索引下推详解
  • 【WS63】星闪开发资源整理
  • 守住矿山 “生命线”!QB800系列在线绝缘监测在矿用提升机电传系统应用方案
  • Altium Designer(AD)原理图更新PCB后所有器件变绿解决方案
  • DIFY 项目中通过 Makefile 调用 Dockerfile 并使用 sudo make build-web 命令构建 web 镜像的方法和注意事项
  • 联合索引最左前缀原则原理索引下推
  • 平衡车 -- 速度环
  • BPE算法深度解析:从零到一构建语言模型的词元化引擎
  • DIPMARK:一种隐蔽、高效且具备鲁棒性的大语言模型水印技术
  • mysql多表联查
  • 审美积累 | 移动端仪表盘
  • 面阵结构光3D相机三维坐标计算
  • 【大前端++】几大特征