體積霧 global fog unity 及改進


 

 

https://github.com/keijiro/KinoFog

lighting box 2.7.2

halfspace fog 相機位於一個位置 這個位置可以在fog volumn里面或者外面  霧開始的地方就是文中的plane

http://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf

 

這個fog volume可以從中間某個位置height 這個平面產生霧 遠近濃度通過depth深度計算

 

 

還可以定義霧密度 

    // Applies one of standard fog formulas, given fog coordinate (i.e. distance)
    half ComputeFogFactor (float coord)
    {
        float fogFac = 0.0;
        if (_SceneFogMode.x == 1) // linear
        {
            // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
            fogFac = coord * _SceneFogParams.z + _SceneFogParams.w;
        }
        if (_SceneFogMode.x == 2) // exp
        {
            // factor = exp(-density*z)
            fogFac = _SceneFogParams.y * coord; fogFac = exp2(-fogFac);
        }
        if (_SceneFogMode.x == 3) // exp2
        {
            // factor = exp(-(density*z)^2)
            fogFac = _SceneFogParams.x * coord; fogFac = exp2(-fogFac*fogFac);
        }
        return saturate(fogFac);
    }

    // Distance-based fog
    float ComputeDistance (float3 camDir, float zdepth)
    {
        float dist; 
        if (_SceneFogMode.y == 1)
            dist = length(camDir);
        else
            dist = zdepth * _ProjectionParams.z;
        // Built-in fog starts at near plane, so match that by
        // subtracting the near value. Not a perfect approximation
        // if near plane is very large, but good enough.
        dist -= _ProjectionParams.y;
        return dist;
    }

     float ComputeHalfSpace (float3 wsDir)
    {
        float3 wpos = _CameraWS + wsDir;
        float FH = _HeightParams.x;
        float3 C = _CameraWS;
        float3 V = wsDir;
        float3 P = wpos;
        float3 aV = _HeightParams.w * V;
        float FdotC = _HeightParams.y;
        float k = _HeightParams.z;
        float FdotP = P.y-FH;
        float FdotV = wsDir.y;
        float c1 = k * (FdotP + FdotC);
        float c2 = (1-2*k) * FdotP;
        float g = min(c2, 0.0);
        g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
        return g;
    }

FdocC = camPos.y-height.value;      height  就是halfplane所定義的高度 plane法線垂直向上

       // Calculate vectors towards frustum corners.
            var cam = GetComponent<Camera>();
            var camtr = cam.transform;
            var camNear = cam.nearClipPlane;
            var camFar = cam.farClipPlane;

            var tanHalfFov = Mathf.Tan(cam.fieldOfView * Mathf.Deg2Rad / 2);
            var toRight = camtr.right * camNear * tanHalfFov * cam.aspect;
            var toTop = camtr.up * camNear * tanHalfFov;

            var v_tl = camtr.forward * camNear - toRight + toTop;
            var v_tr = camtr.forward * camNear + toRight + toTop;
            var v_br = camtr.forward * camNear + toRight - toTop;
            var v_bl = camtr.forward * camNear - toRight - toTop;

            var v_s = v_tl.magnitude * camFar / camNear;

            // Draw screen quad.
            RenderTexture.active = destination;

            _material.SetTexture("_MainTex", source);
            _material.SetPass(0);

            GL.PushMatrix();
            GL.LoadOrtho();
            GL.Begin(GL.QUADS);

            GL.MultiTexCoord2(0, 0, 0);
            GL.MultiTexCoord(1, v_bl.normalized * v_s);
            GL.Vertex3(0, 0, 0.1f);

            GL.MultiTexCoord2(0, 1, 0);
            GL.MultiTexCoord(1, v_br.normalized * v_s);
            GL.Vertex3(1, 0, 0.1f);

            GL.MultiTexCoord2(0, 1, 1);
            GL.MultiTexCoord(1, v_tr.normalized * v_s);
            GL.Vertex3(1, 1, 0.1f);

            GL.MultiTexCoord2(0, 0, 1);
            GL.MultiTexCoord(1, v_tl.normalized * v_s);
            GL.Vertex3(0, 1, 0.1f);

            GL.End();
            GL.PopMatrix();

 

這里是用了一個quard我做到用trangle了

要銘記一點 quard 和trangle的插值結果 頂多數據傳對了 插值是一樣的 沒有差別 因為都是線性的 這個問題我想了好幾個小時!

uv 和pos肯定是一樣的 dir也是一樣的 因為也是線性的

這意味着我接下來可以做大面積優化了 好開心

mg你太棒了 這個小故事告訴我們代碼要每一行都看懂 不要再像黑盒那樣抄了

Vector3 topLeft3 = topLeft*2-bottomLeft;//2

Vector3 bottomRight3 = bottomRight*2 -bottomLeft;//1

Vector3 topRight3= bottomRight3+topLetf3;//0

這里因為scale過到farplane不能在原始那個nearplane的數據直接3x

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM