2014-03-27 5 views
5

Nachdem meine Hauptkamera gerendert ist, möchte ich ihren Tiefenpuffer für den Tiefenpuffer einer (deaktivierten) Kamera verwenden (oder kopieren). Mein Ziel ist es, Partikel auf ein kleineres Renderziel zu ziehen (mit einer separaten Kamera), während der Tiefenpuffer verwendet wird, nachdem opake Objekte gezeichnet wurden. Ich kann das nicht in einer einzigen Kamera tun, da das Ziel ist, ein kleineres Renderziel für die Partikel aus Leistungsgründen zu verwenden.unity3d: Verwende den Tiefenpuffer der Hauptkamera zum Rendern einer anderen Kameraansicht

Ersatz-Shader in Unity sind auch keine Option: Ich möchte, dass meine Partikel ihre vorhandenen Shader verwenden - ich möchte nur den Tiefenpuffer der Partikelkamera mit einer unterabgetasteten Version des Tiefenpuffers der Hauptkamera überschreiben Partikel werden gezeichnet.

Ich habe keine Antwort erhalten to my earlier question; daher der Nachschub.

Hier ist das Skript an meine Hauptkamera angeschlossen. Es rendert alle Nichtpartikelschichten und ich benutze OnRenderImage, um die Partikelkamera aufzurufen.

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; 
} 

}

Ich habe ein paar weiteren Fragen:

1) Warum camera.depthTextureMode = DepthTextureMode.Depth; Ende nach oben zeichnet all Objekte in der Szene nur zu dem Z-Puffer zu schreiben? Mit Intel GPA, sehe ich zwei Durchgänge, bevor OnRenderImage ruft: (i) Z-PrePass, die nur in den Tiefenpuffer schreibt (ii) Farbdurchlauf, der sowohl in die Farbe und Tiefe Puffer schreibt.

2) Ich habe die undurchsichtigen Objekte zu pCam RT mit einem Ersatz-Shader, der schreibt (0,0,0,0) in den colorBuffer mit ZWrite On (um das Tiefenpuffer-Transfer-Problem zu überwinden). Danach, setze ich die Schichten und klare Maske wie folgt:

pCam.cullingMask = 1 << LayerMask.NameToLayer ("Particles"); 
pCam.clearFlags = CameraClearFlags.Nothing; 

und machte sie pCam.Render() verwenden.

Ich dachte, dies würde die Partikel mit ihren vorhandenen Shadern mit dem ZTest machen. Leider merke ich, dass der Tiefen-Schablonen-Puffer gelöscht wird, bevor die Partikel gezogen werden (obwohl ich nichts gelöscht habe).

Warum passiert das?

+0

Entschuldigung, ich weiß nicht, wie Sie den Tiefenpuffer kopieren, wie Sie beschreiben. Nur um zu klären, warum nicht Render-Textur für den normalen Anwendungsfall verwenden? Aus der Unity-Dokumentation: - Erstellen Sie ein neues Render-Texture-Asset mit Assets-> Create-> Render Texture. - Erstellen Sie eine neue Kamera mit GameObject-> Create Other-> Camera. - Weisen Sie die Rendertextur der Zieltextur der neuen Kamera zu. - Erstellen Sie eine breite, große und dünne Box - Ziehen Sie die Render Texture auf sie, um ein Material zu erstellen, das die Render-Textur verwendet. - Rufen Sie den Wiedergabemodus auf und beobachten Sie, dass die Textur der Box basierend auf der Ausgabe der neuen Kamera in Echtzeit aktualisiert wird. –

+0

Danke für die Antwort. MSAA für Alpha-Blended Partikel ist zu teuer und ich möchte es reduzieren.Ich kann die Partikel nicht ohne einen Tiefen-Test in eine separate kleine RT rendern, da ich sicherstellen muss, dass Partikel hinter opaken Objekten Z-culted sind. – Raja

+0

haben Sie versucht, die Clear-Flags auf "Nicht löschen" zu setzen, so zu rendern und die Flags dann auf "Clear" und "Render" zu setzen, nur um die Farbe zu löschen? –

Antwort

0

Ich habe es geschafft, Kamera Z-Puffer "manuell" in den Shader zum Rendern verwendet. Siehe http://forum.unity3d.com/threads/reuse-depth-buffer-of-main-camera.280460/ für mehr.

Ändern Sie einfach den Partikel-Shader, den Sie bereits für das Partikel-Rendering verwenden.

+0

Ah, ich wollte den Tiefen-Test im Pixel-Shader vermeiden. Was müssen Sie im Skript tun, um die Tiefenstruktur zu übergeben? Gibt es eine 'Material.SetTexture (" _ CameraDepthTexture ", Camera.main. ' Zeile irgendwo? – Raja

+0

Einfach http://docs.unity3d.com/ScriptReference/Camera-depthTextureMode.html – Geri

+0

Sobald Sie diese Zeile hinzugefügt, die Tiefe Die Textur wird global über alle Shader "angekündigt", zugänglich über '_CameraDepthTexture'. – Geri