Freeciv-Web WebGL/Three.js prototype

Web version of freeciv. Please mention the site you're using, if speaking things other than general freeciv-web codebase.
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

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/ ... ript/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.
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Re: Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

Update on the progress: I've now added a better method for rendering the terrain using WebGL fragment shaders.
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Re: Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

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.
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Re: Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

The WebGL prototype can be tested here.
louis94
Hardened
Posts: 270
Joined: Thu Apr 25, 2013 10:17 pm
Location: Belgium

Re: Freeciv-Web WebGL/Three.js prototype

Post by louis94 »

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
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Re: Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

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: 270
Joined: Thu Apr 25, 2013 10:17 pm
Location: Belgium

Re: Freeciv-Web WebGL/Three.js prototype

Post by louis94 »

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
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Re: Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

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: 270
Joined: Thu Apr 25, 2013 10:17 pm
Location: Belgium

Re: Freeciv-Web WebGL/Three.js prototype

Post by louis94 »

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
AndreasR
Elite
Posts: 755
Joined: Thu May 02, 2013 10:26 pm

Re: Freeciv-Web WebGL/Three.js prototype

Post by AndreasR »

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.
Post Reply