PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit DX/SM3.0


Corrail
2006-11-03, 12:36:35
Hallo!

Ich versuche gerade folgendes Codestück von GLSL nach DX/HLSL zu portieren:


vec3 tmp_texcoord = v2f_Texcoord;
vec3 offset = view*my_delta;
float height = texture2D(a2v_Heightmap, tmp_texcoord.xy).w;

bool found = false;

if (height < tmp_texcoord.z)
{
for (int i = 0; i <= my_sample_count; i++)
{
tmp_texcoord += offset;
height = texture2D(a2v_Heightmap, tmp_texcoord.xy).w;
if (height >= tmp_texcoord.z)
{
found = true;
break;
}
}
}

das würde bei mir so ausschauen:


float3 tmp_texcoord = IN.TexCoord;
float3 offset = view*my_delta;
float height = tex2D(DMapSampler, tmp_texcoord.xy).w;

bool found = false;
if (height < tmp_texcoord.z)
{
for (int i = 0; i <= my_sample_count; i++)
{
tmp_texcoord += offset;
height = tex2D(DMapSampler, tmp_texcoord.xy).w;
if (height >= tmp_texcoord.z)
{
found = true;
break;
}
}
}

Wenn ich das jetzt mit ps_3_0 kompiliere, schreit er, dass er "break" nicht mag. Kennt HLSL im ps_3_0 kein break? Gut, dann hab ich folgendes probiert:


float3 tmp_texcoord = IN.TexCoord;
float3 offset = view*my_delta;
float height = tex2D(DMapSampler, tmp_texcoord.xy).w;

bool found = false;
if (height < tmp_texcoord.z)
{
for (int i = 0; i <= my_sample_count; i++)
{
if (!found)
{
tmp_texcoord += offset;
height = tex2D(DMapSampler, tmp_texcoord.xy).w;
if (height >= tmp_texcoord.z)
{
found = true;
//break;
}
}
}
}

Alles andere als schön und es funktioniert auch nicht. Bei der for Schleife schreit er, dass es nicht gewährleistet ist, dass sie mit 1024 iterationen endet. Irgendwie kommt mir das sehr suspekt vor. Was kann ich da tun?

Xmas
2006-11-03, 12:46:42
Ja, break geht nicht.

Eine maximale Zahl an Schleifendurchläufen kannst du beispielsweise mit dem Modulo-Operator erzwingen:
for (int i = 0; i < my_sample_count % max_sample_count; i++)
Das <= kommt mir irgendwie suspekt vor.

Corrail
2006-11-03, 12:52:50
Oki, danke. Werde das mal probieren!
[EDIT] Danke, hat hingehaut!

Das <= kommt mir irgendwie suspekt vor.

Das passt schon. Die Idee ist, dass ich innerhalb eines Volumens sampel, wobei ich die Länge weiß, die das Volumen entlang meines View Vektors hat. Und da ich beide Randpunkte (sowohl den Eintrittspunkt als auch den Austrittspunkt) mitsampel muss, muss ich bis my_sample_count und nicht bis my_sample_count-1 gehen,

Corrail
2006-11-03, 18:11:37
Ok, das mit dem % max_sample_count funktioniert grundsätzlich. Nur braucht er dann beim Kompilieren ewig. Anscheinend entfaltet er die Schleife dann manuell. Das scheint mir aber nicht sehr praktisch...

Xmas
2006-11-03, 20:37:22
Ok, das mit dem % max_sample_count funktioniert grundsätzlich. Nur braucht er dann beim Kompilieren ewig. Anscheinend entfaltet er die Schleife dann manuell. Das scheint mir aber nicht sehr praktisch...
Es sollte einen Compiler-Switch geben der steuert ob Loop-Unrolling bevorzugt wird. Aber das scheint mir hier nicht das Problem.
Vielleicht hilft es, statt der Modulo-Anweisung vor der Schleife my_sample_count zu begrenzen:
my_sample_count = min(my_sample_count, max_sample_count);

Corrail
2006-11-04, 12:28:39
my_sample_count = min(my_sample_count, max_sample_count);

Das hab ich schon probiert, aber das checkt der DX Compiler nicht.

Corrail
2006-11-04, 16:06:24
Also, ich hab das Problem gefunden. Nach längerem herumsuchen, hab ich gelesen (http://ati.amd.com/developer/SIGGRAPH05/ShadingCourse_HLSL.pdf Seite 18), dass HLSL Loops unrollen will, sobald in der Schleife irgendwas ist, was entweder eine Gradient (tex2D, ...), ein local array indexing oder sonst noch was ist. Da ich wegen meinem Texture Lookup ein tex2D brauche, macht nun der HLSL Kompiler Loop-Unrolling. Dadurch ergibt es auch das Problem mit 1024 iterations.
Lösung des Problems: Entweder tex2Dlod oder tex2Dgrad (mit vorhergehenden ddx und ddy)