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

Urk

Frischling

  • »Urk« ist der Autor dieses Themas
  • Private Nachricht senden

1

29.06.2011, 00:44

HLSL PS3_0, dynamische Schleifendurchläufe

Guten Abend,

ich bin noch ziemlich neu im Bereich DirectX und versuche mich gerade an einer Implementation von Echtzeit HDR unter Direct3D-9. Mein Problem ist ein Pixelshader (3_0), genauer ein .fx file, in dem ich versuche die Schleifendurchlaufzahl durch eine Variable zu definieren, um im HDR Shader dann die Gauss-Kernel-Size von außen bestimmen zu können.

Hier mal Auszugsweise der Shader "hdr.fx": (alles nicht relevante ist entfernt, um es kurz zu halten)

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//----------------------------------------------------------------------------- 
// Globals. 
//----------------------------------------------------------------------------- 
//#define kernelSize 1 
int kernelSize; 

//----------------------------------------------------------------------------- 
// Vertex Shaders. 
//----------------------------------------------------------------------------- 

struct VS_INPUT { ... }; 
struct VS_OUTPUT { ... }; 

VS_OUTPUT VS_HDR(VS_INPUT IN) 
{ 
 //Vertexshaderzeugs 
} 

//----------------------------------------------------------------------------- 
// Pixel Shaders. 
//----------------------------------------------------------------------------- 
float4 PS_HDR(VS_OUTPUT IN) : COLOR 
{ 
 float4 color = float4(0.0f, 0.0f, 0.0f, 1.0f); 

 for (int j=-kernelSize; j<=kernelSize; ++j) 
 { 
  samp.y = IN.texCoord.y + j * pixelToTexely; 
  for (int i=-kernelSize; i<=kernelSize; ++i) 
  { 
   //Zeug berechnen
  } 
 } 
 return color; 
} 

//----------------------------------------------------------------------------- 
// Techniques. 
//----------------------------------------------------------------------------- 
technique HDR 
{ 
 pass 
 { 
  VertexShader = compile vs_3_0 VS_HDR(); 
  PixelShader = compile ps_3_0 PS_HDR(); 
 } 
} 


Das Problem ist nun folgendes:
- mit "int kernelSize;" stürzt das Ding einfach ab, beim compilieren
- mit "#define kernelSize 1" läuft es einwandfrei

Ich vermute mir fehlt hier einfach Basiswissen (dynamische Schleifenlängen über eine Variable funktionieren an sich ab SM_3_0 soweit ich informiert bin, zumindest in meinem Beleuchtungsshader gehts).

Vielleicht kann mir ja jemand hier einen Tip geben :)

Besten Dank

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

29.06.2011, 01:13

Rein prinzipiell: Einen Gaussfilter willst du nicht als verschachtelte Schleife implementieren. Ein Gaussfilter ist linear separierbar, d.h. statt einen NxN 2D Gaussfilter zu rechnen kannst du auch erst einen 1D Gaussfilter mit N Samples in X-Richtung und danach auf das Ergebnis einen 1D Gaussfilter mit N Sample in Y-Richtung anwenden. Beides führt zum exakt selben Ergebnis mit dem Unterschied dass du bei der ersten Methode N² Texture Samples und bei der zweiten nur 2N brauchst. Auf gut deutsch: Die erste Variante ist grottenlangsam und die zweite pfeilschnell ;)

Wenn du die Größe des Filterkernels dynamisch machen willst, woher kommen dann die Gewichte? Warum genau willst du die Größe dynamisch regelbar machen, ich hoffe dir ist klar dass du damit unter Umständen mit massiven Performanceeinbußen rechnen musst.

Urk

Frischling

  • »Urk« ist der Autor dieses Themas
  • Private Nachricht senden

3

29.06.2011, 01:26

Danke für deine Antwort. Die Performance Frage ist mir hier völlig klar, für einen normalen Gauss Blur benutze ich auch die separierte 2N anstatt der Rechenaufwendigen N² Variante.

