Prozedurale Oberflächen, How-Not-To

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Nicht wirklich, aber ich weiß auch nicht, wie ich es wegkriegen soll. Die Position ist jetzt stetig, aber die erste Ableitung ist in der Mitte der Kanten nicht stetig. Irgendne Idee, wie ich dem beikommen könnte? Kann man sowas überhaupt von Bezier erwarten?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Jonathan »

Ja, du brauchst aber mehr Kontrollpunkte. D.h. du baust deiner Kurvenstücke nicht mehr als 3 Punkten, sondern nimmst immer 5 (oder so). Dadurch wird die Ableitung stetig, aber die Interpolation natürlich auch glatter, d.h. es gehen vermutlich ein paar Details verloren. Der Suchbegriff lautet "C1-Stetig" (C0-Stetig: Kein Sprung in der Position, C1-stetig: kein Sprung in der ersten Ableitung, C2-stetig: kein Sprung in der zweiten Ableitung, usw.):

https://math.stackexchange.com/question ... zier-curve

(ist jetzt vielleicht nicht der beste Link, hab aber auf die schnelle nix besseres gefunden)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Jonathan »

https://www.uni-koblenz.de/~cg/ss09/cg3/13_splines.pdf

Schau dir Folie 14 an. Du siehst eine Kurve, die aus 2 Segmenten zusammengesetzt ist.
- Wenn du willst, dass die Position stetig ist, müssen P3 und P4 identisch sein.
- Wenn du willst, dass die Ableitung stetig ist, müssen P2, P3/P4 und P5 auf einer Geraden liegen. (Die Kurve ist ja am Endpunkt immer tangential zu der Verbindungslinie der ersten/letzten beiden Kontrollpunkte)
- Wenn du eine Stetige 2te Ableitung brauchst (etwa für weiche Kamerafahrten), müssen ähnliche Kriterien für P1 und P6 gelten.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Oh cool. Mehr P's... naja, sehe ich nicht kommen, da ich das nur als Arbeitsbasis brauche und diesen Sprung im Endergebnis hoffentlich nie wieder jemand sehen wird. Aber das gibt mir die Idee, den mittleren Stützpunkt einfach mal mathematisch weiter raus zu schieben. Aktuell habe ich den dahin gesetzt, wo er laut Kurvenkrümmung sein müsste. Aber es ist ja ein Stützpunkt, die eigentliche Oberfläche geht weit davor durch. Ich muss den also soweit rauschieben, wie er bei nem Parallelogramm stehen würde. Und das kann ich mal fix ausprobieren, wenn mein Stand wieder baut.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

dungeon_noisedebug.png
So sieht aktuell die erste Oktave meiner Noise-Funktion aus. Offensichtliche Unstetigkeiten sind offensichtlich. Morgen debugge ich das.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

screenshot0049.png
Noise ist repariert, liefert für Farbwerte gute Rrgebnisse. Leider nicht für die NormalMap. Was ist passiert?

Ich rendere die NormalMap aus, indem ich pro Texturpixel die baryzentrischen Koordinaten des Dreiecks bestimme. Dann berechne ich drei Punkte knapp rund um diese Position und lenke diese drei Punkte anhand des Noise aus, wie ich es auch mit den echten Vertizes tun würde. Die resultierende Normale dieses Dreiecks schreibe ich dann in die NormalMap.

Die Idee war eigentlich gut, fand ich. Aber die Noise ist halt nur linear zwischen 2³ Zufallswerten interpoliert. Die Normale entspricht der Schräge der Oberfläche, ist also quasi die erste Ableitung. Und bei linearer Interpolation ist prinzipiell die erste Ableitung konstant und springt halt an den Werte-Kanten zur nächsten Konstante.

Und ich denke, genau das sieht man hier. Meine Referenz ist das Höhlenstück links oben. Da sieht hübsch, wie in allen drei Raumrichtungen irgendwann eine Kante kommt. Der Abstand der Kanten entspricht der "Rate", mit der das Sampling in den Zufallszahlen voran schreitet.

Wie löst man das Problem jetzt? Ich weiß es nicht. Ich habe versucht, die drei Punkte für die Normalenbestimmung weiter weg zu schieben. Das sorgt zwar für weichere Sprungkanten, weil das "Abtast-Dreieck", was ich zur Normalenbestimmung über die raue Oberfläche schiebe, größer ist. Aber dafür kriege ich eine neue Art von Unstetigkeit rein, nämlich dadurch, dass mein Abtast-Dreieck seinen Zufall aus den Punkten in der eigenen Ebene zieht, die nur selten die Ebene der Nachbarfläche ist.

Was ich eigentlich bräuchte, ist tricubische Interpolation. Oder ich bestimme einfach Höhenwerte pro Texturpixel und berechne die Normale auf die Oldschool-Art.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
marcgfx
Establishment
Beiträge: 2050
Registriert: 18.10.2010, 23:26

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von marcgfx »

sieht schon richtig nice aus!
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Danke! Jetzt sieht es aber richtig nice aus. Die NormalMap wird jetzt nicht mehr direkt ausm Noise berechnet, sondern erst in so ne Art HeightMap ausgerendert, aus der ich dann per pixel die NormalMap berechne. Das führt leider zu ein pixel breiten Störstreifen, die ich erstmal mit nem fiesen kleinen Epsilon beim Ausrendern der Dreiecke auf die Texturen gefixt habe, aber irgendwas ist ja immer.

Die Normalen-Unstetigkeiten entlang der Urflächen-Kanten sind echt lästig. Ich dachte zuerst, es ist ja nur ein bissl Beleuchtungskante, das kann ich später noch fixen. Aber nahezu jede Methode, die Flächen bzw. Punkte auszulenken, zerreist an dieser Stelle die Oberfläche. Und das, obwohl die Ur-Punkte an der Stelle konsistente bruchfreie Normalen haben. Tsss. Nuja, hab wieder furchtbar viel gelernt.
dungeon_fels.png
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Und weil ich das so knöfte finde, hier der Code der Noise-Funktion und der Fractal Brownian Motion-Funktion

Code: Alles auswählen

