![]() |
Alphatransparent von Bildern bei Direct3D
Hallo,
ich bastel gerade etwas mit direkt3D herum und versuche ein 32bit-Bitmap unter berücksichtigung des Alphakanals im Raum darzustellen: auf folgende Art und Weise klappt die Ausgabe jedoch ohne Transparanz (sondern so wie es in Paint dargestellt wird)
Delphi-Quellcode:
auf folgende Art und Weise sehe ich nur noch schwarze Flächen ohne Bild.
f3DDevice.SetTexture(0, fTexture);
f3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); f3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); f3DDevice.SetStreamSource(0,f3DObj.Buffer3D,sizeof(TVertex)); f3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, f3DObj.Count);
Delphi-Quellcode:
Ich hätte es gern so das ich an bestimmten Stellen (bestimmt durch den Alphakanal) durch die Wand durchschauen kann und das sehe was hinter dieser Wand ist.
f3DDevice.SetTexture(0, fTexture);
f3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT); f3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); f3DDevice.SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA); f3DDevice.SetStreamSource(0,f3DObj.Buffer3D,sizeof(TVertex)); f3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, f3DObj.Count); |
Re: Alphatransparent von Bildern bei Direct3D
Für Alphatransparenz musst du die Textur mit D3DXCreateTextureFromFileEx erstellen und dabei einen Colorkey angeben, der dann transparent wird.
Danach musst du Alphatesting aktivieren, z.B. so:
Delphi-Quellcode:
D3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,1);
D3DDevice.SetRenderState(D3DRS_ALPHAREF,$1); D3DDevice.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL); |
Re: Alphatransparent von Bildern bei Direct3D
was bestimmt der ColorKey? Vom Namen her würde ich sagen das er bestimmt welche Farbe transparent wird aber das wäre ja dann nicht alphatransparenz. Ich werd mal im msdn schauen und mich nochma melden falls ich fest hänge.
|
Re: Alphatransparent von Bildern bei Direct3D
Zitat:
Delphi-Quellcode:
+
f3DDevice.SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
Delphi-Quellcode:
und ohne den Colorkey? Is aber nur geraten. Das is das was mein Gehirn mir in der Situation sagen würde :mrgreen:
D3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,1);
D3DDevice.SetRenderState(D3DRS_ALPHAREF,$1); D3DDevice.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL); Gruß Neutral General |
Re: Alphatransparent von Bildern bei Direct3D
@Michael: So gehts nicht, da ist bei mir das ganze Bild transparent so als ob es gar nicht da wäre.
mein aktueller Stand (nachdem ich das von Michael probiert hab):
Delphi-Quellcode:
D3DXCreateTextureFromFileEx(f3DDevice, 'c:\temp\test01.bmp', D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8{ D3DFMT_UNKNOWN}, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR, 0, nil, nil, fTexture);
Delphi-Quellcode:
f3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,1);
f3DDevice.SetRenderState(D3DRS_ALPHAREF,1); f3DDevice.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); f3DDevice.SetTexture(0, fTexture); //Kamera etc. setzen f3DDevice.SetStreamSource(0,f3DObj.Buffer3D,sizeof(TVertex)); f3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, f3DObj.Count); f3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,0); |
Re: Alphatransparent von Bildern bei Direct3D
also ich hab mir jetzt mal D3DRS_ALPHATESTENABLE angeschaut und es scheint so als ob man damit nur bestimmen kann ob gezeichnet wird oder nicht. Aber eine halbdurchsichtigkeit scheine ich damit nicht erreichen zu können. :cry:
mit folgendem Quelltext bekomme ich eine Alphatransparenz in Abhängigkeit von der Texturefarbe. Das muss doch auch irgendwie klappen in Abhängigkeit von dem Alphakanal.
Delphi-Quellcode:
ich hab auch schon mit den Konstanten D3DBLEND_SRCALPHA etc. herum gespielt aber ich bekomme nie das gewünschte Ergebnis (Alphatransparenz nur vom TextureAlphakanal abhängig)
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); Muss eventuell ein bestimmter CULL-Mode gesetzt sein damit es annähernd funktioniert? ich hatte auch mal folgendes probiert:
Delphi-Quellcode:
das müsste ja eigentlich bewirken das pixel mit einem Alphawert größer 0gezeichnet werden. Allerdings ist das Ergebnis das nichts gezeichnet wird. Oder verstehe ich da irgendwas falsch? (habs auch schon mit den geposteten Werten probiert was allerdings auch keinen Erfolg brachte)
D3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE, 1);
D3DDevice.SetRenderState(D3DRS_ALPHAREF, 0); D3DDevice.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATER); Oder muss ich eventuell noch irgendwo einen Puffer auf 32bit setzen (außer den des Bildes) damit während der Ausgabe die 32bit erhalten bleiben und somit beachtet werden können? ich hab eben noch folgendes probiert:
Delphi-Quellcode:
und
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
Delphi-Quellcode:
Und obwohl der Alphakanal des Bildes auf 127 steht (A8R8G8B8) ist entweder gar nichts zu sehen oder mit voller Deckkraft. Es scheint das mein Alphakanal irgendwie ignoriert wird.
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA); |
Re: Alphatransparent von Bildern bei Direct3D
Liegt es ggf. an deinem 32Bit-Bitmap ? Hat es denn einen Alphakanal und wie hast du es erstellt ?
Oder möchtest du ein "normales" Bitmap halb-transparent darstellen ? -> ![]() (..hoffe mal den richtegen Link erwischt zu haben) |
Re: Alphatransparent von Bildern bei Direct3D
Seufz, Browser abgestürzt vor dem Senden. Also nochmal die Kurzfassung.
Punkt 1: Die Blend-Operation, die du erreichen willst, lautet: dest.color = src.color * src.alpha + dest.color * (1 - src.alpha). Also:
Code:
Punkt 2: Alphatesting hat mit Alphablending nichts zu tun.
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); D3DDevice.SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); Punkt 3: Das Ergebnis des Texture Stage soll bei dir den Alphakanal beinhalten. Das sind alles Default-Werte und sie sollten daher nicht eingestellt werden müssen, aber für alle Fälle:
Code:
Das hat zur Konsequenz, dass die modulierte Farbe (!) aus Textur und Diffuse als Farbe herauskommt, und der Alphakanal der Textur als Alphakanal. Erst danach findet das Blending mit dem RenderTarget statt.
D3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); Damit sollte eigentlich alles funktionieren. Wenn nicht, probiere folgendes: Setze den Alphakanal im Diffuse deiner Vertices auf z.B. 0.5, und verwende als ALPHAARG1 D3DTA_DIFFUSE. Dann sollte eigentlich ein Per-Vertex-Alphablending funktionieren und es liegt zumindest nicht generell an einer Fehlkonfiguration. Du solltest deine Textur in dem Fall nochmal genauer untersuchen. Edit: Turbopascals Link geht zwar minimal am Thema vorbei, aber ein Tutorial auf derselben Seite weiter ist eventuell für dich auch zielführend: ![]() |
Re: Alphatransparent von Bildern bei Direct3D
Ich hab das ganze Projekt jetzt nochmal neu aufgesetzt und es funktioniert :shock:
folgende Zeilen haben mich in meinem neuen Projekt zum Ergebnis geführt
Delphi-Quellcode:
Seltsamer Weise bewirken diese im alten Projekt rein gar nichts. Da ich aber schon einen Tag lang probiert hab fehlt mir jetzt der Elan zu Suchen woran es lag.
//Alphaeinstellungen
f3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, Cardinal(True)); //alpha blending enabled ( NEW ) f3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); //source alpha ( NEW ) f3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); //Alpha aus Farbe beziehen f3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); |
Re: Alphatransparent von Bildern bei Direct3D
In meiner Firma sprechen wir in diesem Zusammenhang im Allgemeinen von Sonnenflecken oder Bitflimmern.
Aber ernsthaft, in vielen Fällen liegt es daran, dass man davon ausgeht, dass alle Werte auf Default stehen, obwohl sie irgendwo anders im Projekt verändert wurden. Deshalb schadet es im Zweifel nicht, alle Werte, die das Ergebnis beeinflussen könnten, passend zu setzen. Dann wird man vor allem bei unsauberen Treibern etwas glücklicher werden. |
Re: Alphatransparent von Bildern bei Direct3D
Ich hab mit ZeroMemory etc. gearbeitet und trotzdem das. Ich hab die Befürchtung das ich beim erstellen/initialisieren des 3DDevice oder von IDIRECT3D9 etwas "falsches" angegeben habe.
|
Re: Alphatransparent von Bildern bei Direct3D
Du missverstehst mich. Ich meine nicht die Strukturen etc., die du übergibst, sondern ich meine die Renderstates, TextureStageStates usw. Die initialisierst du ja üblicherweise nicht selbst, sondern verlässt dich auf die Default-Werte.
|
Re: Alphatransparent von Bildern bei Direct3D
ich weiß schon was du meinst, und darauf verlasse ich mich schon nicht. Ich meinte nur das der Grund, warum es im alten Projekt nicht läuft, wohl eine andere Initialisierung des Devices war oder ich hab an irgend ner Stelle die Renderstates verstellt.
Naja, noch eine Anmerkung zu dem Alphablend. Mit dem D3DRS_ALPHABLENDENABLE kann man wunderschön halbtransparente Sachen darstellen. Allerdings muss man darauf achten das dinge die hinter den halbtransparenten gebilden stehen zuerst gezeichnet werden. Malt man erst die halbtransparente Fläche und danach erst danach das was dahinter steht sieht man an der halbtransparenten Stelle das durch was zum Zeitpunkt des Zeischnens dahinter war. Wenn der Alphakanal etwas zu 100% durchsichtig macht gibt es keine Probleme weil dann der Bildpunkt ganz weg gelassen wird. In diesem Zusammenhang ist dann die Verwendung von D3DRS_ALPHATESTENABLE auch ganz gut. Wie bereits erwähnt kann es bei halbtransparenzen unschöne Effekte geben. Mit ALPHATESTENABLE kann man dann dafür sorgen das nicht nur Pixel mit Alphawert 0 ausgelassen werden. So kann man festlegen das zum Beispiel alle Pixel ausgelassen werden wo der Alphawert kleiner 10 ist (das ist so transparent das es fast keinen unterschied macht ob man das pixel ganz weglässt oder blendet) |
Re: Alphatransparent von Bildern bei Direct3D
Zitat:
In deinem funktionierenden Code-Beispiel zeigst du sehr deutlich, dass du viele Renderstates und TextureStageStates eben nicht eingestellt hast. Wenn sie auf Default standen, prima, wenn sie irgendwoanders schon umgestellt wurden, Happy Bughunting. Also, wirklich, lieber einen Renderstate mehr passend einstellen als einen weniger, aber direkt hintereinander nach Möglichkeit, und nicht zwischen lauter DrawPrimitive-Aufrufen. Oder du speicherst den State immer, wenn du Änderungen machst, und stellst ihn anschließend wieder her. Was das Sortieren angeht, üblicherweise werden tatsächlich alle Primitives, die alpha-geblendet werden müssen, von hinten nach vorne gezeichnet. Was dummerweise genau das Gegenteil von dem ist, was man sonst macht, denn normalerweise zeichnet man von vorne nach hinten, weil durch den Z-Test eine Menge Overdraw ausgeschlossen wird. Andererseits braucht man sich z.B. bei Partikelsystemen, einer typischen Anwendung für massives Alphablending, nicht darum kümmern, weil man da additiv arbeitet (DESTBLEND = ONE), und damit die Reihenfolge wieder egal ist. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz