Page 1 of 6

Freeciv-Web WebGL/Three.js prototype

Posted: Sun Oct 23, 2016 4:21 pm
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.

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Sat Oct 29, 2016 2:02 pm
by AndreasR
Update on the progress: I've now added a better method for rendering the terrain using WebGL fragment shaders.

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Mon Nov 07, 2016 6:32 pm
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.

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Tue Nov 08, 2016 7:27 pm
by AndreasR
The WebGL prototype can be tested here.

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Thu Nov 10, 2016 12:43 am
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

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Thu Nov 10, 2016 4:59 am
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

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Thu Nov 10, 2016 12:06 pm
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

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Thu Nov 10, 2016 7:47 pm
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?

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Fri Nov 11, 2016 3:20 am
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

Re: Freeciv-Web WebGL/Three.js prototype

Posted: Fri Nov 11, 2016 5:00 am
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.