文章目录

  • 准备工作
  • 光线步进
  • 分数噪声
  • 基本实现
  • 光照计算
  • 云层移动
  • 相机控制
  • 完整代码

准备工作

我们采用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多行代码实现纯算法云海效果相关推荐

  1. 120 行代码实现纯 Web 剪辑视频

    翁佳瑞:微医前端技术部前端工程师,一个爱玩 dota2 的咸鱼. 前言 前几天偶尔看到一篇 webassembly 的相关文章,对这个技术还是挺感兴趣的,在了解一些相关知识的基础上,看下自己能否小小的 ...

  2. CSS 快速实现烟花绽放(仅100多行代码)

    关注公众号 前端热榜,回复"简历" 领取程序员简历模板 最近项目上需要做一个烟花动画,要求是随机大小,不同地方出现,先看效果 Kapture 2021-08-20 at 23.17 ...

  3. 12行代码AC——试题 算法训练 猴子吃包子——解题报告

    励志用尽量少的代码做高效的表达. 注意点: 挨个算吃包子的时间势必会因为省略小数的问题导致结果不准确. 因此,对于本题:我的核心思路是:分数代替小数,使用除法+取余的方式化简分数,进而解题. 代码: ...

  4. c语言入门级小游戏·飞机(2.0版)| 激发你的编程兴趣(100~150行代码)

    目录 前言 制作可以自由移动并且发射子弹的飞机 介绍第一种清屏函数system("cls") 介绍kbhit函数 介绍方便的getch()函数 添加可以自己移动.击落后会重生的障碍 ...

  5. 贪吃蛇c语言代码高难,100多行代码的《贪吃蛇》

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 耗费两节课,调试到一个不错的效果. http://www.lugede.cn 注意:使用前请确保TC文件夹位于D:\TC目录下. ------- #inc ...

  6. 几行代码自定义view实现聚光灯效果

    效果图 核心代码 @Overrideprotected void onDraw(Canvas canvas) {Bitmap bitmapPic=BitmapFactory.decodeResourc ...

  7. Android进阶学习--十几行代码实现美女撕衣服效果

        效果图: 在这篇文章文章里有介绍过PorterDuffXfermode这个类,下面来用这个知识点来实现一下那种撕衣服的特效,先给两张图片: 上面叫做bg.jpg,下面叫做fg.jpg 然后就直 ...

  8. python写一个类600行代码_带你领略算法的魅力,一个600行代码的分词功能实现(二)...

    从大学毕业到工作的开始几年,一直觉得大学期间学的线性代数,离散数学,概率论简直是浪费时间. 那时候实际做的代码,大部分都是数据进销存.数据输入到数据库介质中的转换,CS,BS架构都写过一些.总觉得现实 ...

  9. 手把手教你!100行代码,用Python做一个“消灭病毒”的小游戏

    公众号关注 "菜鸟学Python" 设为 "星标",重磅干货,第一时间送达! 烟花三月下扬州,我想3月能下楼.虽然很多地方都已经开始慢慢的开放了,但是我怀念的胡 ...

  10. 尤雨溪写的100多行的“玩具 vite”,十分有助于理解 vite 原理

    1. 前言 大家好,我是若川.最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 想学源码,极力推荐之前我写的<学习源码整体架构系列>jQuery.underscore.l ...

最新文章

  1. Python——基于OpenCV获取倾斜子图的一种方法
  2. java高级反射_反射---Java高级开发必须懂的
  3. 我的世界java村民繁殖_我的世界:1.14版本刷新几率小的五种村庄,没有村民咋回事?...
  4. Java基础学习总结(109)——Jdk动态代理和cglib动态代理总结
  5. (一二四)给类对象赋值、以及类对象的返回值
  6. android factory,“工厂映像”(factory image)是什么?你所不知道的Android问题
  7. 数据分析:AI智能科技影响下,电话机器人实现落地
  8. 源码安装php5.5
  9. 干货,分享!后台模板hplus 好看的后台纯模板!!!
  10. LWIP协议栈详解(1)_LWIP协议与网络分层
  11. 2020年百度之星程序设计大赛-初赛一(Drink、GPA、Dec)
  12. 计算机辅助翻译术语PPT,计算机辅助翻译
  13. GD32F103学习笔记(1)——搭建环境、编译烧写
  14. 关于HD-SDI原理设计、PCB设计汇总
  15. 白话区块链~Pow,PoS,DPos
  16. 直播美颜SDK从技术层面如何自行实现
  17. php model module,Yii2用Gii自动生成Module+Model+CRUD
  18. 我们的征程是星辰大海
  19. 微信分享签名无效php_【求助】微信分享朋友圈失效
  20. comsol-添加线圈几何分析

热门文章

  1. Linux 中chmod或者rm 一个文件时出现 not permitted--Unable to delete file, even when running as root
  2. 模块三、修改存款、提款方法
  3. 机器狗的新面孔:开机登录时出现0x0000008E蓝屏错误1
  4. windows下引导双系统卸载Linux
  5. oracle数据库ams,【学习笔记】Oracle ASM 数据库ASM下载与配置手册
  6. 把多线程当成一个人,你瞬间就能明白它的原理
  7. 这些Dubbo面试题你都掌握了吗,还是略知一二
  8. 数据中台为什么要汇聚数据?_光点科技
  9. 15个步骤收获一生的学习习惯
  10. 回顾前端漫漫一年自学路