Freeciv-Web WebGL/Three.js prototype

Web version of freeciv at play.freeciv.org
User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Sun Oct 23, 2016 4:21 pm

Screenshot as of January 21:
Image

Screenshot as of January 16:
Image

I've started (again) on a WebGL/Three.js prototype for Freeciv-web. I think that a 3D version of Freeciv-web is now possible. Anyone is welcome to help with the development of the WebGL version on Github. (Note that this screenshot is no indication of how the final result will look like, it is just a prototype to demonstrate that WebGL can render something remotely like a Freeciv map).

The code can be found here: https://github.com/freeciv/freeciv-web/tree/develop/freeciv-web/src/main/webapp/javascript/webgl

The WebGL prototype can be tested here.
Last edited by AndreasR on Fri Jan 20, 2017 11:31 pm, edited 14 times in total.

User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Re: Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Sat Oct 29, 2016 2:02 pm

Update on the progress: I've now added a better method for rendering the terrain using WebGL fragment shaders.

User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Re: Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Mon Nov 07, 2016 6:32 pm

Update: I have completed some code to render the map with a heightmap and use the shader to shade the terrain. Also note the small settler model on the map there.

User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Re: Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Tue Nov 08, 2016 7:27 pm

The WebGL prototype can be tested here.

louis94
Hardened
Posts: 225
Joined: Thu Apr 25, 2013 10:17 pm
Location: Belgium

Re: Freeciv-Web WebGL/Three.js prototype

Postby louis94 » Thu Nov 10, 2016 12:43 am

Hello,

Let's add a specular component, ambient occlusion and fade out underwater terrain:
New fragment shader.jpeg

(complete vertex shader)

Code: Select all

varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
varying vec3 vPosition_camera;

void main()
{
  vUv = uv;
  vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
  gl_Position = projectionMatrix * mvPosition;
  vPosition_camera = gl_Position.xyz;
  vNormal = normal;
  vPosition = position;
}

(changes to fragment shader)

Code: Select all

// At global scope:
varying vec3 vPosition;
varying vec3 vPosition_camera;
// End of main():
  float x = clamp((vPosition.y - 30.) / 15., 0., 1.);
  vec4 Cb = texture2D(beach, vec2(vUv.x * 50.0, vUv.y * 50.0));
  c = Cb.rgb * (1. - x) + c * x;

  vec3 light = vec3(0.8, 0.6, 0.7);
  light = normalize(light);

  float dProd = dot(vNormal, light);
  float shade_factor = 0.4 + 0.6 * max(0., dProd);
   
  vec3 ambiant = vec3(0.27, 0.55, 1.);
  float ambiant_factor = 0.075 * (vPosition_camera.z - 550.) / 400.;
  gl_FragColor.rgb = (1. - ambiant_factor) * c * shade_factor + ambiant * ambiant_factor;
}

Of course all magic numbers are tunable :-)

Louis

User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Re: Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Thu Nov 10, 2016 4:59 am

Thanks for the contribution, Louis. With your change, this is starting to look very nice!
I have committed your change to Github. Could you please check that the change was correct? Feel free to post more suggestions or code changes. I can help you if you need any help setting things up.

I wonder, do you think I should use the 3D units from Cimpletoons, or render the 2D units from Amplio2 tileset onto 2d rectangles on the 3d map?

Also, do you have any suggestions about how to render the beach?

Andreas

louis94
Hardened
Posts: 225
Joined: Thu Apr 25, 2013 10:17 pm
Location: Belgium

Re: Freeciv-Web WebGL/Three.js prototype

Postby louis94 » Thu Nov 10, 2016 12:06 pm

AndreasR wrote:Thanks for the contribution, Louis. With your change, this is starting to look very nice!

Could you please check that the change was correct? Feel free to post more suggestions or code changes. I can help you if you need any help setting things up.

The change is correct :) Currently I'm just playing with the debugger. Maybe I'll end up install Vagrant… I'll let you know if I have any problem doing it.

I wonder, do you think I should use the 3D units from Cimpletoons, or render the 2D units from Amplio2 tileset onto 2d rectangles on the 3d map?

2d Amplio units facing the camera might look nice in the beginning, but I think we'll want real 3d models in the long run.

Also, do you have any suggestions about how to render the beach?

I tested something along these lines yesterday, it looked good enough except on tiles surrounded by >= 3 oceans. Put it above yesterday's code.

Code: Select all

if (vPosition.y < 53. && vPosition.y > 49.) {
  vec4 Cb = texture2D(desert, vec2(vUv.x * 50.0, vUv.y * 50.0));
  c = Cb.rgb;
}


Louis

User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Re: Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Thu Nov 10, 2016 7:47 pm

Thanks for the idea for how to render beaches. I have committed an update and released it to the production server. Do you have more ideas about how to make it look more realistic? For example, how do we get tile edges to blend smoothly?

louis94
Hardened
Posts: 225
Joined: Thu Apr 25, 2013 10:17 pm
Location: Belgium

Re: Freeciv-Web WebGL/Three.js prototype

Postby louis94 » Fri Nov 11, 2016 3:20 am

AndreasR wrote:Thanks for the idea for how to render beaches. I have committed an update and released it to the production server.

I saw it already :D I tried running the server using vagrant but it uses way too much memory… with the computer swapping plus build.sh and F5 being slow, it wasn't as fun as I expected :(

AndreasR wrote:Do you have more ideas about how to make it look more realistic?

I wouldn't be able to make it photo-realistic (and I don't think it would be a good thing).
I think the heightmap could be smoother on the coast and sharper near mountains. In fact I have the following formula in mind:

Code: Select all

average_tile_height = medium_factor * distance_to_sea + big_factor * terrain_modification + small_factor * mean(terrain_modification of neighbouring tiles)
where terrain_modification is medium for hills, big for mountains and small negative for sea. It's just a guess, I didn't test it…

Cast shadows from mountains would add up to realism, but it's difficult to do. Trees in forests would be great ;)

AndreasR wrote:For example, how do we get tile edges to blend smoothly?

If you mean avoiding the green lines between tiles, I think they are due to multisampling when accessing the map texture. I wasn't able to improve the quality by rounding the UV coordinates (all I could get is uglier aliased lines…). A solution would be to pass the correct UVs (computed in JS) through the vertex shader. Add a few additional pixels around the textures to avoid problems with multisampling near the borders.

Louis

User avatar
AndreasR
Elite
Posts: 701
Joined: Thu May 02, 2013 10:26 pm
Location: Norway

Re: Freeciv-Web WebGL/Three.js prototype

Postby AndreasR » Fri Nov 11, 2016 5:00 am

How much memory do you have? You can modify the amount of memory allocated to the virtual machine by changing v.memory in the Vagrantfile file. If you get swapping, then reduce it.

There is a script called build-js.sh which builds the JavaScript only, and is quite fast. If you have modified the shader, then copy the file to the tomcat directory in /var/lib/tomcat/webapps.