事情是这样的, 这天本来风和日丽,阳光明媚,万里无云。我就想着,用着色器把这般美好的画卷给描绘出来。 于是,我自然而然地想到了,去shaderToy上借鉴一下。 搜索关键字为sky,果然有很多令人击节赞叹的代码。
最开始,我选择了这一份代码,因为看着 着实不错,虽然代码量比较大,但是我只要截取sky的那部分实现就行了。XldGR7
第一份sky代码
很明显,这是三维的, 所以,它肯定也是用了RAYMarch, sky函数应该就是一个sdf函数。 正好这个sky函数相当简短,除开注释就不到10行,大概意思就是在球的sdf基础上,对坐标进行一定程度的偏移,得到一个距离,最后再对这个距离加上一点儿偏移。 偏移使用的是细胞噪声,hash就是随机函数。
我就直接移植到之前的RayMarch架子里, 把这个sky纯纯的作为一个sdf函数。 可是,太卡了,真的卡爆了。 调试无果,算了,我放弃了。 太卡了,之前的代码已经被我删掉了,下面是shaderToy的代码本地化后,仅仅第一个Buffer的结果,天空这一块效果是差不多的。
嗯,差不多。
第二份sky代码
这次我吸取教训,在没有熟读全文的情况下,尽量不搞断章取义的事。 于是我找到一份不足50行的代码,欣喜若狂,才这么点代码,我应该能看明白。 日出日落
算是看明白了,但是这个代码就死在这里了,我无法活用它。后来,让GPT分析了一下,我才知道,这里面用的公式是计算大气散射的。 之前搜mie 没搜出来,mie scatter是一个著名的计算散射的解法。 但是,这个代码我还是不理解,于是又去搜散射的代码。
第三份散射sky代码
这次,我找了个更短的代码 还是日出日落
源代码是真的短, 因为它把公式的结果直接写在一行了!!! 我当然要拆分一下啊,拆分后如下。 其实这代码对我来说还是死的, 因为我发现这个散射是整个天空区域都是联动的, 这一系列的公式计算。 本来只有两行计算的,分别是计算太阳的,和计算剩余大气的, 用的是加法。
结语
虽然说,好的效果,往往只需要简单的代码。但是有些东西很明显,它不可能真的那么简单。如果它真的很简单,那肯定是比较黑盒的,看到只是一个结果,就像上面后两份代码,是把公式的计算代数结果直接放上去了,但是你不知它是怎么来的,难以灵活运用。
学习,对于我这种没有天分的人来说,终究是要一步一个脚印,不能怕麻烦。
等理解了散射公式的运用,再来细说。