unity3d:使用主摄像头的深度缓冲区渲染另一个摄像头视图

Raj*_*aja 6 graphics rendering unity-game-engine

在我的主相机渲染后,我想将其深度缓冲区用于(或复制)到(禁用)相机的深度缓冲区.我的目标是在绘制不透明对象后使用深度缓冲区时将粒子绘制到较小的渲染目标上(使用单独的相机).我无法在单个相机中执行此操作,因为出于性能原因,目标是为粒子使用较小的渲染目标.

Unity中的替换着色器也不是一个选项:我希望我的粒子使用他们现有的着色器 - 我只是希望在绘制粒子之前用主摄像头的深度缓冲器的子采样版本覆盖粒子摄像头的深度缓冲.

我没有得到任何回复我之前的问题 ; 因此,重新发布.

这是附在我的主相机上的脚本.它呈现所有非粒子层,我用它OnRenderImage来调用粒子相机.

public class MagicRenderer : MonoBehaviour {
public Shader   particleShader; // shader that uses the main camera's depth buffer to depth test particle Z
public Material blendMat;       // material that uses a simple blend shader
public int      downSampleFactor = 1;

private RenderTexture particleRT;
private static GameObject pCam;

void Awake () {
    // make the main cameras depth buffer available to the shaders via _CameraDepthTexture
    camera.depthTextureMode = DepthTextureMode.Depth;
}

// Update is called once per frame
void Update () {

}

void OnRenderImage(RenderTexture src, RenderTexture dest) {
            // create tmp RT
            particleRT = RenderTexture.GetTemporary (Screen.width / downSampleFactor, Screen.height / downSampleFactor, 0);
            particleRT.antiAliasing = 1;

            // create particle cam
            Camera pCam = GetPCam ();
            pCam.CopyFrom (camera); 
            pCam.clearFlags = CameraClearFlags.SolidColor;
            pCam.backgroundColor = new Color (0.0f, 0.0f, 0.0f, 0.0f);
            pCam.cullingMask = 1 << LayerMask.NameToLayer ("Particles");
            pCam.useOcclusionCulling = false;
            pCam.targetTexture = particleRT;
            pCam.depth = 0;

            // Draw to particleRT's colorBuffer using mainCam's depth buffer
            // ?? - how do i transfer this camera's depth buffer to pCam?
            pCam.Render ();
            // pCam.RenderWithShader (particleShader, "Transparent"); // I don't want to replace the shaders my particles use; os shader replacement isnt an option.

    // blend mainCam's colorBuffer with particleRT's colorBuffer
    // Graphics.Blit(pCam.targetTexture, src, blendMat);        

    // copy resulting buffer to destination
    Graphics.Blit (pCam.targetTexture, dest);


    // clean up
    RenderTexture.ReleaseTemporary(particleRT);
}

static public Camera GetPCam() {
    if (!pCam) {
        GameObject oldpcam = GameObject.Find("pCam");
        Debug.Log (oldpcam);
        if (oldpcam) Destroy(oldpcam);

        pCam = new GameObject("pCam");
        pCam.AddComponent<Camera>();
        pCam.camera.enabled = false;
        pCam.hideFlags = HideFlags.DontSave;
    }

    return pCam.camera;
}
Run Code Online (Sandbox Code Playgroud)

}

我还有一些问题:

1)为什么camera.depthTextureMode = DepthTextureMode.Depth;最终只是为了写入Z缓冲区而绘制场景中的所有对象?使用英特尔GPA,我会在OnRenderImage调用之前看到两个传递:(i)Z-PrePass,只写入深度缓冲区(ii)颜色传递,写入颜色和深度缓冲区.

2)我使用替换着色器将不透明对象重新渲染到pCam的RT,该着色器将(0,0,0,0)写入colorBuffer ZWrite On(以克服深度缓冲区传输问题).之后,我重置图层并清除掩码,如下所示:

pCam.cullingMask = 1 << LayerMask.NameToLayer ("Particles");
pCam.clearFlags = CameraClearFlags.Nothing;
Run Code Online (Sandbox Code Playgroud)

并使用它们渲染它们pCam.Render().

我认为这将使用ZTest的现有着色器渲染粒子.不幸的是,我注意到深度模板缓冲区在粒子被抽出之前被清除(尽管我没有清除任何东西......).

为什么会这样?

Ger*_*eri 0

我设法在用于渲染的着色器中“手动”重用相机 Z 缓冲区。有关更多信息,请参阅http://forum.unity3d.com/threads/reuse-depth-buffer-of-main-camera.280460/

只需更改已用于粒子渲染的粒子着色器即可。