|
应用场景主要在聚光灯投射出去有体积的效果。
实现思路和知乎上几个做法差不多,先找交点,然后积分。
求交
首先先求出与锥形的交点,这里用了这里的公式Inigo Quilez,现成的直接抄就好,链接里面有shadertoy的示例
定义几个属性带进去可以把交点求出来,需要注意的点是需要稍微修改下公式把t2也就是远处的交点也求出来。
if( y>0.0 && y<d2 )
{
t1 = float2(t, 1.0);
}
t = (sqrt(h)-k1)/k2;
y = m1 - ra*rr + t*m2;
if( y>0.0 && y<d2 )
{
t2 = float2(t, 1.0);
} 积分
积分公式用的这里的 FOXhunt:游戏开发相关实时渲染技术之体积光,效果不错而且不贵。
float InScatter(vec3 start, vec3 rd, vec3 lightPos, float d)
{
vec3 q = start - lightPos;
float b = dot(rd, q);
float c = dot(q, q);
float iv = 1.0f / sqrt(c - b*b);
float l = iv * (atan( (d + b) * iv) - atan( b*iv ));
return l;
}start是第一个交点,rd是视线,d是两个交点之间的距离(t2-t1)
边缘衰减
用的这位大佬的方法 刘相敬:高质量Mesh体积光渲染
1 - saturate((1 - cosθ) / (1 - cosα) - _InnerRate)
Mesh优化
如果简单的用一个片做Mesh会浪费很多个像素的性能,这里的做法是建一个圆柱把灯的范围包起来,这样我们基本trace的像素都是灯光的范围内,通过顶点着色器改变模型的高度和张角,这几个参数都可以和聚光灯上的属性关联起来。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|