zoukankan      html  css  js  c++  java
  • 体积雾 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

  • 相关阅读:
    TyporaRecord
    c# 串口 应答式顺序下发命令 循环 间隔发送指令
    WPF 如何在单独的配置文件中使用Log4net
    UWP VisualStateManager
    USB通信
    UWP RelativePanel
    JSON 序列化与反序列化
    Unity 依赖注入的三种常用模板
    IOC Unity容器的基本使用
    使用EF完成基于SQLite的CodeFirst
  • 原文地址:https://www.cnblogs.com/minggoddess/p/10102269.html
Copyright © 2011-2022 走看看