Seite 1 von 1

Tunnel und Nebel

Verfasst: 10.02.2015, 11:39
von Carsten
Eigentlich sollte es sich um eine Standardfragestellung handeln, ich hab aber noch nichts dazu gefunden, und zwar folgendes Problem:

Hier ist etwas stärkerer Nebel eingestellt und dann führt das dazu, dass die Tunnelröhre unrealistisch wirkt, da der Nebel im Tunnel ja eigentlich dunkel sei muss. Noch blöder sieht das aus, wenn man dann im Tunnel unterwegs ist und in hellen Nebel fährt.

Bild

Also habe ich die Meshes im Tunnel als solche gekennzeichnet und mit dunklem Nebel beaufschlagt. Dann sieht es im Tunnel und kurz davor ok aus, nicht aber, wenn der Tunnel noch etwas weiter weg ist:

Bild

Das einzige, was mir bisher eingefallen ist, wäre ein "Vorhang" im Tunnelportal, der mit zunehmender Annäherung transparent wird. Aber bevor ich mich daran mache, würde mich interessieren, ob das Problem vielleicht schon einmal jemand geschickter gelöst hat.

Carsten

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 13:21
von Zudomon
Wenn du schattierten Volumennebel berechnest, statt einfachen Entfernungsnebel, sollte es klappen :D

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 13:52
von Carsten
Also eine Wand ins Portal mauern und als Volumefog rechnen. Das hört sich irgendwie auch nicht besser an als meine Idee mit dem Vorhang, meine ich. Vor allem wenn ich aus dem Tunnel raus fahre, müßte die Wand für das falsche Ergebnis sorgen, denke ich.

Carsten

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 14:05
von Zudomon
Ich meinte eher, Entfernungsnebel raus und Volumennebel rein. Wäre dann erstmal so wie jetzt mit de Entfernungsnebel... allerdings dann den Volumennebel schattieren. Dadurch sollte der im Tunnel dann dunkel sein... hab das noch nie gemacht, aber würde mich mal reizen zu sehen, wie das aussieht :D

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 14:16
von Carsten
Volumennebel kenn ich als ein 3-Objekt, das irgendwo in der Landschaft rumliegt und das man "nebelig rendert", so dass ein örtlich waberndes Nebelobjekt entsteht. Wie sollte das denn hier funktionieren?

Carsten

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 14:37
von Schrompf
Welche Engine ist denn das? Theoretisch müsste der Nebel dort ja ganz einfach hellgrau wie überall sonst sein, wenn die Standard-Nebenformel wirkt. Dass Nebel aufgrund der Lichtstreuung und Umgebungsverdeckung dort eigentlich dunkler sein müsste, ist ein anderes Thema. Was ich auf dem Bild sehe, ist echtes Schwarz. Und das könnte z.b. ein #INF oder #NAN sein, wass Du Dir irgendwo im Shader eingetreten hast.

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 14:46
von Zudomon
Das Problem ist ja, dass einfacher Entfernungsnebel hier nicht funktioniert... da dieser anscheinend eine sehr hellgraue Farbe hat. Wenn dann die Berge im Weg sind, dann kommt die Nebelfarbe da nicht so raus, aber im Tunnel kann man ja weit blicken und sieht daher die für den Tunnel viel zu helle Farbe.

Volumennebel hat eigentlich nichts mit einem Objekt zu tun...

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 14:49
von Carsten
Welche Engine ist denn das? Theoretisch müsste der Nebel dort ja ganz einfach hellgrau wie überall sonst sein, wenn die Standard-Nebenformel wirkt.
Das ist ohne externe engine selbst geschrieben. Der Nebel wird ja auch ohne weitere Maßnahmen normal grau wie auf dem ersten Bild zu sehen. Aber das darf halt im Tunnel eigentlich nicht sein, dort soll es ja dunkel sein. Trotzdem muss der Tunnel aus der Ferne betrachtet vernebeln.

