たびに大きな頭のシェーダを作る - 簡単な関数から言えば

  最近、おそらく次の図に、メインカメラ角度から見える見えない異なるカメラ視界および範囲をレンダリングする機能。 

  シャドウマップは、同じ原理を達成ちょうど同じように、目に見えるものと見えないオブザーバーカメラをマークするために、単に場所とビューとオブザーバービジョンカメラの一致のメインカメラ分野でデプスマップの変換、世界クラスの座標、毎回に関連していますこのような機能は、そのロジックはシンプルですが、非常に悲しいリマインダーであってもよいが、Unity3Dでのトラブルの多くを行ってます...

  原理:深さを得ることがRenderTextureシートに格納された視聴者カメラをマッピングし、各フラグメントが観察者ならば、世界は、カメラビューポート観察者にワールド座標変換、メインカメラに対応した座標位置を取得しますカメラの視野、ビューポートが対応する深さに格納された座標にUV座標に継続は、その後、RenderTextureが深さ未満の深さよりも観察者に見えるか、または、深さマップと等しい場合は、深さ値は、実際の深度比較に変換される取り除かれますそれは満たすことができません。

 

  どの深チャートば、デプスマップをマークすることができます追加するには、カメラを取得する種類のレンダリングの何に関係なく、初めて目を取得します:

        _cam = GetComponent <カメラ> (); 
        _cam.depthTextureMode | = DepthTextureMode.Depth。

  

  次いで、高精度な点についての奥行きマップ、図にシングルチャネル:

        renderTexture = RenderTexture.GetTemporary(Screen.width、Screen.height、0 、RenderTextureFormat.RFloat)。
        renderTexture.hideFlags = HideFlags.DontSave。

  

  デプスマップにレンダリング処理した後にカメラに直接マップした後: 

    プライベート ボイドOnRenderImage(RenderTexture源、RenderTexture先)
    { 
        場合(_material && _cam)
        { 
            Shader.SetGlobalFloat(" _cameraNear " 、_cam.nearClipPlane)。
            Shader.SetGlobalFloat(" _cameraFar " 、_cam.farClipPlane)。

            Graphics.Blit(ソース、renderTexture、_material)。
        } 
        Graphics.Blit(ソース、デスティネーション); 
    }

  材料は、単純なシェーダ取得深さです。 

    sampler2D _CameraDepthTexture;    
    均一なフロート_cameraFar。
    均一なフロート_cameraNear。
    
    フロート DistanceToLinearDepth(フロート D、フロートの近くに、フロート遠い)
    { 
        フロート Zが=(D -周辺)/(遠く- 周辺)
        リターンZ; 
    } 
    
    fixed4 FRAG(V2F I):SV_Target 
    { 
        フロート深さ= SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture、i.uv)。
        深さ = LinearEyeDepth(深さ)。
        深さ =DistanceToLinearDepth(深さ、_cameraNear、_cameraFar)。
        リターンするfloat4(深さ、深さ、深さ、1 )。
    }
    

 

  ここで少し奇妙な、なぜリターンは、深度マップの深さではない、またそれはLinear01Depth(奥行き)正規化された深さが、彼ら自身の計算された深さでしょうか?

  これは、カメラに直接レンダメソッドを持っているという事実を参照してくださいAPIの公式文書の欠如........は次のとおりです。 

        _cam.SetTargetBuffers(renderTexture.colorBuffer、renderTexture.depthBuffer)。

  しかし、ドキュメンテーションなし例なしああ、悪魔はあなたが私はああ使用方法をレンダリング知らない、renderTexture.depthBufferはテクスチャシェーダああとして渡す方法を最後に...私は以前のように、のIntPtrによってそれらの間の変換動作を試してみましたです失敗...

  彼は、その後、SAMPLE_DEPTH_TEXTUREそれからシェーダをレンダリングデプスマップを通じて最も安全な方法を、使用することができますので(_CameraDepthTexture、i.uv);取得深度値はNDC座標である必要があり、奥行き値の範囲は[0にしてください、1]を右(非線形)の間に、他のカメラの過程で得られた実際の深さは、その後、あなたは自分のLinearEyeDepth(フロートz)は、この方法を実現する必要がある場合:

インラインフロート LinearEyeDepth(フロートZ)
{ 
    リターン 1.0 /(_ZBufferParams.z * Z + _ZBufferParams.w)。
}

  あなたが実現した場合、異なるプラットフォーム、値が同じではありません_ZBufferParamsでは、それは非常に面倒になり、そして私のテストの後、結果は右ではありません......

ダブルX、Y。

OpenGLはなり、この
X =(1.0 - m_FarClip / m_NearClip)/ 2.0 
Y =(1.0 + m_FarClip / m_NearClip)/ 2.0 

D3Dがあり 、この
X = 1.0 - m_FarClip / m_NearClip。
Y = m_FarClip / m_NearClip。

_ZBufferParams =のfloat4(X、Y、X / m_FarClip、Y / m_FarClip)。

  

 

  最後に、基本機能だけで作られたサンプルの深さからの距離の推定値を持っていない何の涙は反対の性別、治療しようとするこれらの必要性のマップを開くがないように、それはギザギザの影のように硬いだけでなく、気持ちのようになります...

おすすめ

転載: www.cnblogs.com/tiancaiwrk/p/11928333.html