float MakeSomeNoise( TVektor3 pos) noexcept
{
  __m128 p = _mm_set_ps( 0.0f, pos.z, pos.y, pos.x);
  __m128 ip = _mm_floor_ps(p);
  auto dp = _mm256_set_m128( ip, ip);

  // 4x (2x vec4) bilden, wo jeweils die untere Lane X+0 und die obere Lane x+1 hat
  static constexpr float OffsetWerte[8] = { 0.0f, 0.0f, 1.0f, 1.0f,      0.0f, 1.0f, 1.0f, 0.0f };
  auto offset = _mm256_load_ps( OffsetWerte);
  auto p01 = _mm256_add_ps(dp, _mm256_permute_ps( offset, 0b00'01'00'00)); // +0000 0100
  auto p23 = _mm256_add_ps(dp, _mm256_permute_ps( offset, 0b00'01'00'10)); // +0010 0101
  auto p45 = _mm256_add_ps(dp, _mm256_permute_ps( offset, 0b00'01'10'00)); // +0100 0110
  auto p67 = _mm256_add_ps(dp, _mm256_permute_ps( offset, 0b00'01'10'10)); // +0110 0111

  // 4x (2x float4) jeweils punktprodukten zu 4x2 float 
  static constexpr float SkalWerte[8] = { 0.29575f, 0.72357f, 0.471205f, 0.0f,     0.29575f, 0.72357f, 0.471205f, 0.0f };
  auto skal = _mm256_load_ps( SkalWerte);
  auto dp01 = _mm256_dp_ps( _mm256_mul_ps( p01, p01), skal, 0b0111'1111); // Punktprodukt "xxxx = 0xyz dot skal" auf beiden Lanes
  auto dp23 = _mm256_dp_ps( _mm256_mul_ps( p23, p23), skal, 0b0111'1111);
  auto dp45 = _mm256_dp_ps( _mm256_mul_ps( p45, p45), skal, 0b0111'1111);
  auto dp67 = _mm256_dp_ps( _mm256_mul_ps( p67, p67), skal, 0b0111'1111);
  
  // Zusammenmischen, so dass jedes Punktprodukt-Ergebnis in einem der 8x float landet
  auto zufall8 = _mm256_blend_ps( _mm256_blend_ps( dp01, dp23, 0b1010'1010), _mm256_blend_ps( dp45, dp67, 0b1010'1010), 0b1100'1100);
  // der Nachkomma-Anteil ist der Zufall
  zufall8 = _mm256_sub_ps( zufall8, _mm256_floor_ps( zufall8));

  // Nachkomma-Anteil. Den müssen wir jetzt in v und 1.0f-v auftrennen und gleichmäßig auf alle 8 Werte verteilen
  __m128 lp = _mm_sub_ps( p, ip);
  static constexpr float PlusMinusWerte[8] = { 1.0f, 1.0f, -1.0f, -1.0f,     1.0f, -1.0f, 1.0f, -1.0f };
  static constexpr float EinsNullWerte[8] = { 0.0f, 0.0f, 1.0f, 1.0f,        0.0f, 1.0f, 0.0f, 1.0f };
  auto plusMinus = _mm256_load_ps( PlusMinusWerte);
  auto einsNull = _mm256_load_ps( EinsNullWerte);
  auto spx = _mm256_broadcastss_ps( lp);                        //  +1 -1 +1 -1 +1 -1 +1 -1        0 1 0 1 0 1 0 1
  spx = _mm256_fmadd_ps( spx, _mm256_permute_ps( plusMinus, 0b00'11'00'11), _mm256_permute_ps( einsNull, 0b00'11'00'11));
  auto spy = _mm256_broadcastss_ps( _mm_shuffle_ps( lp, lp, 1)); //  +1 +1 -1 -1 +1 +1 -1 -1        0 0 1 1 0 0 1 1
  spy = _mm256_fmadd_ps( spy, _mm256_permute_ps( plusMinus, 0b00'00'11'11), _mm256_permute_ps( einsNull, 0b00'00'11'11));
  auto spz = _mm256_broadcastss_ps( _mm_shuffle_ps( lp, lp, 2)); //  +1 +1 +1 +1 -1 -1 -1 -1        0 0 0 0 1 1 1 1
  spz = _mm256_fmadd_ps( spz, _mm256_permute_ps( plusMinus, 0b10'10'10'10), _mm256_permute_ps( einsNull, 0b10'10'10'10));

  auto gewichte = _mm256_mul_ps( spx, _mm256_mul_ps( spy, spz));

  // 4xfloat Punktprodukt | 4xfloat Punktprodukt, wir schreiben das Ergebnis jeweils in alle 4 floats
  auto punktProdukt4 = _mm256_dp_ps( zufall8, gewichte, 0b1111'1111);
  // und dann ziehen wir wahllos einen Float aus den oberen 4float und einen aus den unteren 4float und summieren
  auto erg = _mm_cvtss_f32( _mm256_extractf128_ps( punktProdukt4, 0)) + _mm_cvtss_f32( _mm256_extractf128_ps( punktProdukt4, 1));
  return erg;
}

static constexpr TMatrix4x4 NoiseTransform[8] = {
TMatrix4x4 { 0.2506f, 0.2779f, 0.4035f, 0.0125f,
             -0.2134f, 0.4699f, -0.1912f, 5.6359f,
             -0.4411f, -0.0694f, 0.3217f, 1.9330f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { -0.7059f, 0.1936f, -0.7067f, 8.9596f,
             -0.7324f, -0.1580f, 0.6883f, 8.2284f,
             0.0212f, 0.9862f, 0.2490f, 7.4660f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { 1.1198f, 0.8200f, 1.4891f, 3.0399f,
             -1.6983f, 0.6172f, 0.9372f, 0.1498f,
             -0.0739f, -1.7579f, 1.0236f, 0.9140f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { 2.7346f, -2.6272f, -0.7243f, 4.4569f,
             2.1789f, 2.7241f, -1.6543f, 1.1908f,
             1.6368f, 0.7630f, 3.4123f, 0.0467f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { -6.5153f, -1.4712f, 4.5432f, 6.0176f,
             -4.4642f, 4.6056f, -4.9106f, 6.0717f,
             -1.6959f, -6.4714f, -4.5277f, 1.6623f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { 11.0403f, 10.5473f, -3.4436f, 6.0768f,
             -1.3244f, -3.5705f, -15.1819f, 7.8332f,
             -11.0159f, 11.0000f, -1.6260f, 8.0261f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { -23.9722f, 0.6439f, -17.4160f, 9.5590f,
             17.3036f, -2.6512f, -23.9155f, 9.2572f,
             -2.0775f, -29.5119f, 1.7685f, 5.3935f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
TMatrix4x4 { -49.1905f, 0.0925f, -39.5407f, 2.0960f,
             -25.5453f, -48.2477f, 31.6666f, 7.7966f,
             -30.1814f, 40.6857f, 37.6422f, 8.4365f,
             0.0000f, 0.0000f, 0.0000f, 1.0000f },
};

float MakeNoise( TVektor3 pos)
{
  float v = 0.0f;
  for( int a = 0; a < 8; ++a )
    v += pow( 0.50946f, float( a + 1)) * MakeSomeNoise( NoiseTransform[a] * pos);
  return v;
}
Noise ist immer ein bissl Rumspielsache.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

Welten besser jetzt. Sehr schön.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Jonathan »

Also die Oberflächen sehen jetzt richtig schick und detailliert aus. Aber wo diese harten Kanten her kommen verstehe ich immer noch nicht so ganz.
Die Ausgangslage sind doch große Würfel (so dass die Szene von links nach rechts ~5 Würfel breit ist), die du dann mit Splines interpolierst, richtig? Und die Kanten die man sieht sind genau die zwischen den ursprünglichen Würfeln, oder? Aber wie ist das jetzt gerendert, sind das noch die ursprünglichen Würfel und du erzeugst die Details per Tesselation oder so? Denn wenn nicht (es also einfach high-poly Geometrie ist), und du die Splines an den Übergangen richtig zusammengesetzt hast, verstehe ich nicht wirklich wieso man von den Ursprünglichen Kanten noch überhaupt etwas sehen sollte.

Die Ausführungen zu der Normalenberechnung hab ich auch nicht komplett verstanden. Vielleicht fehlt mir da einfach etwas Wissen über den Rest der Pipeline. Aber egal, bis auf diese kleinen Artefakte scheint ja jetzt schon alles recht gut zu funktionieren.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Jonathan hat geschrieben: 09.04.2021, 19:33 Also die Oberflächen sehen jetzt richtig schick und detailliert aus. Aber wo diese harten Kanten her kommen verstehe ich immer noch nicht so ganz.
Die Ausgangslage sind doch große Würfel (so dass die Szene von links nach rechts ~5 Würfel breit ist), die du dann mit Splines interpolierst, richtig? Und die Kanten die man sieht sind genau die zwischen den ursprünglichen Würfeln, oder? Aber wie ist das jetzt gerendert, sind das noch die ursprünglichen Würfel und du erzeugst die Details per Tesselation oder so? Denn wenn nicht (es also einfach high-poly Geometrie ist), und du die Splines an den Übergangen richtig zusammengesetzt hast, verstehe ich nicht wirklich wieso man von den Ursprünglichen Kanten noch überhaupt etwas sehen sollte.

Die Ausführungen zu der Normalenberechnung hab ich auch nicht komplett verstanden. Vielleicht fehlt mir da einfach etwas Wissen über den Rest der Pipeline. Aber egal, bis auf diese kleinen Artefakte scheint ja jetzt schon alles recht gut zu funktionieren.
Diese Lichtkanten haben wir im IRC umfangreich diskutiert. Das Problem ist, dass ich mit den Kontrollpunkten des Herrn Bezier zwar hinbekomme, dass die Positionen der Kantenvertizes auf beiden Seiten der Kante identisch verlaufen. Aber was ich damit nicht hinkriege, ist dass die erste Ableitung - die Normalen - an der Kante stabil sind. An den Ecken passt es, weil ich die Stützpunkte in der Ebene der Eck-Normale platziere. Ich *glaube*, mit quadruplischer oder wie das heißt Bezier könnte ich das stabil kriegen. Joeydee meint dagegen, das wäre bei Dreiecken prinzipiell unmöglich.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
joeydee
Establishment
Beiträge: 1039
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von joeydee »

Sehr cool :)

Hier nochmal das Ergebnis aus dem Chat: geht wahrscheinlich nicht so wie ich gedacht hatte (Konstruktion der Kontrollpunkte aus dem Tangent-Space). C1-Stetigkeit im Vertex wird nicht automatisch zur C1-Stetigkeit der Patch-Kanten, sondern bleibt nur in den Vertices. Da kann man mitunter recht scharfe Kanten produzieren, wenn man die Vertexnormalen entsprechend verbiegt.
crap1.jpg
crap2.jpg
(EDIT: ich habe mit Quad-Patchens ausprobiert, Schrompf mit Dreiecks-Patches. Zwei Dreiecken zum Quad zusammengesetzt fehlt dann aber Nachbarschaftsinformation über den jeweils gegenüberliegenden Vertex, d.h. das Kantenproblem tritt zusätzlich auch an den Diagonalen auf; davon unabhängig hatte ich noch vermutet, dass hier auch das damit verwandte UV-Koordinatenproblem für Trapeze mit reinschlagen könnte: https://forums.autodesk.com/t5/image/se ... F3FE0?v=v2)


Also doch irgendwie anders. Weg von den Averaged Normals und den Ecken als Fixpunkte.
In 2D kann man stattdessen ja auch die Linienmitten als Fixpunkte, und die Ecken als Kontrollpunkte nehmen. Also im folgenden Bild statt wie oben, wie unten verfahren.
facecentered.jpg
Wie das in 3D auf ein beliebiges Mesh umzusetzen wäre, bis man die 16 Kontrollpunkte für ein Bezierpatch hat, da habe ich jetzt noch keine Zeit/Gehirnschmalz investiert.

Kommt dann auch dem von Jonathan vorgeschlagenen Catmull-Clark-Algo nahe, Ecken werden abgefeilt oder aufgefüllt. Also würde ich auch mal CC ins Auge fassen. Evtl. gewichtetes Average, um Kontrolle über den Grad der Rundung zu bekommen, müsste eigentlich gehen.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Jonathan »

Uff, die 3D-Bildchen sind ein bisschen schwer zu parsen, aber ich denke, ich verstehe das Problem.
Die Verallgemeinerung von 2D auf 3D ist einfach, solange man ein 'reguläres Gitter' hat, aber wenn Vertexe zu beliebig vielen Dreiecken gehören können ist ja irgendwann nichmal mehr klar, wie eine Linie weiter geht...

Ich habe auch noch nie mit Bezier-Flächen gearbeitet. Der Wikipediaartikel gibt möglicherweise ein paar Stichworte für weitere Suchen, speziell die Dreiecks-Bezeirflächen hören sich vielversprechend an:

https://de.wikipedia.org/wiki/Bezierfl%C3%A4che

Aber da scheint die Mathematik schnell ziemlich unübersichtlich zu werden. Vermutlich alles ganz einfach, sobald man einmal die Indices etc. verstanden hat, trotzdem bin ich gerade ein wenig zu faul, mir das alles in 3D vorzustellen...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
joeydee
Establishment
Beiträge: 1039
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von joeydee »

Wikipedia & Co. zu Bezier-Patch sind eigentlich durch, das ist ja alles umgesetzt.
Die Frage ist/war ja nicht, wie man ein Patch generell interpoliert, sondern ob man die Kontrollpunkte zweier Patches mit gemeinsamer Kante derart konstruieren kann, dass a) die ursprünglichen Vertices erhalten bleiben (ja), b) eine gemittelte (also quasi-beliebige) Normale an diesem Vertex vorgegeben werden kann wobei die Oberfläche dort C1-stetig ist (ja) und c) die Stetigkeit auch auf alle Kanten zwischen diesen Vertices zutrifft (offensichtlich nein).

In 2D bringt die Normalenvorgabe genug "Wissen" der Umgebung mit, damit man ein einzelnes Kurvensegment separat konstruieren kann: es reichen jeweils die beiden Vertices und deren Normalen als Information, die weitere Umgebung muss nicht berücksichtigt werden. Das war der Hintergedanke.

Bilder schwer zu parsen: ich habe das nur aus dem Chat wiederholt, war ursprünglich für Schrompf. Man muss die ganzen Linien nicht verstehen, würde jetzt zu weit führen, Aussage der Bilder ist lediglich: "ich habs mit Quads probiert, C1 geht am Vertex, aber geht futsch an der Kante, wenn man die Kontrollpunkte so konstruiert wie besprochen."

Man könnte da natürlich noch weiterexperimentieren, bestimmte Kontrollpunkte versuchen so anzupassen dass sie zum nächsten Patch wieder auf einer Eben liegen, ohne dass die Ecken kaputtgehen ...

Dreieckspatches vielversprechend: Das hat Schrompf ja umgesetzt. C1 geht dann wohl zusätzlich an der Diagonalen flöten.

Man *kann* natürlich Bezier-Patches sauber aneinanderreihen, aber muss dann, wie bei Catmull-Clark-Subdiv, auf die Eigenschaft a) verzichten, und b) ergibt sich aus der neuen Geometrie, ohne Vorgabe.
Für Beziers bekäme man erstmal ein N-Gon aus den angrenzenden Flächenmitten, welches auf Dreiecks- oder Vierecks-Patches konvertiert werden müsste. Die Kontrollpunkte werden auf der alten Oberfläche liegend konstruiert. Man hätte dann die beiden neuen Prämissen a) Position der Flächenmitten bleibt erhalten und b) Normale der Flächenmitte bleibt erhalten (glaube ich).
Bei Catmull-Clark gehen auch diese beiden mehr oder weniger kaputt. Wäre aber auch nicht tragisch. Und wahrscheinlich einfacher, als Bezierpatches aus NGons zu erstellen.

Schrompf hatte sowas Ähnliches ja als Basis, aber hier im Thread dann das mit der Normalenvorgabe begonnen, weil ihm die andere Methode an Konvex-Konkav-Stellen irgendwie explodiert ist. Catmull-Clark müsste das aber können.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

Wikipedia hat ein Beispielbild was man machen muss, aber nicht _wie_ man es macht

https://de.wikipedia.org/wiki/Datei:Ble ... zierfl.svg

Bild

Der Artikel (https://de.wikipedia.org/wiki/Geometrische_Stetigkeit) erinnert noch an die alte Wikipedia vor 15 Jahren. Da hat halt jemand sein Vorlesungsscript in Einzelteilen hochgeladen, so ungefähr. Mit Perlen wie
Bemerkung: Das Zusammensetzen von Kurven/Flächen mit G 1 {\displaystyle G^{1}} G^{1}-Kontakt ist relativ einfach. Kurven mit G 2 {\displaystyle G^{2}} G^2-Kontakt zu modellieren ist etwas schwieriger. Ziemlich schwer ist es, Flächen mit G 2 {\displaystyle G^{2}} G^2-Kontakt herzustellen.[3] In der vorwiegend englischsprachigen Literatur findet man die Erzeugung G n {\displaystyle G^{n}} G^{n}-stetiger Kurven und Flächen unter dem Titel blending curves and surfaces.
Der Artikel über Bezierflächen selbst hat ja auch so ein "Für weitere Details sei auf die Literatur verwiesen."

Das Skript auf das sie sich beziehen ist: https://www2.mathematik.tu-darmstadt.de ... en0104.pdf, da Kapitel 11. Daraus ist auch das oben verlinkte Bild (S. 132).

Ich habe aber noch nicht lange genug draufgeschaut um beurteilen zu können ob man Kapitel 1 - 10 lesen und verstehen muss um da einzusteigen. Das wäre ja genau das was Schrompf am Anfang nicht wollte.


Ich habe übrigens lange gebraucht zu verstehen, was eigentlich das Problem ist, weil ich gar nicht die Intuition hatte, dass das, was hier nicht geht, gehen müsste, und fast nochmal genausolange die offensiven Linien im gerenderten Bild zu finden, weil ich die für ein Feature hielt und keinen Bug.

Womit wir wieder bei einer meiner früheren Antworten an Zudo wären: Ich habe nie sagen wir verstanden, wie Computergrafiker den Normalenbegriff verwenden. Es ist ja eigentlich ganz klar, dass zwei Dreiecke nur dann dieselbe Normale haben können, wenn sie koplanar sind und wenn sie einander zusätzlich berühren sollen, dann liegen sie halt trivial in derselben Ebene. Scheint mir eine nicht wegzudiskutierende Eigenschaft der Diskretisierung zu sein. Manchmal hat die Welt halt eine Kante.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

Nachtrag: Wenn ich das Prolem lösen müsste und keine Lust hätte das o. g. Skript nachzuprogrammieren, würde ich vermutlich versuchen es iterativ zu nähern, kann aber sein, dass das dann nur einen schlechteren Catmull-Clark hergeleitet aus first principles ergibt.

Nachtrag zum Nachtrag: Dem Titel nach zu urteilen hatte auch die Idee schon jemand:

http://www.cs.cmu.edu/afs/cs.cmu.edu/ac ... atches.pdf

"Approximating Catmull-Clark Subdivision Surfaceswith Bicubic Patches"
joeydee
Establishment
Beiträge: 1039
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von joeydee »

Alexander Kornrumpf hat geschrieben: 10.04.2021, 10:39 aber nicht _wie_ man es macht
So:
joeydee hat geschrieben: 10.04.2021, 09:51 Für Beziers bekäme man erstmal ein N-Gon aus den angrenzenden Flächenmitten, welches auf Dreiecks- oder Vierecks-Patches konvertiert werden müsste. Die Kontrollpunkte werden auf der alten Oberfläche liegend konstruiert. Man hätte dann die beiden neuen Prämissen a) Position der Flächenmitten bleibt erhalten und b) Normale der Flächenmitte bleibt erhalten (glaube ich).
Bezogen auf das Wiki-Bild: neue Vertices liegen auf der roten Linie (im allgemeinen alte Flächenmitte z.B., wenn es sich um zusammenhängende Flächen handeln würde), Kontrollpunkte für das neue grüne Patch liegen jeweils auf den alten Tangenten der Ursprungspatches an der roten Line, bzw einfach auf der planaren Ursprungsfläche. In meinem letzten Post als 2D-Anwendung im letzten Bild untere Hälfte grob veranschaulicht.
Erfüllt halt wie gesagt nicht Schrompfs ursprüngliche Prämissen, dass Eckpunkte und deren Normalen vorgegeben werden und erhalten bleiben, was aber imho auch gar nicht notwendig ist für ein anschauliches solides Ergebnis.
Aslo ja, ganz genau: Ecken so wie zuletzt illustriert auffüllen/abfeilen, ob mit Bezier oder CC.
Alexander Kornrumpf hat geschrieben: 10.04.2021, 10:39 Ich habe nie sagen wir verstanden, wie Computergrafiker den Normalenbegriff verwenden. Es ist ja eigentlich ganz klar, dass zwei Dreiecke nur dann dieselbe Normale haben können, wenn sie koplanar sind und wenn sie einander zusätzlich berühren sollen, dann liegen sie halt trivial in derselben Ebene. Scheint mir eine nicht wegzudiskutierende Eigenschaft der Diskretisierung zu sein. Manchmal hat die Welt halt eine Kante.
Ja. Und wenn man grafisch sagen wir eine Kugel aus Facetten annähert, dann nimmt man gerne z.B. "Averaged Normals", also nicht die echten die aus zwei benachbarte Facetten berechnet werden und für jede Facette separat gelten, sondern man mittelt und interpoliert über die Fläche neu berechnete Normalen, auf Basis der originalen Facetten-Normalen, damit die Beleuchtung einer Kugel an jedem Pixel kontinuierlich rund wirkt, obwohl es die Geometrie dort gar nicht ist.

Edit: hier nochmal illustriert:
phong.jpg
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

joeydee hat geschrieben: 10.04.2021, 13:46 Ja. Und wenn man grafisch sagen wir eine Kugel aus Facetten annähert, dann nimmt man gerne z.B. "Averaged Normals", also nicht die echten die aus zwei benachbarte Facetten berechnet werden und für jede Facette separat gelten, sondern man mittelt und interpoliert über die Fläche neu berechnete Normalen, auf Basis der originalen Facetten-Normalen, damit die Beleuchtung einer Kugel an jedem Pixel kontinuierlich rund wirkt, obwohl es die Geometrie dort gar nicht ist.
Soweit so klar. Nur manchmal hat der abgebildete Gegenstand ja wirklich eine Kante und dann sollen die Normalen der beiden Flächen ja in verschiedene Richtungen zeigen und dann muss ich auf einmal unterscheiden in welchem der beiden Fälle ich bin.

Also ich angefangen habe mich damit zu beschäftigen war es noch akzeptiert das einmal global zu entscheiden und die Hälfte der Geometrie für die das die falsche Entscheidung war, sieht dann halt falsch aus (nannte sich damals dann glaube ich "hard" und "soft" shading"). Dann gab es "Bumpmaps" (das killer-feature von Doom 3), wohl heute Normalmaps, was ich mit meinem heutigen Wissen mal als "der Modellierer entscheidet" interpretieren würde. Korrekt?

Und das was Thomas hier vorhat ("prozedural") läuft ja darauf hinaus, die Entscheidung entweder wieder global zu treffen (die Kante zwischen Säule und Boden ist richtig, dieselbe Kante zwischen Boden und Boden ist falsch) oder irgendwie algorithmisch zu erkennen in welchem Fall wir sind (glätte Winkel unter x aber nicht über x, ist halt auch nur eine Heuristik) oder eben doch wieder auf modellierer Input zu setzen, dann ist es aber nicht vollständig prozedural.

Ich meine, dass dieser Tradeoff nicht weggeht und man irgendeinen Tod sterben muss.

Sieht man ja z. B. auch daran, dass Minecraft richtig aussieht, weil es vom Gehirn als die Legostein-Abstraktion geparst wird, die es ist, und Zudos Screenshots hier im Thread dagegen völlig falsch aussehen, weil sie uncanny-valley Signale senden die sich nicht zwischen "fotorealistisch" und "keine echte Landschaft würde so aussehen" entscheiden können.

Am Ende geht es denke ich darum, den Tradeoff zu wählen, der am ehesten dem entspricht, was man erreichen will, aber alles auf einmal wird nicht gehen.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

Nachtrag: mein Post und dein Edit haben sich überschnitten. Ich meinte mit "hard" und "soft" das was dein Bild "flat" und "phong" nennt.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Alexander Kornrumpf hat geschrieben: 10.04.2021, 14:23 Soweit so klar. Nur manchmal hat der abgebildete Gegenstand ja wirklich eine Kante und dann sollen die Normalen der beiden Flächen ja in verschiedene Richtungen zeigen und dann muss ich auf einmal unterscheiden in welchem der beiden Fälle ich bin.

Also ich angefangen habe mich damit zu beschäftigen war es noch akzeptiert das einmal global zu entscheiden und die Hälfte der Geometrie für die das die falsche Entscheidung war, sieht dann halt falsch aus (nannte sich damals dann glaube ich "hard" und "soft" shading"). Dann gab es "Bumpmaps" (das killer-feature von Doom 3), wohl heute Normalmaps, was ich mit meinem heutigen Wissen mal als "der Modellierer entscheidet" interpretieren würde. Korrekt?

Und das was Thomas hier vorhat ("prozedural") läuft ja darauf hinaus, die Entscheidung entweder wieder global zu treffen (die Kante zwischen Säule und Boden ist richtig, dieselbe Kante zwischen Boden und Boden ist falsch) oder irgendwie algorithmisch zu erkennen in welchem Fall wir sind (glätte Winkel unter x aber nicht über x, ist halt auch nur eine Heuristik) oder eben doch wieder auf modellierer Input zu setzen, dann ist es aber nicht vollständig prozedural.

Ich meine, dass dieser Tradeoff nicht weggeht und man irgendeinen Tod sterben muss.

Sieht man ja z. B. auch daran, dass Minecraft richtig aussieht, weil es vom Gehirn als die Legostein-Abstraktion geparst wird, die es ist, und Zudos Screenshots hier im Thread dagegen völlig falsch aussehen, weil sie uncanny-valley Signale senden die sich nicht zwischen "fotorealistisch" und "keine echte Landschaft würde so aussehen" entscheiden können.

Am Ende geht es denke ich darum, den Tradeoff zu wählen, der am ehesten dem entspricht, was man erreichen will, aber alles auf einmal wird nicht gehen.
Nein, Du bist auf dem falschen Pfad, das ist ne komplett anderen Problemstellung.

Das, was Du meinst, ist im Endeffekt Grafikerhandwerk. Früher hatte man Flächen mit Normalen, und hat an den Kanten entscheiden müssen, wie sich die Normalen da verhalten. Heutzutage hat mein keine Eck- und Kanten-Normalen mehr, sondern Normal Maps, also Per-Texel-Normalen, und die komplette Problemstellung ist einfach aus der Welt verschwunden.

Das ist aber alles nur historisch interessant, denn hier in diesem Thread geht es darum, dass zwei Flächen eine gemeinsame Kante haben, deren zwei Eckpunkte haben jeweils eine Normale. Die Normale ist hier immer kontinuierlich, die Entscheidung, von der Du sprachst, ist also global getroffen. Das Problem ist, dass die Subdivision nicht in der ersten Ableitung kontinuierlich ist. Und ich bin inzwischen überzeugt, dass das mit nem kubischen Polynom gehen müsste.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

Schrompf hat geschrieben: 10.04.2021, 15:04 Nein, Du bist auf dem falschen Pfad,
Auf dem falschen würde ich nicht sagen. Bewusst auf ein Nebengleis abgebogen trifft es eher.
Das ist aber alles nur historisch interessant, denn hier in diesem Thread geht es darum, dass zwei Flächen eine gemeinsame Kante haben, deren zwei Eckpunkte haben jeweils eine Normale. Die Normale ist hier immer kontinuierlich, die Entscheidung, von der Du sprachst, ist also global getroffen. Das Problem ist, dass die Subdivision nicht in der ersten Ableitung kontinuierlich ist. Und ich bin inzwischen überzeugt, dass das mit nem kubischen Polynom gehen müsste.
Ja schon klar. Wenn du das global enscheidest kannst du halt keine harten Kanten mehr irgendwo haben. War dir sicher auch klar und ist bestimmt legitim. Es geht mir nur darum, dass harte Kanten nicht per se falsch sind, sondern, dass es eine Wahl ist, die man da trifft.

Der Teil den ich nicht verstehe, im Sinne des ersten Beitrags dieses Nebenstrangs ist woher diese Fixierung auf weiche Kanten kommt. Insbesondere wenn die Zeiten in denen wir aus technischen Gründen keine an sich glatten Geometrie haben konnten vorbei sind.

Ist aber eine rein ästhetische Diskussion. Technisch sind wir uns völlig einig.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Alexander Kornrumpf hat geschrieben: 10.04.2021, 15:45 Ja schon klar. Wenn du das global enscheidest kannst du halt keine harten Kanten mehr irgendwo haben. War dir sicher auch klar und ist bestimmt legitim. Es geht mir nur darum, dass harte Kanten nicht per se falsch sind, sondern, dass es eine Wahl ist, die man da trifft.
Ok, das verstehe ich.
Alexander Kornrumpf hat geschrieben: 10.04.2021, 15:45 Der Teil den ich nicht verstehe, im Sinne des ersten Beitrags dieses Nebenstrangs ist woher diese Fixierung auf weiche Kanten kommt. Insbesondere wenn die Zeiten in denen wir aus technischen Gründen keine an sich glatten Geometrie haben konnten vorbei sind.
Ist aber eine rein ästhetische Diskussion. Technisch sind wir uns völlig einig.
Naja, eben gerade nicht :) Irgendwer hier im Thread oder auch im IRC hatte sich über die harten Kanten z.B. am Fuß der Säule gewundert, wo ich doch soviel Aufwand betrieben habe, damit alles rund wird. Und im Prinzip wird bei mir erstmal alles rund, es gibt noch keine Design-Einflussmöglichkeit, harte Kanten einzuziehen. Und eben gerade weil trotz dieser Absicht eben nicht alles perfekt rund wird, gibt es diese Diskussion überhaupt. Man könnte also sagen, es ist eine rein technische Diskussion.

Und deswegen widerspreche ich Dir hier so beharrlich :-) Ästhetik war nie verlangt.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

Schrompf hat geschrieben: 10.04.2021, 17:43 Naja, eben gerade nicht :) Irgendwer hier im Thread oder auch im IRC hatte sich über die harten Kanten z.B. am Fuß der Säule gewundert, wo ich doch soviel Aufwand betrieben habe, damit alles rund wird. Und im Prinzip wird bei mir erstmal alles rund, es gibt noch keine Design-Einflussmöglichkeit, harte Kanten einzuziehen. Und eben gerade weil trotz dieser Absicht eben nicht alles perfekt rund wird, gibt es diese Diskussion überhaupt. Man könnte also sagen, es ist eine rein technische Diskussion.

Und deswegen widerspreche ich Dir hier so beharrlich :-) Ästhetik war nie verlangt.
Ah jetzt. Für mich stellte es sich so dar als wäre die ursprüngliche Anforderung durch das was du jetzt gemacht hast erfüllt, und dann fällt als neue Anforderung vom Himmel, dass es in den genrierten Punkten auch glatt sein soll (was ich intuitiv ohne groß drüber nachzudenken nicht erwartet hätte, dass es das wird) aber für dich war das immer Teil der Anforderung.
joeydee
Establishment
Beiträge: 1039
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von joeydee »

Alexander, das hier ist die ursprüngliche Problemstellung, bzw. Schrompf's Anforderung:
normal_offset.jpg
Ursprungsmesh: blaue Punkte.
Normalen des Ursprungsmeshes: oberes Bild, grün. Wenn man jetzt das Mesh in kleinere Faces (schwarze Punkte) unterteilt und per Noise-Wert die neuen Punkte entlang der Flächennormalen verschiebt (rot=neue Oberfläche), entstehen hässliche Verzerrungen an den Ecken und Kanten.

Wenn man stattdessen an gemittelten und interpolierten Normalen verschiebt (unteres Bild, grün), bekommt man durch die Stetigkeit ein gleichmäßigeres Ergebnis. Und weniger Probleme an konkaven Stellen, wo sich die Offset-Geometrie überlappen kann.

In diesem Thread werden verschiedene Möglichkeiten diskutiert und ausprobiert, wie man das anhand möglichst weniger Nachbarinformation sauber berechnen kann. Am Ende soll das eine möglichst universelle Lösung für (quasi-)beliebige Meshes sein. (Meine Beiträge befassen sich bisher zwar mit Quad-Patches, durch einen Subdivision-Step kann man aber gemischte Polygon-Meshes in reine Quad-Meshes verwandeln).

Und ja, natürlich gibts da die genannten Lösungen, die aber i.d.R. die blauen Punkte verschieben. Ich speziell war einer Lösung hinterher, wo diese erhalten bleiben. Auch das geht, mit mehr Nachbarschaftsinformation. Ich versuche noch rauszubekommen, was die geringste ist.

Es ging also nie um Beleuchtung oder Ästhetik an dieser Stelle; zieht man aber die interpolierten Normalen testweise zur Beleuchtung heran (ohne Noise), kann man ganz gut beurteilen, ob die Interpolation überhaupt sauber funktioniert hat und wirklich überall Stetigkeit (== glatte Farbübergänge ohne harte Sprünge) herrscht.
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von starcow »

Sehr spannend und einmal mehr beeindruckend, wie kompetent und engagiert ihr hier wieder unterwegs seid und diskutiert. Einfach top! :-)
Ich verstehe zwar das Problem, konnte aber nicht bei jedem Lösungsversuch druchsteigen. Ich vermute, mir fehlt es dafür leider noch an "Background".
Ein kleiner Hinweis tortzdem von mir - einfach um sicherzustellen, dass dies in der Hitze des Gefechtes nicht vergessen geht.

Bild

Wenn ihr ein Polynom dritten Grades verwendet, das ausschauen soll, wie es die Grafik zeigt, würde ich das in jedem Fall so definieren:
Polynom in der Nullstellenform
k(x-x1)(x-x2)^2

- links aussen liegt offensichtlich eine einfache Nullstelle
- rechts aussen liegt offensichtlich eine doppelte Nullstelle

Jetzt Fehlt noch 1 Information, um das Polynom zu determinieren und k zu bestimmen.

Dafür würde ich den Terrassenpunkt in der Mitte nehmen. Das ist dort, wo die 1. Ableitung ihre _erste_ Nullstelle hat (die erste Ableitung hat noch eine weitere Nullstelle rechts aussen).

Edit:
Alternativ, könnte man - anstatt des Terassenpunktes, einfach einen "letzten" Punkt festlegen, bei welchem das Polynom durchkommen muss.
Legt man diesen einen Punkt noch fest, hat ein Polynom dritten Grades kein Freiheitsgrad mehr und ist eindeutig definiert.
Keine Ahnung, ob das jetzt hilft! :-)

LG, starcow
Zuletzt geändert von starcow am 11.04.2021, 10:44, insgesamt 1-mal geändert.
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Schrompf »

Ja, prima mitgedacht :-) Für diesen Fall hast Du auch völlig Recht, das würde so funktionieren. Ich brauchte aber den 3D-Fall für beliebige Senkrechtenvektoren an allen drei Ecken des Dreiecks.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Alexander Kornrumpf
Moderator
Beiträge: 2106
Registriert: 25.02.2009, 13:37

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Alexander Kornrumpf »

joeydee hat geschrieben: 11.04.2021, 09:25 Alexander, das hier ist die ursprüngliche Problemstellung, bzw. Schrompf's Anforderung:
[2d Bild]
Das jetzt noch verbleibende Problem tritt aber in 2d nicht auf, soweit ich es jetzt verstehe. Deswegen habe ich es nicht als Teil den "ursprünglichen Problems" verstanden, weil der Thread in 2d anfing. Dass es in Shrompfs Kopf immer Teil der Anforderung war, ist mir inzwischen auch klar.

Wir können das aber gerne nochmal testen. Dein Zitat von weiter oben:
C1-Stetigkeit im Vertex wird nicht automatisch zur C1-Stetigkeit der Patch-Kanten,
Ich verstehe das so, dass du mit "Vertex" die Vertices des Ursprungsmesh meinst und mit "Patch-Kanten" die Kanten des Usrprungsmesh, auch wenn der Algorithmus dort weitere Vertices anlegt.

Wenn die fehlende dritte Kante, die in deinem 2d-Bild senkrecht zur Bildebene stehen würde, eine Gerade ist, haben wir kein Problem. Erst wenn in der dritten Richtung auch eine Verbiegung wirkt geht die gewünschte Eigenschaft in der anderen Richtung _an den Zwischenpunkten_ verloren. In anderen Worten: Wenn die dritte Kante, die wir nicht sehen, verbogen ist, ist diese Verbiegung in Richtung der dritten Kante sehr wohl korrekt, das Problem tritt in der Richtung auf, die wir im Bild sehen. Sozusagen quer zu der Kante.

Oder habe ich es wirklich völlig falsch verstanden?

Und alles was ich zu dem Thema sagen wollte, ist, dass ich intuitiv auch nicht erwartet hätte dass die Eigenschaft bei der gewählen Lösung da erhalten bleibt, und dass mir eben nicht klar war, dass das von Anfang an eure Anforderung war. Oder in deinen Worten:

- "C1-Stetigkeit im Vertex" Das hielt ich für die Anforderung, aufgrund Schrompfs ersten 2d Bildern.
- "wird nicht automatisch zur C1-Stetigkeit der Patch-Kanten," das hatte ich weder als Teil der ursprünglichen Anforderung auf dem Schirm noch erwartet, dass es einfach mit funktioniert.
Es ging also nie um Beleuchtung oder Ästhetik an dieser Stelle;
Wir müssen das jetzt nicht totdiskutieren. Trotzdem vielleicht eine Erklärung woher ich damit komme. Ich bin es gewöhnt zwischen Bug und Missing Feature zu unterscheiden. Ein Bug wäre es für mich wenn man beim gewählten Verfahren erwarten würde, dass die nunmehr fehlende Stetigkeit gegeben ist und es einfach nicht funktioniert. Ein Missing Feature ist, wenn die gewählte und für sich genommen korrekte Implementierung schlicht nicht das hergibt was man will. Dass wir tief im zweiten Fall sind, sieht man meiner Meinung nach schon trivial daran, dass du das Requirement, dass die Ursprungsvertices erhalten bleiben aufgeben willst (eigentlich wahrscheinlich sogar musst) um das andere Ziel zu erreichen.

In meiner Welt, aber wie gesagt, wir müssen das nicht totdiskutieren, ist das eine "Kundenentscheidung", "Designentscheidung" oder wie auch immer du es nennen willst. Es gibt kein internes Apriori-Wertesystem in dem Stetigkeit an den neuen Vertices offensichtlich "besser" ist als das Erhalten der Urspringsvertices. Das _ist_ eine Entscheidung, die man trifft.

Richtig ist sicherlich, dass Schrompf diese Entscheidung lange vor dem Thread getroffen hatte, und ich nur nicht verstanden hatte, dass er das hat. Falsch ist, meiner Meinung nach, dass diese Entscheidung technisch diktiert ist. Es könnte genauso technische Gründe geben, dass die Ausgangsvertices erhalten werden _müssen_.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Zudomon »

Ich finde es auch super, dass hier so angeregt diskutiert wird. Hoffentlich kommt da noch die ein oder andere Idee zustande, die ich dann für StoneQuest nutzen kann.

@Schrompf
Ich bin stolz auf dich, dass du nicht aufgegeben hast! Als ich dein erstes Bezier-Bild mit dem Dreieckssalat gesehen habe, dachte ich, es wird nichts mehr. Aber jetzt sieht dein Ergebnis recht solide aus. Und dein Noise gefällt mir richtig gut! Bin schon sehr gespannt, wie dein Fels in ein paar Tagen aussieht 👍

@joeydee
joeydee hat geschrieben: 11.04.2021, 09:25 [...] entstehen hässliche Verzerrungen an den Ecken und Kanten.
Das ist aber sehr optimistisch, aber so ist es auch in deinem Bild dargestellt.
Eigentlich müsste das Bild aber so aussehen (rote Linie in der oberen Abbildung an dem mittleren Vertex entfernt):
normal_offset_real.jpg
Wenn man davon ausgeht, dass die roten Linien die durch Displacement verschobene Geometrie darstellt...
Jede Unstetigkeit in den Normalen führt dazu, dass die Vertexkoordinaten zu unterschiedlichen Positionen im Raum geschoben werden. Dadurch zerreißt die Geometrie bzw. es entstehen unschöne Lücken.
In 3D ist es natürlich gravierend, wenn dann der Himmel durch die Welt scheint:
20210411_1.jpg
Schrompfs Idee, die Normalen für das Displacement stetig zu konstruieren, ist ein guter Ansatz dem entgegen kommen. Damit bleibt dann die Geometrie trotz Displacements schön bündig.
20210411_2.jpg
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Prozedurale Oberflächen, How-Not-To

Beitrag von Jonathan »

Naja, aber ob die Normalen stetig sind oder nicht hat ja erstmal nichts damit zu tun, ob man die Vertices verbindet oder nicht. In der hübschen 2D-Zeichnung hält einen ja nichts davon ab, auch im oberen Fall die zwei roten Linien miteinander zu verbinden. Desweiteren soll das Displacement ja in der Regel Objekte nicht nur größer machen, sondern ist im Mittel eher neutral (die rote Linie wäre also mal über und mal unter der blauen Linie), und wenn die Texturübergänge passen, dann ist an dem Übergang auch kein harter Sprung. Man sollte dann nur vielleicht darauf achten, dass das Displacement an der harten Kante gleich 0 ist, damit der mittlere blaue Punkt nicht an zwei Unterschiedliche Stellen verschoben wird.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten