Dies ist eine Hardwarebeschränkung. Der Fragment-Shader ist Teil der programmierbaren Pipeline, aber die endgültige Farbmischung mit den Zielpuffern ist in weit verbreiteter Hardware / Commodity-Hardware derzeit nicht programmierbar (sie kann über Mischzustände konfiguriert werden, Sie können jedoch keine willkürlichen Werte schreiben Code, der die integrierten Mischvorgänge der GPUs ersetzt).
Der Grund, warum die Hardware nicht dafür gebaut wurde, hängt wahrscheinlich damit zusammen, dass die GPUs massiv parallel sind. Sie verarbeiten viele Fragmente gleichzeitig. Einige dieser Fragmente können letztendlich innerhalb der Zielpuffer miteinander interagieren, aber aufgrund der asynchronen Art der Fragmentverarbeitung ist es nicht möglich zu wissen, wie, bis das Fragment verarbeitet und die endgültige Farbe ausgegeben wurde ... was gewonnen hat passiert nicht immer deterministisch.
Nur weil Pixel A im letzten Frame hinter Pixel B liegt, bedeutet dies nicht, dass Pixel A immer die Fragmentverarbeitung abschließt und vor B an das Ziel geschrieben wird, insbesondere über mehrere Rendering-Frames hinweg. Der während der Verarbeitung von Pixel B aus dem Zielpuffer gelesene Wert ist also nicht immer der Wert von Pixel A - manchmal sind es die eindeutigen Werte.
Ich vermute also, dass das Nichtzulassen von direkten Zielpuffer-Lesevorgängen während der Fragmentierungsphase weit mehr damit zu tun hat, den Shader-Programmierer daran zu hindern, sich in den Fuß zu schießen, indem er potenziell nicht deterministische Ergebnisse aus diesen Lesevorgängen erhält, als aus irgendwelchen tatsächlichen technischen Einschränkungen bei der vollständigen Erstellung der Mischphase. programmierbar. Indem die Leseoperationen streng kontrolliert werden (zum Beispiel der Tiefentest), stellt die GPU sicher, dass die Operationen, die mit dem gelesenen Wert ausgeführt werden, einen Sinn ergeben.
Das heißt, es kann auch eine Kosten / Nutzen-Sache geben. Wenn dieser Aspekt der GPU-Pipeline programmierbar wäre, würde dies das Chipdesign etwas komplizieren, und der Bedarf / die Nachfrage nach Lesevorgängen für den Zielpuffer war im Vergleich zu anderen Merkmalen relativ gering.
Es ist zwar ärgerlich, bietet Hardware-Herstellern jedoch die Flexibilität, den Rendering-Prozess auf zahlreiche und transparente Arten zu optimieren.
Beispielsweise wartet die PowerVR-Hardware (früher sicherlich verwendet, lange nicht mehr verwendet), bis die gesamte zu rendernde Szene übermittelt wurde, und führt dann eine automatische Tiefensortierung mithilfe des Maleralgorithmus durch, ohne dass tatsächlich eine generiert werden muss Tiefenpuffer. Es würde den Bildschirm in Kacheln aufteilen und jede nacheinander rendern.
quelle
Der Pixel-Shader kann aus den Farb- und Tiefenpuffern nicht lesen, weil:
Pixel A und B können in der Hardware genau zum gleichen Zeitpunkt schattiert werden, obwohl B letztendlich über ("nach") Pixel A gerendert wird.
Wenn Sie sicherstellen würden, dass die Hardware A vor B schattiert, würden Teile der Hardware herumstehen und nichts tun, während A schattiert ist, und Teile der Hardware würden herumstehen und nichts tun, während B schattiert ist.
Im schlimmsten Fall werden alle Pixel, die Sie schattieren, übereinander gerendert, und Tausende und Abertausende von GPU-Threads - bis auf einen - bleiben im Leerlauf. Dieser eine Thread schattiert geduldig Pixel A, dann B, dann C ...
quelle