Wie macht man eine Illusion von einer runden Welt?

7

Ich möchte eine flache Welt erstellen, aber ich möchte sie in Teile aufteilen, die in Segmente geladen werden (zur besseren Optimierung). Wenn Sie sich am Ende der Karte befinden, werden die Segmente wieder von vorne geladen. Und ich möchte eine Illusion von Rundheit machen (wenn möglich nur optischer Effekt). Wenn Sie beispielsweise Schiffe am Horizont beobachten, sehen Sie zuerst deren Masten.

Ich frage nur nach theoretischen Ideen, daher müssen Sie keine Skripte senden.

T. Růžička
quelle
1
So etwas wie youtube.com/watch?v=_kY4v-L3rvY ? Verwendet Shader, um eine flache Umgebung als gekrümmt darzustellen.
Fadden
Es gab ein altes Spiel namens Populous 3, das runde Welten hatte. Sie würden eine rechteckige Karte um die Welt kacheln, so dass sich die Oberseiten und Seiten des Rechtecks ​​verbinden würden (obwohl es unmöglich ist, ein Rechteck auf diese Weise um eine Kugel zu wickeln). Es war eine sehr kluge Illusion und sie haben es sehr gut geschafft.
JSideris
Danke, aber für mich ist Vertex Shader eine bessere Option.
T. Růžička

Antworten:

10

Sie können dies nur in einem Vertex-Shader tun. Sie möchten diesen Shader auf alles anwenden, was Sie rendern.

Ein Trick, den Sie tun können, ist es, es so zu beschweren, dass die Objekte in der Nähe auf 100 Meter flach sind. Ich würde dies empfehlen, da in einem FPS-Spiel die Verzerrung von Objekten erfordert, dass Sie Dinge ändern. (Spieler werden auf falsche Dinge zielen). Wenn Sie die nahe gelegenen Regionen flach halten, beginnen Sie die Kurve in einem Abstand, der ohne Interaktionsprobleme gleich aussieht.

Hier ist ein Bild zu verstehen. (Ich habe den Code im Moment nicht auf diesem Computer, aber es sind nur ein paar Zeilen, wenn ich mich richtig erinnere).

Geben Sie hier die Bildbeschreibung ein

Da hast du nach Code gefragt. Ich kann diesen Code nicht zu 100% überprüfen, aber ich habe gesehen, dass Bilder davon funktionieren. (Ich habe einen Pseudocode für einen Freund geschrieben, der ihn in HLSL konvertiert hat, und die Bilder haben gezeigt, dass er funktioniert).

cbuffer matrix_buffer
{
  matrix world;
  matrix view;
  matrix projection;
};

struct vertex_input_type
{
  float4 position : POSITION;
  float3 normal : NORMAL;
};

struct pixel_input_type
{
  float4 position : SV_POSITION;
  float3 normal : NORMAL;
};

pixel_input_type vertex_shader(vertex_input_type input)
{
  pixel_input_type output;

  input.position.w = 1.0f;

#if 0
  output.position = mul(world, input.position);
  output.position = mul(view, output.position);
  output.position = mul(projection, output.position);
#else
  float4 viewPosition = float4(0, 20.0, 0, 1);
  float seaLevel = 0.0;
  float4 vertex = input.position;
  matrix model = world;
  float radius = 900.0;

  vertex = mul(model, vertex);
  float2 diff = vertex.xz - viewPosition.xz;
  float angleX = -length(diff) / radius;
  float angleY = atan2(diff.x, diff.y);
  float3x3 rotateX =
  {
    1, 0, 0,
    0, cos(angleX), -sin(angleX),
    0, sin(angleX), cos(angleX)
  };
  float3x3 rotateY =
  {
    cos(angleY), 0, sin(angleY),
    0, 1, 0,
    -sin(angleY), 0, cos(angleY)
  };
  vertex = float4(mul(rotateY, mul(rotateX, float3(0, radius + vertex.y - seaLevel, 0))) + float3(0, -radius, 0), 1);
  vertex = mul(projection, mul(view, vertex));
  output.position = vertex;
#endif

  output.normal = input.normal;

  return output;
}
Sirisian
quelle
Vielen Dank. Wird es irgendwie genannt? So kann ich selbst nach Code suchen.
T. Růžička
Es wird ein paar Stunden dauern, bis ich nach Hause komme. In der Zwischenzeit ist hier ein weiteres Bild: i.imgur.com/RKzQifZ.png Dieses zeigt die Regionen, die geladen werden müssen, basierend auf der maximalen Höhe, die eine Kamera erreichen kann. Auch en.wikipedia.org/wiki/Tangent_lines_to_circles
Sirisian
@ T.Růžička Ich habe mit dem einzigen Codebeispiel aktualisiert, das ich in meinen alten Notizen habe. Ich hoffe, es hilft.
Sirisian
Danke, es hat geholfen
T. Růžička
Wissen Sie bitte, wie man es in Unity benutzt?
T. Růžička