100多行代码实现纯算法云海效果
文章目录
- 准备工作
- 光线步进
- 分数噪声
- 基本实现
- 光照计算
- 云层移动
- 相机控制
- 完整代码
准备工作
我们采用shadertoy
作为工具,在它上面编写代码,查看效果。打开shadertoy
,在右上角直接点击新建,即可创建一个新的着色器,可以看到如下的初始代码:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{// Normalized pixel coordinates (from 0 to 1)vec2 uv = fragCoord/iResolution.xy;// Time varying pixel colorvec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));// Output to screenfragColor = vec4(col,1.0);
}
显示结果如下:
其中mainImage
是入口函数,参数fragColor
是输出结果,fragCoord
是当前的像素坐标。将代码修改如下(后面带// new
的表示新增代码):
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{vec2 uv = fragCoord / iResolution.xy;uv = 2.0 * uv - 1.0; // newuv.x *= iResolution.x / iResolution.y; // newfragColor = vec4(1.0);
}
由于画布的宽高是不一样的,也为了方便计算,所以新增了两行代码先将uv转换到[-1, 1]
范围内,再根据宽高比对x
的值进行调整。
光线步进
游戏采用的一般是光栅化的方式进行渲染,现在部分显卡和引擎也支持了光线追踪,光线步进的思路和追踪很相似,都是从观察点发射一束光线,然后计算它最终的颜色,只不过追踪采用的是几何体交叉判断,而步进采用的是有符号距离函数(SDF
)来判断。
SDF
的返回值d
表示当前位置距离几何体的最近距离,其含义如下:
- d > 0,当前位置在几何体外,距离几何体表面最近距离为d
- d == 0,当前位置正好在几何体表面
- d < 0, 当前位置在几何体内,距离几何体表面最近距离为-d
我们参考光线步进的做法,但是将SDF的含义修改一下,让其返回值表示当前位置的云的密度。如果小于0,则表示在云层外,如果大于0则表示当前位置云层的密度,后续我们根据这个密度来计算当前位置的颜色。我们添加一个getDensity
函数来计算密度,和一个render
函数来计算颜色:
float getDensity(in vec3 pos) {return 1.0;
}// ori:观察位置
// dir:观察方向
vec4 render(in vec3 ori, in vec3 dir) {return vec4(1.0);
}
在主函数中调用render
函数:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{vec2 uv = fragCoord/iResolution.xy;uv = 2.0 * uv - 1.0; // newuv.x *= iResolution.x / iResolution.y; // newvec3 ori = 4.0 * vec3(0.0, 0.3, -1.0); // newvec3 dir = normalize(vec3(uv.xy, 1.5)); // newfragColor = render(ori, dir); // new
}
此时的渲染结果应为一个纯白的画布,接下来首先来完成getDensity
函数。
分数噪声
getDensity
决定了云的形状,一般通过噪声贴图来实现,但由于我们不使用任何纹理,所以可以通过噪声函数来生成,普通的噪声离散性较强,与云的形状不符合,我们采用分数噪声函数来生成云的形状,其基本原理如下图所示:
修改代码如下:
float hash(vec3 p)
{p = fract(p * 0.3183099 + .1);p *= 17.0;return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
}float noise(in vec3 x)
{vec3 i = floor(x);vec3 f = fract(x);f = f * f * (3.0 - 2.0 * f);return mix(mix(mix( hash(i+vec3(0,0,0)), hash(i+vec3(1,0,0)),f.x),mix( hash(i+vec3(0,1,0)), hash(i+vec3(1,1,0)),f.x),f.y),mix(mix( hash(i+vec3(0,0,1)), hash(i+vec3(1,0,1)),f.x),mix( hash(i+vec3(0,1,1)), hash(i+vec3(1,1,1)),f.x),f.y),f.z);
}float getDensity(in vec3 pos) {vec3 q = pos;float g = 0.5 + 0.5 * noise(q * 0.3);float f = 0.60000 * noise(q); q = q *
100多行代码实现纯算法云海效果相关推荐
- 120 行代码实现纯 Web 剪辑视频
翁佳瑞:微医前端技术部前端工程师,一个爱玩 dota2 的咸鱼. 前言 前几天偶尔看到一篇 webassembly 的相关文章,对这个技术还是挺感兴趣的,在了解一些相关知识的基础上,看下自己能否小小的 ...
- CSS 快速实现烟花绽放(仅100多行代码)
关注公众号 前端热榜,回复"简历" 领取程序员简历模板 最近项目上需要做一个烟花动画,要求是随机大小,不同地方出现,先看效果 Kapture 2021-08-20 at 23.17 ...
- 12行代码AC——试题 算法训练 猴子吃包子——解题报告
励志用尽量少的代码做高效的表达. 注意点: 挨个算吃包子的时间势必会因为省略小数的问题导致结果不准确. 因此,对于本题:我的核心思路是:分数代替小数,使用除法+取余的方式化简分数,进而解题. 代码: ...
- c语言入门级小游戏·飞机(2.0版)| 激发你的编程兴趣(100~150行代码)
目录 前言 制作可以自由移动并且发射子弹的飞机 介绍第一种清屏函数system("cls") 介绍kbhit函数 介绍方便的getch()函数 添加可以自己移动.击落后会重生的障碍 ...
- 贪吃蛇c语言代码高难,100多行代码的《贪吃蛇》
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 耗费两节课,调试到一个不错的效果. http://www.lugede.cn 注意:使用前请确保TC文件夹位于D:\TC目录下. ------- #inc ...
- 几行代码自定义view实现聚光灯效果
效果图 核心代码 @Overrideprotected void onDraw(Canvas canvas) {Bitmap bitmapPic=BitmapFactory.decodeResourc ...
- Android进阶学习--十几行代码实现美女撕衣服效果
效果图: 在这篇文章文章里有介绍过PorterDuffXfermode这个类,下面来用这个知识点来实现一下那种撕衣服的特效,先给两张图片: 上面叫做bg.jpg,下面叫做fg.jpg 然后就直 ...
- python写一个类600行代码_带你领略算法的魅力,一个600行代码的分词功能实现(二)...
从大学毕业到工作的开始几年,一直觉得大学期间学的线性代数,离散数学,概率论简直是浪费时间. 那时候实际做的代码,大部分都是数据进销存.数据输入到数据库介质中的转换,CS,BS架构都写过一些.总觉得现实 ...
- 手把手教你!100行代码,用Python做一个“消灭病毒”的小游戏
公众号关注 "菜鸟学Python" 设为 "星标",重磅干货,第一时间送达! 烟花三月下扬州,我想3月能下楼.虽然很多地方都已经开始慢慢的开放了,但是我怀念的胡 ...
- 尤雨溪写的100多行的“玩具 vite”,十分有助于理解 vite 原理
1. 前言 大家好,我是若川.最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 想学源码,极力推荐之前我写的<学习源码整体架构系列>jQuery.underscore.l ...
最新文章
- Python——基于OpenCV获取倾斜子图的一种方法
- java高级反射_反射---Java高级开发必须懂的
- 我的世界java村民繁殖_我的世界:1.14版本刷新几率小的五种村庄,没有村民咋回事?...
- Java基础学习总结(109)——Jdk动态代理和cglib动态代理总结
- (一二四)给类对象赋值、以及类对象的返回值
- android factory,“工厂映像”(factory image)是什么?你所不知道的Android问题
- 数据分析:AI智能科技影响下,电话机器人实现落地
- 源码安装php5.5
- 干货,分享!后台模板hplus 好看的后台纯模板!!!
- LWIP协议栈详解(1)_LWIP协议与网络分层
- 2020年百度之星程序设计大赛-初赛一(Drink、GPA、Dec)
- 计算机辅助翻译术语PPT,计算机辅助翻译
- GD32F103学习笔记(1)——搭建环境、编译烧写
- 关于HD-SDI原理设计、PCB设计汇总
- 白话区块链~Pow,PoS,DPos
- 直播美颜SDK从技术层面如何自行实现
- php model module,Yii2用Gii自动生成Module+Model+CRUD
- 我们的征程是星辰大海
- 微信分享签名无效php_【求助】微信分享朋友圈失效
- comsol-添加线圈几何分析
热门文章
- Linux 中chmod或者rm 一个文件时出现 not permitted--Unable to delete file, even when running as root
- 模块三、修改存款、提款方法
- 机器狗的新面孔:开机登录时出现0x0000008E蓝屏错误1
- windows下引导双系统卸载Linux
- oracle数据库ams,【学习笔记】Oracle ASM 数据库ASM下载与配置手册
- 把多线程当成一个人,你瞬间就能明白它的原理
- 这些Dubbo面试题你都掌握了吗,还是略知一二
- 数据中台为什么要汇聚数据?_光点科技
- 15个步骤收获一生的学习习惯
- 回顾前端漫漫一年自学路