Shader GrabPass应用实例——高度体积雾(2)

体积的表现

上一节实现了初步的垂直高度雾效果(点击查看链接),在四周开发的情况下,表现不理想,缺少体积的表现。如下图,目前(上一篇实现方案)P点显示的Fog值是根据P'点的高度h计算的,而实际显示的Fog值是与光线的传递长度L有关的,求出L值就可以了,这里主要是使用微分近似的方法,从P点向P'点进行梯度逼近。学习率(逼近值)使用的是0.01m。

Shader GrabPass应用实例——高度体积雾(2)_第1张图片

核心代码如下:

                //使用逼近的方法,求出光线的传递的距离
                int ii = 0; 
                half4 heightColor = tex2Dlod(_HeightTexture, ray.xyww);

                float len = 0;
                for ( ii = 0; ii < steps; ii++)
                {
                	ray.xyz += rayDirOffset;

                	heightColor = tex2Dlod(_HeightTexture, ray.xyww);
                	float curH =  heightColor.r * hMax + _Start;
                	if (ray.y < curH)
                		len += stepOffset;

                	if (len > 2* hMax)
                		break;
                }

效果如下:

Shader GrabPass应用实例——高度体积雾(2)_第2张图片

Shader GrabPass应用实例——高度体积雾(2)_第3张图片

可以看到从侧面也可以看出体的效果了。

引入噪声实现类似云的效果

把上面其中的HeightTexture替换为一个普通的噪声图,调整下UV tile效果就出来了。目前边界边还是有一些问题,后续还需要再进行改进。当然还可以加入一些比如Panner UV平移等操作。

Shader GrabPass应用实例——高度体积雾(2)_第4张图片

Shader GrabPass应用实例——高度体积雾(2)_第5张图片

上图,还有外边界过硬的问题,主要是无法判断是否在Box外,屏幕射线已经射到Box外也,还在进行计算,由于使用的XZ轴平面进行对高度图采样,所有即使采样点在Box外也会获取到高度值,从而加入错误值。这里目前想到的只能是通过判断XZ当前采样点是否在BOX区域内,这种在Shader里加入If else是很耗性能的。

Shader GrabPass应用实例——高度体积雾(2)_第6张图片

你可能感兴趣的:(Shader)