Es geht mir hier in erster Linie darum, einen Testshader zu bauen, in dem ich unterschiedliche Algorithmen zur Erstellung der Gewichtungsmaps für die einzelnen Bilder der Belichtungsreihe, sehr effektiv ausprobieren kann.
Die Optimierung und Zerlegung in verschiedene aufeinanderfolgende Shader/Passes erfolgt dann sobald ein HDR Operator als "ok" eingestuft wird.

Zur Zeit habe ich einen Varianzoperator implementiert, der die Varianz der Helligkeit um einen Pixel mit einem Radius von "kernelSize" berechnet. Genau diese Ausdehnung des lokalen Operators würde ich nun gerne steuern, um die Auswirkung bei größerem Einzugsbereich untersuchen zu können.

Zum Thema Gewichte, die berechne ich zur Zeit auch innerhalb des Shaders mit weight= 1 / (Pi*kernelSize²) + exp (- (deltax²+deltay²) / kernelSize²)
Performance ist also erstmal nicht das vordringliche Problem (die landen Später dann natürlich in Lookup tables ;)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

29.06.2011, 01:34

Oh, du willst also die Berechnung von HDR Bildern aus Belichtungsreihen mit Shadern beschleunigen? Ich dachte es ging nur um den üblichen Bloom Effekt ;)

Was genau für einen Compilerfehler bekommst du denn?

Urk

Frischling

  • »Urk« ist der Autor dieses Themas
  • Private Nachricht senden

5

29.06.2011, 01:44

Ja, genau darum geht es. Eine Belichtungsreihe aus einer Szene erzeugen (3 Bilder) und dann richtiges HDR zu generieren und nicht "nur" Blooming.

Das Problem mit dem abgreifen des Fehler ist folgender (auch hier mangelt es mir offensichtlich noch an Erfahrung mit dem D3D Zeugs (bin dort erst seit gut 6 Wochen unterwegs).

Der C-Code zum compilieren des .fx Files sieht so aus:

C-/C++-Quelltext

1
2
3
4
5
6
HRESULT hr = D3DXCreateEffectFromFile(g_pd3dDevice, fname, 0, 0, dwShaderFlags, 0, &pEffect, &pCompilationErrors);

if (FAILED(hr)) //Hier kommt das Programm bereits nicht mehr an, sobald ich "kernelSize" als int Variable setze
{
 //Fehler behandeln
}


Ich kann "hr" also überhaupt nicht mehr auslesen, weil das Programm schlicht abstürzt. (Kommt nur die Meldung bla.exe funktioniert nicht mehr)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

29.06.2011, 01:46

Na schau doch mal was dein pCompilationErrors so enthält ;)

EDIT: Oh ok, es stürzt also ab? Was sagt denn der Debugger? Kanns sein dass dein g_pd3dDevice schlicht und einfach 0 ist?

Urk

Frischling

  • »Urk« ist der Autor dieses Themas
  • Private Nachricht senden

7

29.06.2011, 01:56

Das spuckt er aus:


(Link)


PS: Das Device ist in Ordnung, die 33 .fx Files davor werden einwandfrei kompiliert

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

29.06.2011, 02:08

Hm, versuch vielleicht mal deine kernelSize auf einen vernünftigen Wert zu initialisieren.

Urk

Frischling

  • »Urk« ist der Autor dieses Themas
  • Private Nachricht senden

9

29.06.2011, 02:12

Eine Änderung auf z.B.

C-/C++-Quelltext

1
int kernelSize=2;

erzeugt den gleichen Fehler.

Ich komme da auch nicht wirklich hinter, in einem anderen Shader für die Beleuchtung benutze ich eine globale Variable

C-/C++-Quelltext

1
int numLights;

die von außen mit einem Wert von 1 bis 24 bestückt wird. Dort klappt das wunderbar, nur in diesem Shader nicht.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

29.06.2011, 02:15

Ja das ist komisch. Evtl. liegts an irgendwelchen Funktionen die du in der Schleife benutzt. Modifizierst du den Schleifenzähler irgendwie?

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (29.06.2011, 02:22)


Werbeanzeige