Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

11

13.03.2010, 23:15

Ahh.. OK, so langsam bestätigt sich das, was ich vermutet hatte :D

Es gibt also "einfach" solche Funktionen so ähnlich wie SetRenderstate etc., mit denen man die Variablen übergibt, oder?

Danke ;)

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

12

14.03.2010, 11:46

Exakt.

13

15.03.2010, 20:56

Das mit dem Übergeben von Variablen hat mich echt einiges an Nerven gekostet.
Ich habe erst nach monate, wo ich schon lange mit dem FX composer rumgespielt habe, nach lesen des ca. 25 Shader turorials rausgekriegt wie man Variablen übergibt. Ich find es ist echt ne unverschämtheit dass das überall weggelassen wird.

Naja wenn man den dreh einmal raushat kann man sich eine Funktion schreiben die in etwa so aussieht (Tribase):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void set_effect_variables(tbEffect* effect)
{
    D3DXMATRIX mView;
    D3DXMATRIX mProj;
    D3DXMATRIX mWorld;
    tbDirect3D::Instance().GetDevice()->GetTransform(D3DTS_VIEW,&mView);
    tbDirect3D::Instance().GetDevice()->GetTransform(D3DTS_PROJECTION,&mProj);
    tbDirect3D::Instance().GetDevice()->GetTransform(D3DTS_WORLD,&mWorld);

    D3DLIGHT9 light;
    tbDirect3D::Instance().GetDevice()->GetLight(0,&light);

    


    effect->GetEffect()->SetValue("World",mWorld,sizeof(D3DXMATRIX));
    effect->GetEffect()->SetValue("View",mView,sizeof(D3DXMATRIX));
    effect->GetEffect()->SetValue("Projection",mProj,sizeof(D3DXMATRIX));

    effect->GetEffect()->SetVector("Ambient",(D3DXVECTOR4*)&light.Ambient);
    effect->GetEffect()->SetVector("Diffuse",(D3DXVECTOR4*)&light.Diffuse);


}


Mit so einer Funktion deckt man alle wichtigen Varablen ab, die man für fast jeden Shader brauch.
Im Shader muss dann nur noch das stehen:

Quellcode

1
2
3
4
5
6
float4x4 World : WORLD;// das : WORLD ist nur wegen dem FX composer
float4x4 View : VIEW;
float4x4 Projection : PROJECTION;

float4 Diffuse;
float4 Ambient;


Ich hab dann einfach nur meine Shadercodes aus dem FX Composer per drag&drop in den Converter der Tribase reingetan, Texturen gesetzt( standard beim import) und Fertig!

Ich hoffe das Hilft jemandem

mfG Nick
Aller Anfang ist schwer

14

30.04.2010, 11:54

hi,

vielleicht nochmal eine Noob-Frage: Wie schalte ich denn einen Shader "aus"?

Ich arbeite mit einem Framework, das mit Knoten arbeitet. Einen Knoten kann man dabei in einem Ausgabefenster zeichnen lassen, wobei die Klasse zum zeichnen einen Callback aufruft. Der Knoten um den es geht, hat eine Eingabetextur, die mit einem Shader bearbeitet werden und dann gezeichnet werden soll. D.h. in dem Draw-Callback muss ich ja zuerst mal meine neue Textur rendern, also den Viewport umstellen, ein Quad zeichnen und dieses per Pixel-Shader einfärben, soweit kein Problem.
Wenn ich danach dann diese Textur binde und diese über ein Objekt im Viewport legen will, muss ich das ganze jetzt aber ohne Shader machen, weil der sonst die Textur wieder einfärbt. Muss ich dazu das ganze Programm deleten, nur den Shader detachen, das aktuelle Programm einfach auf 0 setzen, ein Shader-Programm einführen, das nur die Std-Operationen macht oder oder oder?

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

15

30.04.2010, 12:12

In OpenGL < 3.0 einfach ausschalten oder die saubere alternative für GL und Direct3D: Standard-Shader binden, sprich Vertexshader, der einfach die Standard-Matrizen-Multiplikationen mit dem Eingangswert durchführt und im Fragment-Shader dann einfach Ausgabe = Eingangswert.

LG
Alyx

16

03.05.2010, 11:56

Das ist auch das erste was mir eingefallen ist. Kam mir nur etwas merkwürdig vor, dass man da extra nochmal den HelloWorld-Shader bauen muss. Dachte, da kann man einfach irgendwas auf 0 setzen oder so ähnlich.

Nächste Frage :)

Wie gesagt funktioniert das ganze ja per Draw-Callback. D.h., mal in Pseudocode ausgedrückt, möchte ich ja pro Aufruf folgendes machen:

