【UnityShader】光线追踪体积光

最近尝试实现了一下光线追踪体积光,效果以下:算法




光线追踪(Ray tracing)是三维计算机图形学中的特殊渲染算法,跟踪从眼睛发出的光线而不是光源发出的光线,经过这样一项技术生成编排好的场景的数学模型显现出来。(摘自维基百科)cookie



实现步骤:app

1、在灯光区域生成体积光的载体mesh,即咱们的体积光其实是渲染在mesh上的,所以光线追踪的起点是每一个顶点的位置,并计算出该顶点的视线方向,延视线进行递进:性能


2、在灯光空间生成深度图渲染相机:.net

咱们须要在射线递进的过程当中经过比较深度来判断是否当前点处于光线不可到达的遮挡位置,以此来渲染体积光中的阴影位置,这里我渲染了视空间深度(固然若是考虑直接使用unity的阴影贴图也能够,这样就能够直接为unity灯光添加体积光效果了):3d


Pass
{
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"
 
    struct v2f
    {
        float4 vertex : SV_POSITION;
        float depth : TEXCOORD0;
    };
                 
    v2f vert(appdata_base v)
    {
        v2f o;
        UNITY_INITIALIZE_OUTPUT(v2f, o);
        o.vertex = UnityObjectToClipPos(v.vertex);
        o.depth = COMPUTE_DEPTH_01;
        return o;
    }
                 
    fixed4 frag(v2f i) : SV_Target
    {
        return EncodeFloatRGBA(i.depth);
    }
    ENDCG
}

3、光线追踪:code

为了在每次递进后能够方便的采样深度图,我将递进的过程放到了投影空间,而且在投影空间下能够方便的计算每次递进的距离:blog

for (float k = 0; k< RAY_STEP; k++) {
    float4 curpos = beginPjPos;
    float3 vdir = pjViewDir.xyz*k*delta;
    curpos.xyz += vdir;
 
    half cdep = LinearLightEyeDepth(-curpos.z);
    float boardFac = step(-1, curpos.x)*step(-1, curpos.y)*step(-1, curpos.z)*step(curpos.x, 1)*step(curpos.y, 1)*step(curpos.z, 1);
    curpos = ComputeScreenPos(curpos);
    half2 pjuv = curpos.xy / curpos.w;
#if UNITY_UV_STARTS_AT_TOP
    pjuv.y = 1 - pjuv.y;
#endif
 
#ifdef USE_COOKIE
    fixed4 cookie = tex2D(internalCookie, pjuv);
    fixed3 cookiecol = cookie.rgb*cookie.a;
#else
    half2 toCent = pjuv - half2(0.5, 0.5);
    half l = 1 - saturate((length(toCent) - 0.3) / (0.5 - 0.3));
    fixed3 cookiecol = fixed3(l, l, l);
#endif
 
    half dep = DecodeFloatRGBA(tex2D(internalShadowMap, pjuv)) / internalProjectionParams.w;
    float shadow = step(cdep, dep) *(1 - saturate(cdep*internalProjectionParams.w));
 
    col.rgb += cookiecol*i.vcol.rgb*delta / 2 * boardFac*shadow;
}

另外,考虑到在片断着色器下进行递进可能比较影响性能,能够尝试在顶点着色器下执行,注意若是在顶点着色器执行须要适当的增长载体mesh的顶点数量,不然可能没法达到较精确的效果,以下:




Demo GitHub连接请点击http://www.lsngo.net/2017/10/22/unityshader_volumetriclight/ip

更多文章:http://www.lsngo.netci