Carsten

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 14:50
von Carsten
@Zudomon: Ich hab zum Volumennebel ins SDK geschaut, da gab's mal ein entsprechendes Beispiel. Welchen Ansatz meinst Du?

Carsten

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 15:14
von Zudomon
Ich denke mal, richtiger Volumennebel, wie man ihn bei Wolken hat, wäre für dich sowieso keine Option, da es doch ein wenig Performance braucht.

Wenn es was schnelles sein soll, dann würde ich wie du schon sagst, dazu raten, den Tunnel direkt am Berg schwarz zu machen... denn im Tunnel wäre der Nebel ja auch schwarz. Dadurch würdest du erreichen, dass die Schwärze aber vom normalen Nebel absorbiert wird, d.h. der Nebel vorm Tunnel hätte etwa die gleiche Dichte wie an den Berghängen daneben. Wenn man dann näher an den Tunnel kommt, solltest du die schwärze ausblenden. Ich glaube, so hattest du es ja auch schon beschrieben. Das sollte recht passabel aussehen, wenn man von draußen in den Tunnel rein schaut... wenn du im Tunnel bist ist es schwieriger... aber vielleicht würde das gleiche Prinzip da auch funktionieren. Ansonsten würde ich die Nebelfarbe einfach abdunkeln, wenn du im Tunnel bist... exakt wirst du es mit diesen Varianten eh nicht hinbekommen... also einfach mit den Notlösungen erstmal zufrieden geben.

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 16:45
von Schrompf
Im Tunnel ist es schwarz. Wie kommt es zu diesem Schwarz? Hast Du für den Tunnel einfach den Nebel abgeschaltet? Oder hast Du da numerische Probleme? Lass mich nicht rumraten bitte.

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 17:01
von Carsten
Steht eigentlich schon oben. Die Tunnelpolygone werden mit dunklem Nebel gerechnet, damit es im Tunnel korrekt aussiht, wenn man sich drin befindet.

Carsten

Re: Tunnel und Nebel

Verfasst: 10.02.2015, 17:24
von Krishty
@Schrompf: Wahrscheinlich sind die Tunnelwände schwarz (denn die sollen dunkel sein). Wenn dann schwarzer Nebel dazukommt, bleiben sie einfach schwarz.

Physikalisch korrekt:

1. Du zeichnest erstmal alles *außer* dem Tunnel (auch außer dem durch den Tunnel sichtbaren Terrain) mit normalem Nebel. Dieses "außer" setzt Occluder oder Stencil Buffering oder sowas voraus.

2. Du zeichnest das durch den Tunnel sichtbare Terrain mit Nebel, dessen Anfangs- und Endpunkt um die Distanz zum Tunnelende verschoben ist. So, als würdest du am Tunnelende stehen und rausgucken.

3. Du zeichnest den Tunnel selber mit schwarzem Nebel.

4. Du zeichnest einen unsichtbaren Deckel über den Tunneleingang, mit normalem Nebel.

Das setzt premultiplied Alpha oder Dual-Source Color Blending voraus, denn nur da gilt Fog(d_near, d_tunnel) + Fog(d_tunnel, d_far) == Fog(d1, d3).

Alles andere läuft auf endloses Gefrickel und Drumherumprogrammieren hinaus. Im Notfall: Gib jedem Tunnelpolygon exakt die selbe Menge Nebel wie direkt am Tunneleingang (selben Z-Wert schreiben oder so). Das löst nicht alle Probleme, beseitigt aber die dicksten Artefakte.

Re: Tunnel und Nebel

Verfasst: 12.02.2015, 15:33
von TGGC
Der Fehler ist doch einfach nur, das ein Teil des Tunnels hinter der Far Plane liegt. Dann ist dort einfach nur die Hintergrundfarbe vom Screenclear/Skycube etc. zu sehen. Du musst vor der ganzen Szene einfach nur ohne zwrite deinen schwarzen Vorhang rendern (bzw. genau genommen die konvexe Huelle des Tunnels, aber da der Rest ehh immer im Terrain steckt, reicht der "Vorhang" am Ein- und Ausgang).

