directx - Multi-Texturing - Interpolation between two layers of an 3D texture -


i'm trying achieve terrain texturing using 3d texture consists of several layers of material , make smooth blending between materials.

maybe illustration explain better:
pretty picture

just imagine each color cool terrain texture, grass, stone, etc.
want them blended, current approach textures between requested besides textures want appear (it seems logical because, i've read, 3d texture treated three-dimensional array instead of texture pillars).
current (and foolish, obviously) approach simple pie ('current' result rendered using point interpolation, desired result hand-painted):

vertexes:
vertex 1: position = vector3.zero, uvw = vector3.zero
vertex 2: position = vector3(0, 1, 0), uvw = vector3(0, 1, 0.75f)
vertex 3: position = vector3(0, 0, 1), uvw = vector3(1, 0, 1)
can see, first vertex of triangle uses first material (the red one), second vertex uses third material (the blue one) , third vertex uses last fourth material (the yellow one).

this how it's done in pixel shader (uvw directly passed without changes):
float3 texcolor = tex3d(colortexturesampler, input.uvw);
return float4(texcolor, 1);
reason choice terrain structure. terrain being generated voxels (each voxel holds material id) using marching cubes. each vertex 'welded' because meshes pretty big , don't want make every triangle individual (but can still if there no way solve question using connected vertices).
came idea storing material ids of other 2 vertices of triangle , blend factors (i have float2 uv pair, float3 material ids , float3 blend factor of each material id) in each vertex, don't see way accomplish without breaking mesh individual triangles.
any help appreciated. i'm targeting slimdx c# , direct3d 9 api. reading.
p.s.: i'm sorry if made mistakes in text, english not native language.

probably, colortexturesampler using point filtering (d3dtexf_point). use either d3dtexf_linear or d3dtexf_anisotropic acheve desired interpolation effect. i'm not familiar slimdx 9, you've got idea.

btw, nice illustration =)

update 1 result in comment below seems appropriate code. looks desired effect must change overall approach. not complete solution you, there how make in plain 3d terrains:

  • every vertex has 1 pair (u, v) of texure coodrinates
  • you have n textures sample (t1, t2, t3, ..., tn) represents different layers of terrain: sand, grass, rock, etc.
  • you have mask texture(s) n channels in total, stores blending coefficients each texture t in channels: r channel holds alpha t1, g channel t2, b t3, ... etc.
  • in pixel shader sampling layer textures usual, , color values float4 val1, val2, val3, ...
  • then sampling masks texture(s) corresponding blend coefficients , float blend1, blend2, blend3, ...
  • then applying kind of blending algorith, example simple linear interpolation:
float4 terraincolor = lerp( val1, val2, blend1 ); terraincolor = lerp( terraincolor, val3, blend2); terraincolor = lerp( terraincolor, ..., blendn ); 

for example if t1 grass, , have big grass field in middle of map, wave big red field in middle.

this algorithm bit slow, because of texture sampling, simple implement, gives visual results , flexible. can use not mask blend coefficients, values: example height (sample more snow in mountain peaks, rock in mountains, dirt in low ground), slope (rock on steep, grass on flat), fixed values, etc. or mix of that. also, can vary blending: use built-in lerp or more complicated (warning! example stupid):

float4 terraincolor = val1 * val2 * blend1 + val2 * val3 * blend2;
terraincolor = saturate(terraincolor);

playing blend algo interesting part of aproach. , can find many-many techniques in google.

not sure, hope helps! happy coding! =)


Comments

Popular posts from this blog

php - cannot display multiple markers in google maps v3 from traceroute result -

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -