Khaj

Založen: 16. 01. 2008 Příspěvky: 49
|
Zaslal: 23. září 2013, 17:19:09 Předmět: Kubická rekonstrukce gradientu |
|
|
Ahoj!
Pro rekonstrukci normál (ve volume renderingu nad 3D texturama) používám kubický B Spline z http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter20.html (optimalizuje kubické filtrování v shaderu pomocí hw-lineárních čtení z textury a ukazuje jak rekonstruovat gradienty).
Narazil jsem na dva problémy:
1) V článku říkají, že výsledný filtr pro zisk derivace v jednom směru vezmu jako tensorový součin derivovaného filtru v jednom směru s nederivovanými filtry v ostatních směrech.
Otázka je, v jakém pořadí mám provádět interpolování dle os a jestli to není jedno. (Když chci derivaci dle osy X, jestli nejdřív mám filtrovat Y,Z a nakonec derivovaně dle X, nebo jestli můžu v jiném pořadí.)
2) Výslednej gradient používám k osvětlování, vypadá to celkem OK nicméně velikost vektoru gradientu je neskutečně malá! (Což mi kazí implementaci ostatních metod, které např. dle normy gradientu určují jak moc šumu je v daném bodě, nebo násobí průhlednost touto normou ke zlepšení rozeznání objektů).
Nemám náhodou ve svém kódu chybu?
Prosím jukněte na to, přikládám HLSL kód pro 3D černobílé textury, který má vracet xyzw jako (gradX,gradY,gradZ,HodnotaVBodě).
Nikde na internetu jsem nenašel jinou implementaci (pro víc než 1D rekonstrukce gradientu).
kód: |
float4 tex3DBicubic(sampler3D Texture,float3 coord_source)
{ //xyz,w - smer normaly A barva v danym bode
//optimalizovano pro cernobily
// calc filter texture coordinates where [0,1] is a single texel
// (can be done in vertex program instead)
float3 coord_hg = coord_source * SrcTexDim.xyz - float3(0.5f, 0.5f, 0.5f);
// fetch offsets and weights from filter texture
float3 hg_x = tex1Dlod( TexHG, float4(coord_hg.x,0,0,1) ).xyz;
float3 hg_y = tex1Dlod( TexHG, float4(coord_hg.y,0,0,1) ).xyz;
float3 hg_z = tex1Dlod( TexHG, float4(coord_hg.z,0,0,1) ).xyz;
// determine linear sampling coordinates
float4 coord_source100,coord_source000,coord_source110,coord_source010,coord_source111,coord_source011,coord_source101,coord_source001;
coord_source100.w=1.0f;coord_source000.w=1.0f;coord_source110.w=1.0f;coord_source010.w=1.0f;coord_source111.w=1.0f;coord_source011.w=1.0f;coord_source101.w=1.0f;coord_source001.w=1.0f;
coord_source100.xyz = coord_source + hg_x.x * XTexelVect.xyz;
coord_source000.xyz = coord_source - hg_x.y * XTexelVect.xyz;
coord_source110.xyz = coord_source100.xyz + hg_y.x * YTexelVect.xyz;
coord_source010.xyz = coord_source000.xyz + hg_y.x * YTexelVect.xyz;
coord_source111.xyz = coord_source110.xyz + hg_z.x * ZTexelVect.xyz;
coord_source011.xyz = coord_source010.xyz + hg_z.x * ZTexelVect.xyz;
coord_source100.xyz = coord_source100.xyz - hg_y.y * YTexelVect.xyz;
coord_source000.xyz = coord_source000.xyz - hg_y.y * YTexelVect.xyz;
coord_source101.xyz = coord_source100.xyz + hg_z.x * ZTexelVect.xyz;
coord_source001.xyz = coord_source000.xyz + hg_z.x * ZTexelVect.xyz;
coord_source100.xyz = coord_source100.xyz - hg_z.y * ZTexelVect.xyz;
coord_source000.xyz = coord_source000.xyz - hg_z.y * ZTexelVect.xyz;
coord_source110.xyz = coord_source110.xyz - hg_z.y * ZTexelVect.xyz;
coord_source010.xyz = coord_source010.xyz - hg_z.y * ZTexelVect.xyz;
// fetch 2*four linearly interpolated inputs. saturate?
float4 tex_source0;
float4 tex_source1;
tex_source0.r = tex3Dlod( Texture, coord_source000).r;
tex_source0.g = tex3Dlod( Texture, coord_source100).r;
tex_source0.b = tex3Dlod( Texture, coord_source001).r;
tex_source0.a = tex3Dlod( Texture, coord_source101).r;
tex_source1.r = tex3Dlod( Texture, coord_source010).r;
tex_source1.g = tex3Dlod( Texture, coord_source110).r;
tex_source1.b = tex3Dlod( Texture, coord_source011).r;
tex_source1.a = tex3Dlod( Texture, coord_source111).r;
//along x dir for Y grad
float4 grad_source0=float4(tex_source0.r,tex_source1.r,tex_source0.b,tex_source1.b);
float4 grad_source1=float4(tex_source0.g,tex_source1.g,tex_source0.a,tex_source1.a);
grad_source1=lerp( grad_source0, grad_source1, hg_x.z );
// weight along y direction
tex_source0 = lerp( tex_source0,tex_source1,hg_y.z);
//weight along Z for X grad
//along z dir
tex_source1.xy=grad_source1.zw;
tex_source1.zw=tex_source0.zw;
//grad_source1.xy=grad_source1.xy;
grad_source1.zw=tex_source0.xy;
grad_source0=lerp(grad_source1,tex_source1,hg_z.z);//lerp Y&X
tex_source1.y=(grad_source0.x-grad_source0.y) * hg_y.z;//ted texsource slouzi jako return
tex_source1.x = ( grad_source0.z - grad_source0.w ) * hg_x.z;
// weight along x direction
tex_source0.xy = lerp( tex_source0.rb, tex_source0.ga, hg_x.z );
//gradient along z dir
tex_source1.z = ( tex_source0.x - tex_source0.y ) * hg_z.z;
//weight along z direction
tex_source1.w = lerp( tex_source0.x, tex_source0.y, hg_z.z );
return tex_source1;
} |
Díky moc! Kdybyste tušili o lepším způsobu získání gradientu v shaderu, nebo někdy něco podobného řešili, prosím řekněte.[/code] |
|