Re: Tunnel und Nebel

Verfasst: 12.02.2015, 15:52
von Carsten
Nein, die Farplne ist viel weiter hinten.

Carsten

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 01:37
von Carsten
Ich wollt mal den Ansatz versuchen, den Vorhang im Tunnel wegzublenden und hab mich dafür mal etwas mit Shadern beschäftigt. Nun hätte ich vermutet, dass das hier gehen sollte:

Code: Alles auswählen

// +++ globale Variablen - müssen vom Programmcode noch gesetzt werden! +++ 
float4x4 matWV: WORLDVIEW; 
float4x4 matP: PROJECTION; 
float4 nebelfarbe = 0.5;
float nebelstart = 0.01;
float nebelende = 10;
float4 auge;

texture t0 < string Name = "tiger.bmp"; >; 

// +++ Variablen nur für EffectEdit +++ 
string XFile = "tiger.x"; 


// +++ VertexShader +++ 
struct VS_OUTPUT 
{ 
   float4 vDiffuse : COLOR; 
   float4 vPosition : POSITION; 
   float1 fogFactor : FOG;
}; 


struct VS_INPUT 
{ 
   float4 vDif : COLOR; 
   float3 vPos : POSITION; 
}; 


VS_OUTPUT RenderVS( VS_INPUT In ) 
{ 
   VS_OUTPUT Out; 
   float4 cameraPosition = mul(auge, matWV); 
   float4 v = mul(float4(In.vPos,1), matWV);
   Out.vPosition = mul(v, (float4x4)matP ); 
   Out.vDiffuse = In.vDif; 
   Out.fogFactor = saturate((nebelende - cameraPosition.z) / (nebelende - nebelstart));

   return Out;
}


// +++ PixelShader +++ 
struct PS_OUTPUT 
{ 
   float4 RGBA: COLOR; 
}; 


PS_OUTPUT RenderPS( VS_OUTPUT In ) 
{ 
   PS_OUTPUT Out; 

   Out.RGBA.r = In.fogFactor * nebelfarbe.r;
   Out.RGBA.g = In.fogFactor * nebelfarbe.g;
   Out.RGBA.b = In.fogFactor * nebelfarbe.b;
   Out.RGBA.a = In.fogFactor; 
   return Out;
}
 

// Technik(en) und Pass(es) 
technique tec0 
{ 
   pass p0 
   { 
      VertexShader = compile vs_2_0 RenderVS(); 
      PixelShader = compile ps_2_0 RenderPS(); 
   } 
}
Es kommt aber ein Fehler, den ich nicht verstehe, und zwar führen in PS_OUTPUT die Kommandos Out.RGBA.r = In.fogFactor * nebelfarbe.r usw. zu einem Fehler. Setzt man die Werte dort einfach z.B. auf Out.RGBA.r = nebelfarbe.r + 0.5; dann kompiliert der Shader erstmal, natürlich nicht wirklich mit dem gewünschten Ergebnis. ich versteh nicht, warum In.fogFactor hier ein Problem macht.

Carsten

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 12:21
von Schrompf
Das sagt Dir evtl. die konkrete Fehlermeldung, die Dir der Compiler ausgespuckt hat.

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 13:41
von Carsten
Die Fehler haben leider die von MS gewohnte Aussagekraft:

....\nebel.fx(88): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
ID3DXEffectCompiler: Compilation failed

Carsten

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 14:35
von Zudomon
Kann dir auf die schnelle leider nicht helfen, weil ich gleich weg muss... allerdings ist mir aufgefallen, dass du den Pixelshader ein wenig optimierter schreiben kannst. Weniger code heißt ja auch manchmal weniger Fehlerquellen:

Code: Alles auswählen

