I want to make a flat world, but i want to split it into pieces which will load in segments (for better optimization), and when you are at the end of map it will start loading segments from the beginning again. And I want to make an illusion of roundness (only optical effect if possible). For example, when you watch ships on the horizon, you see their masts first.

I'm asking only for theoretical ideas, so you don't need to send any scripts.

  • 1
    \$\begingroup\$ Something like youtube.com/watch?v=_kY4v-L3rvY ? Uses shaders to present a flat environment as curved. \$\endgroup\$
    – fadden
    Feb 25, 2016 at 18:26
  • \$\begingroup\$ There was an old game that I use to play called Populous 3 that had round worlds. They would tile a rectangular map around the world so that the tops and sides of the rectangle would connect (even though it is impossible to wrap a rectangle around a sphere in this way). It was a very clever illusion and they pulled it off very well. \$\endgroup\$
    – JSideris
    Feb 28, 2016 at 20:06
  • \$\begingroup\$ Thanks, but for me is vertex shader better option. \$\endgroup\$ Feb 28, 2016 at 21:56

1 Answer 1


You can do this purely in a vertex shader. You'd want to apply this shader to everything you render.

One trick though that you can do is weight it so that the nearby objects are flat out to say 100 meters. I'd recommend this because in an FPS game the distortion on objects requires you to change things. (Players will aim at things wrong). If you keep the nearby regions flat then start the curve at a distance it'll look the same without having interaction problems.

Here's an image to understand. (I don't have the code at the moment on this machine, but it's only a few lines if I remember correctly).

enter image description here

Since you asked for code. I can't vet this code 100%, but I did see images of it working. (I wrote pseudocode for a friend who converted it to HLSL and the images showed it working).

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);
  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;

  output.normal = input.normal;

  return output;
  • \$\begingroup\$ Thanks a lot. Is it called somehow? So i can look for code on my own. \$\endgroup\$ Feb 25, 2016 at 19:21
  • \$\begingroup\$ It'll be a few hours until I get home. In the mean-time here's another image: i.imgur.com/RKzQifZ.png This one shows the regions that require loading based on the maximum height a camera can get to. Also en.wikipedia.org/wiki/Tangent_lines_to_circles \$\endgroup\$
    – Sirisian
    Feb 25, 2016 at 19:47
  • \$\begingroup\$ @T.Růžička I updated with the only code sample I have in my old notes. I hope it helps. \$\endgroup\$
    – Sirisian
    Feb 26, 2016 at 8:50
  • \$\begingroup\$ Thaks, it helped \$\endgroup\$ Feb 26, 2016 at 8:54
  • \$\begingroup\$ Do you know how to use it in Unity please? \$\endgroup\$ Mar 1, 2016 at 13:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .