tentone / geo-three

Tile based geographic world map visualization library for threejs
https://tentone.github.io/geo-three/docs/
MIT License
728 stars 119 forks source link

How to implement custom map nodes #4

Open farfromrefug opened 3 years ago

farfromrefug commented 3 years ago

I got your lib to run in my very specific mobile env and first thank you for that! Your GPU height shader is pretty awesome!

Now the aim of my project is to get something like PeakFinder. i already have the Three JS post processing effect using https://github.com/OmarShehata/webgl-outlines (which i need to change i guess to be able to use your height shader).

Thanks

Screenshot 2021-04-28 at 15 08 24
tentone commented 3 years ago

Hello

The TileProvider is just used to acess tiles by their coordinates it should be fairly simple create a tiler provider that does not return anything (to save on processing).

The LOD Control is responsible for deciding when to subdivide or simplify the tiles, im currently working on a system based on CancelablePromises to solve the problem that you are facing where you need to wait for intermediate tile level instead of going directly to the final LOD level.

Thanks a lot for your questions.

Cheers

farfromrefug commented 3 years ago

@tentone thank you :D are you in the three discord? maybe we could chat a bit more there. Would love to help you on that lib. Could really help me get the end result of my oss project

tentone commented 3 years ago

No, but feel free to ask for help anytime here on github.

Cheers

farfromrefug commented 3 years ago

@tentone thanks so i ll ask :P 1/ I have looked at how to not using a "texture" on the 3d terrain but it was possible as is. The idea was to override the MapNode to not fetchTile in loadTexture and directly set textureLoaded and call nodeReady. No big deal as i think i will have to my own MapNode anyway. Which makes me ask: could you add a way to use a custom MapNode?

2/ i am trying to compute the normals in the vertex shader of MapHeightNodeShader. The idea is to render MapHeightNodeShader like MeshNormalMaterial (i need a normalBuffer for a post effect). as you see i am not there yet. Screenshot_1619630983 I have done something like this: But something seems wrong with my dz computation Would you have any idea on how to do that ?

EDIT: actually got it. Need to handle tiles borders now

var vertexShader = `
    varying vec2 vUv;

    uniform sampler2D heightMap;
    varying vec3 vNormal;

    float getElevation(vec2 coord, float bias) {
        // Convert encoded elevation value to meters
        vec4 e = texture2D(heightMap, clamp(coord, 0.0, 1.0));
        return ((e.r * 255.0 * 65536.0 + e.g * 255.0 * 256.0 + e.b * 255.0) * 0.1) - 10000.0;
    }

    void main() 
    {
        vUv = uv;

        // queried pixels:
        // +-----------+
        // |   |   |   |
        // | a | b | c |
        // |   |   |   |
        // +-----------+
        // |   |   |   |
        // | d | e | f |
        // |   |   |   |
        // +-----------+
        // |   |   |   |
        // | g | h | i |
        // |   |   |   |
        // +-----------+

        // vec4 theight = texture2D(heightMap, vUv);
        ivec2 size = textureSize(heightMap, 0);
        float offset = 1.0 / 256.0;
        float a = getElevation(vUv + vec2(-offset, -offset), 0.0);
        float b = getElevation(vUv + vec2(0, -offset), 0.0);
        float c = getElevation(vUv + vec2(offset, -offset), 0.0);
        float d = getElevation(vUv + vec2(-offset, 0), 0.0);
        float e = getElevation(vUv, 0.0);
        float f = getElevation(vUv + vec2(offset, 0), 0.0);
        float g = getElevation(vUv + vec2(-offset, offset), 0.0);
        float h = getElevation(vUv + vec2(0, offset), 0.0);
        float i = getElevation(vUv + vec2(offset,offset), 0.0);

        const float NormalLength = 0.001;

        vec3 v0 = vec3(0.0, 0.0, 0.0);
        vec3 v1 = vec3(0.0, NormalLength, 0.0);
        vec3 v2 = vec3(NormalLength, 0.0, 0.0);
        v0.z = (e + d + g + h) / 4.0;
        v1.z = (e+ b + a + d) / 4.0;
        v2.z = (e+ h + i + f) / 4.0;

        vec3 transformed = position + e * normal;
        vec3 worldNormal = normalize ( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );

        vNormal = (normalize(cross(v2 - v0, v1 - v0)));
        gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);
    }`;
farfromrefug commented 3 years ago

@tentone got most of what i need running. Still need to fix the normals are they are wrong on the "ground"

Screenshot 2021-04-29 at 12 25 07

Now i had to make some changes to your lib to make it work (to allow more customisation). Are you ok with me creating PR with those?

tentone commented 3 years ago

Yes please go ahead open a PR with your solution for custom map nodes.

I was starting to work on something too allow external implementation of MapNodes but probablt you already have something that can be used.

farfromrefug commented 3 years ago

@tentone ok will do. One question. is there any point where the childrenCache would be removed? If i look correctly at the code it wont. Wouldn't kill memory at one point? Would be nice to have a way to "destroy" meshes if they are far away

EDIT: @tentone you can see What i have so far at https://farfromrefug.github.io/geo-three/examples/

tentone commented 3 years ago

@farfromrefug

The childcache has no mechanism for removing them currently. I want to introduce a mechanism for this eventually.

Your code seems quite nice 👍 Feel free to open PR maybe can be used as an example of custom nodes.

I will finish today the new mechanism for custom nodes and provide a simple example

farfromrefug commented 3 years ago

@tentone i made a lot of progress in my demo here https://farfromrefug.github.io/geo-three/examples/index.html. got almost everything working. Now i made quite a lot of changes that you can see here https://github.com/farfromrefug/geo-three/commits/master (tried to separate everything in understandable commits):

I have not made PRs yet cause i think it would be better for you first to look at one i have done a bit. If you like something i can make PR and change things to your liking

tentone commented 3 years ago

It would be cool if you could share those examples, they seem quite nice we can add an example page to the library.

Thanks a lot once again!

farfromrefug commented 3 years ago

@tentone when you say examples you mean the classes for LOD and and Nodes? or the example app using all that?

tentone commented 3 years ago

Just the classes should be enough, i think we can add some running examples based on these.

Should be of help to other people trying to achieve similar goal ;)