- Überprüfen, ob sich der Eingabeparameter "angle" geändert hat (denn dann müsste ich eine neue Textur zeichnen)
- falls ja: zeichne neue Textur
- zeichne die zuletzt gerenderte Textur

Problematisch wirds in diesem Schritt mit den Viewports. Wenn ich eine neue Textur zeichnen muss, muss ich mich auch um den Viewport kümmern, d.h. ich initialisiere da erstmal meine FBOs und rufe irgendwann diese Funktion auf:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Setup scene for parallel projection
void ParallaxTest::SetupParallelProjection()
{
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(TEXTURE_SIZE / 2, TEXTURE_SIZE / 2, TEXTURE_SIZE / 2, TEXTURE_SIZE / 2, 0.1f, 1000.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -1.0f);
}


Jetzt müsste ich nur für folgenden Schritt "- zeichne die zuletzt gerenderte Textur" wieder den alten Viewport haben. Der wurde vom Framework gesetzt, ich habe also keine Ahnung, was da alles passiert ist. Gibts jetzt eine Möglichkeit, bevor ich die Parallel-Projektion einstelle, das alles irgendwie auf einem Stack zu sichern? Ich meine, ich habe in der Richtung mal was gelesen, finde das aber nicht mehr.

Die andere Möglichkeit wäre einfach folgendes zu machen:

- Überprüfen, ob sich der Eingabeparameter "angle" geändert hat (denn dann müsste ich eine neue Textur zeichnen)
- falls ja: zeichne neue Textur
- falls nein: zeichne die zuletzt gerenderte Textur

Damit würde ich quasi einen Aufruf des Callback nur zum rendern der neuen Textur verwenden und nichts zeichnen. Beim nächsten Aufruf wäre der Viewport dann wieder richtig gesetzt und ich könnte ganz normal meine Szene mit der neuen Textur zeichnen.
Sieht allerdings etwas unsauber aus oder kann man das machen? Immerhin zeichne ich die Szene dann mindestens einen Frame lang nach einer Änderung nicht...

17

11.05.2010, 10:01

ok, das bitte vergessen, hat sich erledigt. Andere Sache, die auch wirklich basic ist und wahrscheinlich Millionen beschäftigt ;)

Wie debugge ich shader?

Ich habe jetzt einen eigenen Shader gebaut, der Parallax Occlusion Mapping machen soll. Somit ist er also schon relativ komplex (jedenfalls für mich, weiß ja nicht, was ihr da so für Romane codet). Ausgabe ist natürlich ein schwarzes Quad, nur wie finde ich jetzt den Fehler?
Problem ist nämlich, dass mein GLSL-Verständnis alles andere als hieb- und stichfest ist, da kann sich also easy ein Fehler eingeschlichen haben, den ich mangels Kenntnis einfach nicht finden werde.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

18

11.05.2010, 21:01

Ich würde zuerst mal schauen, ob du überhaupt alles richtig eingestellt hast. Also mal einen ganz einfachen Shader bauen, der nur alles z.B einfarbig macht. Dann weisst du, dass es am eigentlichen Shadercode und nicht an der Pipeline liegt.

Dann kannst du ja relativ gut Schritt für Schritt den Shader zu dem erweitern, was du haben willst. Wenn irgendwann unerwartete Ergebnisse auftauchen, dann gehst du einfach einen Schritt zurück und weisst die Stelle recht genau.

Dann gibt es ein paar Tools, die dir das Debuggen vereinfachen. Für HLSL gibt es z.B Pix:
http://www.gamedev.net/community/forums/…topic_id=441943
Ebenfalls könntest du die Shader mit einem Tool, wie z.B Rendermonkey erstellen, womit das ganze auch einfacher sein sollte:
http://developer.amd.com/gpu/rendermonkey/Pages/default.aspx

Gibt noch ein bekanntest Tool, aber mir fällt der Name gerade nicht ein.

Tobiking

1x Rätselkönig

  • Private Nachricht senden

19

11.05.2010, 21:08

Wenn man nach "Shader Debugger" sucht findet man nen paar Sachen. Ich habs zwar noch nicht ausprobiert, aber http://www.vis.uni-stuttgart.de/glsldevil/ sieht z.B. ganz gut aus.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

20

11.05.2010, 23:39

Was Shader debuggen angeht wäre wohl als erstes PIX zu nennen, das kommt mit dem DX SDK.
Und dann gibts natürlich NVIDIA Nsight http://developer.nvidia.com/object/nsight.html
Bin noch nicht dazugekommen letzteres auszuprobieren, das dürfte aber so ziemlich das mit Abstand beste Tool sein was es aktuell so gibt...

Werbeanzeige