DGL
https://delphigl.com/forum/

Marching-Tetrahedra
https://delphigl.com/forum/viewtopic.php?f=20&t=10356
Seite 1 von 1

Autor:  FrenK [ Di Mär 13, 2012 09:03 ]
Betreff des Beitrags:  Marching-Tetrahedra

Ich habe einige Zeit damit verbracht einen Shader, der den Marching-Tetrahedra Algorithmus auf der GPU ausführt zu schreiben.
Wem das ganze nichts sagt, Marching-Tetrahedra dient der Oberflächengenerirung aus einem Wertegitter(z.B ein Massengitter bei einer Flüssigkeitsimulation oder vll Hitze).

Derzeit gibt es jedoch einige probleme den so erzeugten Mesh zu texturieren, mir fehlt schlicht der Ansatz.

Code:
  1.  
  2. #version 420 core
  3.  
  4. // uniform buffer bindings
  5. #define TRANSFORM   0
  6. // texture units
  7. #define DATAFIELD   1
  8.  
  9. layout (points, invocations = 1) in;
  10. layout (triangle_strip, max_vertices = 24) out;
  11.  
  12. layout (binding = TRANSFORM) uniform transform {
  13.     mat4 ModelViewMatrix;
  14.     mat4 ProjectionMatrix;
  15.     mat4 InfProjectionMatrix;
  16.     mat4 MVPMatrix;
  17.     vec4 Viewport;
  18. } Transform;
  19.  
  20. //Volume data field texture
  21. layout (binding = DATAFIELD) uniform sampler3D dataFieldTex;
  22.  
  23. out TexCoord {
  24.     smooth vec2 decalTexCoord;
  25. } Out;
  26.  
  27. uniform float isolevel = 0.39;
  28. uniform vec3 vertDecals[8];
  29.  
  30. const int[14] edgeTable = {
  31.   0x0d, 0x13, 0x1e, 0x26, 0x2b, 0x35, 0x38, 0x38, 0x35, 0x2b, 0x26, 0x1e, 0x13, 0x0d
  32. };
  33.  
  34. const int[14 * 4] triTable = {
  35.    0,  3,  2, -1,
  36.    0,  1,  4, -1,
  37.    1,  4,  2,  3,
  38.  
  39.    1,  2,  5, -1,
  40.    3,  5,  0,  1,
  41.    2,  5,  0,  4,
  42.    5,  4,  3, -1,
  43.  
  44.    3,  4,  5, -1,
  45.    4,  5,  0,  2,
  46.    1,  5,  0,  3,
  47.    5,  2,  1, -1,
  48.  
  49.    3,  4,  2,  1,
  50.    4,  1,  0, -1,
  51.    2,  3,  0, -1,
  52. };
  53.  
  54. void marchTetra(vec3[4] pos, float[4] val){
  55.      //Determine the index into the edge table which
  56.      //tells us which vertices are inside of the surface
  57.      int tetraIndexFlag = 0;
  58.  
  59.      if (val[0] < isolevel) tetraIndexFlag |= 1;
  60.      if (val[1] < isolevel) tetraIndexFlag |= 2;
  61.      if (val[2] < isolevel) tetraIndexFlag |= 4;
  62.      if (val[3] < isolevel) tetraIndexFlag |= 8;
  63.  
  64.      if (tetraIndexFlag == 0 || tetraIndexFlag == 15) return;
  65.  
  66.      tetraIndexFlag--;
  67.  
  68.      vec3 vertlist[6];
  69.  
  70.      if ((edgeTable[tetraIndexFlag] & 1)!=0 )
  71.           vertlist[0] = mix(pos[0], pos[1], (isolevel-val[0])/(val[1]-val[0]));
  72.      if ((edgeTable[tetraIndexFlag] & 2)!=0 )
  73.       vertlist[1] = mix(pos[1], pos[2], (isolevel-val[1])/(val[2]-val[1]));
  74.      if ((edgeTable[tetraIndexFlag] & 4)!=0)
  75.       vertlist[2] = mix(pos[2], pos[0], (isolevel-val[2])/(val[0]-val[2]));
  76.      if ((edgeTable[tetraIndexFlag] & 8)!=0)
  77.       vertlist[3] = mix(pos[0], pos[3], (isolevel-val[0])/(val[3]-val[0]));
  78.      if ((edgeTable[tetraIndexFlag] & 16)!=0)
  79.       vertlist[4] = mix(pos[1], pos[3], (isolevel-val[1])/(val[3]-val[1]));
  80.      if ((edgeTable[tetraIndexFlag] & 32)!=0)
  81.       vertlist[5] = mix(pos[2], pos[3], (isolevel-val[2])/(val[3]-val[2]));
  82.  
  83.      gl_Position = Transform.MVPMatrix * vec4(vertlist[triTable[tetraIndexFlag * 4 ]], 1);
  84.      Out.decalTexCoord = vertlist[triTable[tetraIndexFlag * 4 + 0]].xy;
  85.      EmitVertex();
  86.  
  87.      gl_Position = Transform.MVPMatrix * vec4(vertlist[triTable[tetraIndexFlag * 4 + 1]], 1);
  88.      Out.decalTexCoord = vertlist[triTable[tetraIndexFlag * 4 + 1]].xy;
  89.      EmitVertex();
  90.  
  91.      gl_Position = Transform.MVPMatrix * vec4(vertlist[triTable[tetraIndexFlag * 4 + 2]], 1);
  92.      Out.decalTexCoord = vertlist[triTable[tetraIndexFlag * 4 + 2]].xy;
  93.      EmitVertex();
  94.  
  95.      if(triTable[tetraIndexFlag * 4 + 3] != -1){
  96.        gl_Position = Transform.MVPMatrix * vec4(vertlist[triTable[tetraIndexFlag * 4 + 3]], 1);
  97.        Out.decalTexCoord = vertlist[triTable[tetraIndexFlag * 4 + 3]].xy;
  98.        EmitVertex();
  99.      }
  100.  
  101.      EndPrimitive();
  102. }
  103.  
  104. const float texshift = 1.0;
  105.  
  106. //Geometry Shader entry point
  107. void main(void) {
  108.      vec3 pos5 = gl_in[0].gl_Position.xyz + vertDecals[5];
  109.      vec3 pos[4];
  110.  
  111.      pos[0] = gl_in[0].gl_Position.xyz + vertDecals[0];
  112.      pos[1] = pos5;
  113.      pos[2] = gl_in[0].gl_Position.xyz + vertDecals[1];
  114.      pos[3] = gl_in[0].gl_Position.xyz + vertDecals[6];
  115.  
  116.      float val5 = texture(dataFieldTex, (pos5+texshift)/2).r;
  117.      float val[4];
  118.  
  119.      val[0] = texture(dataFieldTex, (pos[0]+texshift)/2).r;
  120.      val[1] = val5;
  121.      val[2] = texture(dataFieldTex, (pos[2]+texshift)/2).r;
  122.      val[3] = texture(dataFieldTex, (pos[3]+texshift)/2).r;
  123.  
  124.      marchTetra(pos, val);
  125.  
  126.      pos[1] = pos[2];
  127.      pos[2] = gl_in[0].gl_Position.xyz + vertDecals[2];
  128.      val[1] = val[2];
  129.      val[2] = texture(dataFieldTex, (pos[2]+texshift)/2).r;
  130.  
  131.      marchTetra(pos, val);
  132.  
  133.      pos[1] = pos[2];
  134.      pos[2] = gl_in[0].gl_Position.xyz + vertDecals[3];
  135.      val[1] = val[2];
  136.      val[2] = texture(dataFieldTex, (pos[2]+texshift)/2).r;
  137.  
  138.      marchTetra(pos, val);
  139.  
  140.      pos[1] = pos[2];
  141.      pos[2] = gl_in[0].gl_Position.xyz + vertDecals[7];
  142.      val[1] = val[2];
  143.      val[2] = texture(dataFieldTex, (pos[2]+texshift)/2).r;
  144.  
  145.      marchTetra(pos, val);
  146.  
  147.      pos[1] = pos[2];
  148.      pos[2] = gl_in[0].gl_Position.xyz + vertDecals[4];
  149.      val[1] = val[2];
  150.      val[2] = texture(dataFieldTex, (pos[2]+texshift)/2).r;
  151.  
  152.      marchTetra(pos, val);
  153.  
  154.      pos[1] = pos[2];
  155.      pos[2] = pos5;
  156.      val[1] = val[2];
  157.      val[2] = val5;
  158.  
  159.      marchTetra(pos, val);
  160. }
  161.  

Autor:  Coolcat [ Di Mär 13, 2012 17:53 ]
Betreff des Beitrags:  Re: Marching-Tetrahedra

In GPU Gems 3 gibt es ein Kapitel zu Marching Cubes. Dort gibt es ja im wesentlichen das gleiche Problem. In Abschnitt 1.5 wird "triplanar texturing" als Lösung beschrieben. Im wesentlichen nimmst du eine schöne kachelbare Textur und wählst dann ein die am besten passende 2D-Projektion entlang einer der drei Koordinatenachsen. Dazwischen gibt es dann natürlich etwas Blending.

Das Kapitel (und das ganze Buch) gibt es hier kostenlos als HTML:
http://http.developer.nvidia.com/GPUGem ... _ch01.html

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/