PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : effiziente approximation für richtungsvektor zu long/lat konvertierung


Chris Lux
2005-03-07, 10:59:06
hi,
ich bin schon ne weile am suchen und überlegen, wie man die convertierung eines richtungsvektors für den lookup in eine long/lat environment map in einem shader effizienter gestalten kann. folgendes tue ich jetzt gerade:

mathematisch korrektes glslang beispiel:
vec2 _polar;

_polar.x = 0.5*(1.0 + _invpi*atan(_refl.x, -_refl.z)); // mappt [-pi,pi] auf [0,1]
_polar.y = acos(_refl.y)*_invpi; // mappt [0,pi] auf [0,1]

vec4 _env = texture2D(_u_environment_spec, _polar);


ich hatte glaube mal eine demo, die diese berechnung approximiert hat, leider kann ich sie nicht mehr finden... kennt vielleicht jemand eine effizientere implementierung?

edit: ich sollte noch dazu sagen, dass der richtungsvektor normal ist.

muhkuh_rs
2005-03-08, 12:44:06
Vielleicht wäre eine Cube Map, die zu einem Richtungsvektor ein u,v speichert eine Idee? Wenn der Richtungsvektor normiert ist, reichen auch eine 2D (x,z->u) und eine 1D Textur (y->v), denke ich.

Trap
2005-03-08, 15:18:24
Wie gut soll die Approximation sein? Immer (0,0) als Ergebnis ist nicht gut genug glaub ich ;)

Chris Lux
2005-03-08, 17:05:49
Vielleicht wäre eine Cube Map, die zu einem Richtungsvektor ein u,v speichert eine Idee? Wenn der Richtungsvektor normiert ist, reichen auch eine 2D (x,z->u) und eine 1D Textur (y->v), denke ich.
das sind gute ideen, über die ich auch schon nachgedacht habe... wiess jemand wie lange die atan und acos funktionen bei nvidia dauern, dh ob es sich lohnt gegen texturelookups zu tauschen...

ScottManDeath
2005-03-08, 18:32:04
acos wird zu ca 11 Anweisungen(mul, mad, rcp, rsq) erweitert.

atan2 wird zu ca 27 Anweisungen(mul, mad, rcp, rsq) erweitert.

Also alles nicht ganz billig.

Chris Lux
2005-03-08, 20:27:11
acos wird zu ca 11 Anweisungen(mul, mad, rcp, rsq) erweitert.

atan2 wird zu ca 27 Anweisungen(mul, mad, rcp, rsq) erweitert.

Also alles nicht ganz billig.

ui, da muss ich morgen mal was machen... das compilat hab ich mir auch schon ausgeben lassen, war noch nicht dazu gekommen es zu analysieren.

zeckensack
2005-03-08, 20:57:23
Kannst du nicht direkt mit Cubemaps arbyten, indem du die Polar-Maps vorher umwandelst?

ScottManDeath
2005-03-08, 21:07:06
Ich hatte ein bischen mit Matlab gespielt um die funktionen zu approxieren. Allerdings kann das Matlab Curve Fitting Tool nur Funktionen von einer abhängigen Variablen, deswegen hat das mit dem Atan nicht geklappt.

Den Acos hat er als kubisches Polynom halbwegs hinbekommen, allerdings war die Shader Implementation nicht so pralle. Kostet aber auch nur ca 7 Ops


//als Kubisches Polynom
float my_acos_3(float x)

{

float4 c = float4( -0.1231 , 0.002854, -0.2984, 0.4984);



float x_2 = x*x;

float x_3 = x_2*x;

float4 x_vec = float4(x_3,x_2,x,1.0f);

returndot(x_vec,c);

}
// als x^5 Polynom
float my_acos_5(float x)

{

float4 c1 = float4( -0.1481 , 0.004843, 0.03328, -0.00553);

float2 c2 = float2(-0.3316, 0.5013);



float x_2 = x*x;

float x_3 = x_2*x;

float x_4 = x_2 * x_2;

float x_5 = x_3 * x_2;



float4 x_vec1 = float4(x_5,x_4,x_3,x_2);

float2 x_vec2 = float2(x,1.0f);



returndot(x_vec1,c1) + dot(x_vec2,c2);

}

/*

Linear model Poly5:

f(x) = p1*x^5 + p2*x^4 + p3*x^3 + p4*x^2 + p5*x + p6

Coefficients (with 95% confidence bounds):

p1 = -0.1481 (-0.1493, -0.1469)

p2 = 0.004843 (0.004222, 0.005463)

p3 = 0.03328 (0.03195, 0.0346)

p4 = -0.00553 (-0.006068, -0.004991)

p5 = -0.3316 (-0.3319, -0.3313)

p6 = 0.5013 (0.5012, 0.5014)

Goodness of fit:

SSE: 0.09534

R-square: 0.9999

Adjusted R-square: 0.9999

RMSE: 0.002471

*/

Chris Lux
2005-03-08, 22:20:09
Kannst du nicht direkt mit Cubemaps arbyten, indem du die Polar-Maps vorher umwandelst?
das problem ist, dass cube maps an den rändern der einzelnen faces nicht korrekt filtert, dh es wird für das filtern nur das durch den lookup vektor bestimmte face verwendet und nicht in die angrenzenden faces geschaut. dies wird offensichtlich wenn man mit dem lod bias rumspielt, um ein paar sachen in den mipmaps zu verstecken...

Chris Lux
2005-03-08, 22:21:47
Ich hatte ein bischen mit Matlab gespielt um die funktionen zu approxieren. Allerdings kann das Matlab Curve Fitting Tool nur Funktionen von einer abhängigen Variablen, deswegen hat das mit dem Atan nicht geklappt.

Den Acos hat er als kubisches Polynom halbwegs hinbekommen, allerdings war die Shader Implementation nicht so pralle. Kostet aber auch nur ca 7 Ops

cool, danke ich tests das alles mal...

muhkuh_rs
2005-03-09, 01:06:38
Boah! Da kann ich mir nicht vorstellen, dass die rechnerische Annäherung mit dem cube map lookup mithalten kann. Dazu kommt noch, dass dann der Reflexionsvektor auch nicht normiert sein muss, so dass man eventuell vorher schon was spart. Außerdem kann das dann sogar SM 1.1 noch berechnen, obwohl man dann so weit ich das jetzt überblicke R nur per vertex berechnen kann.