// +++ PixelShader +++ 
float4 RenderPS( VS_OUTPUT In ) 
{ 
float4 c = In.fogFactor; 
c.rgb *= nebelfarbe;
return c;
}
Nicht getestet... also ohne Gewähr :D

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 15:00
von Carsten
ja, optimiert ist das nicht im Ansatz. hab's extra "aufgedröselt", um die Fehler besser eingrenzen zu können.

Carsten

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 15:21
von Schrompf
Mit dem Effects Framework kenne ich mich leider nicht aus, ich schreib meine Shader immer direkt. Ich bin aber halbwegs sicher, dass man da irgendwo vorher auch ne konkrete Fehlermeldung abgreifen kann. Zudomons kurzer Code-Schnippsel würde z.b. eine Warnung "Implicit truncation of vector" generieren, weil der Code einen float4 nebelfarbe mit einem float3 c.rgb multipliziert. OpenGL würde Dich an der Stelle schon geiseln, weil es nicht erraten kann, welche drei Komponenten von den 4 verfügbaren es für die Multiplikation verwenden soll.

Ich will damit sagen, dass Microsoft in diesem Fall keine Schimpfe verdient - der Shader-Compiler ist normalerweise sehr ausführlich bei Fehlermeldungen und Warnungen. Die Fehler, die Dich interessieren, sind aber wahrscheinlich irgendwo in einem Zwischenschritt des Effect Frameworks versteckt. Keine Ahung, wie Du da rankommst, aber die Doku kennt sicher einen Weg.

Re: Tunnel und Nebel

Verfasst: 13.02.2015, 18:00
von Krishty
Mit SM 2.0:
ERROR 0:19: error X4502: invalid ps_2_0 input semantic 'POSITION'
Mit SM 3.0 kompiliert der hier gut.

Re: Tunnel und Nebel

Verfasst: 16.02.2015, 21:00
von Carsten
Danke für den Hinweis, bei mir auch. Wie kommt denn das?

Hab's jetzt zum Laufen bekommen mit diesem Code:

Code: Alles auswählen

// Simples Sample 

// +++ globale Variablen - müssen vom Programmcode noch gesetzt werden! +++ 
float4x4 matWV: WORLDVIEW; 
float4x4 matP: PROJECTION; 
float4 nebelfarbe = 0.5;
float nebeldichte = 0.5;
float3 auge;

// +++ VertexShader +++ 
struct VS_OUTPUT 
{ 
   float4 vPosition : POSITION; 
   float1 fogFactor: FOG;
}; 


struct VS_INPUT 
{ 
   float3 vPos : POSITION; 
   float3 vNormal: NORMAL;
   float2 vTex0: TEXCOORD0;
}; 


VS_OUTPUT RenderVS( VS_INPUT In ) 
{ 
   VS_OUTPUT Out; 
   float4 cameraPosition = mul(float4(auge,1), matWV); 
   float4 v = mul(float4(In.vPos,1), matWV);
   Out.vPosition = mul(v, matP ); 
   Out.fogFactor = 1 - (1 / exp(Out.vPosition.z * nebeldichte));
 
   return Out;
}


// +++ PixelShader +++ 
struct PS_OUTPUT 
{ 
   float4 RGBA: COLOR; 
}; 


PS_OUTPUT RenderPS( VS_OUTPUT In ) 
{ 
   PS_OUTPUT Out; 

   float4 c = 0; 
   Out.RGBA.r = c.r * (1-In.fogFactor) + nebelfarbe.r * In.fogFactor;
   Out.RGBA.g = c.g * (1-In.fogFactor) + nebelfarbe.g * In.fogFactor;
   Out.RGBA.b = c.b * (1-In.fogFactor) + nebelfarbe.b * In.fogFactor;
   Out.RGBA.a = In.fogFactor;
   return Out;
}
 

// Technik(en) und Pass(es) 
technique nebelwand 
{ 
   pass p0 
   { 
      VertexShader = compile vs_3_0 RenderVS(); 
      PixelShader = compile ps_3_0 RenderPS(); 
   } 
}