Jump to content

Icosphere: 20 sides polyhedron, uv, subdivide, smooth/flat normals


G'kar
 Share

Recommended Posts

Hi all, my first post here.
Just starting to play with babylonjs. So far great tool. Many thanks to all contributors.

For my own experiment, I start to design a new primitive, the IcoSphere (20 triangular sides regular polyhedron)

I share my code with you. Comments are welcome, not sure if it is of interest for others.

Features:
- geometry based on regular polyhedron : 12 vertices, 20 triangular sides
- sub-divide by N support, get 20*N^2 sides to approximate a sphere
- flat/smooth normal: smooth normal are orthogonal to containing sphere surface matching the normal or neighbour faces. flat normal is same for all vertex of face (the face normal)
- uv mapping for texture: the 20 faces are unwrap to a single texture file. This gives low distortion mapping of texture to sphere (unlike standard uv sphere that have strong singulary/distortion around the 2 poles). uv propagate with sub-division.

The result in playground: http://www.babylonjs-playground.com/#1Q6W25
Quick setup to show sequence of sub-divide and flat/smooth setup.
The texture used for playground demo is put as well on the plan below sphere
2 lights are moving around to grab the smooth/flat difference in normals.
Brute force setup with 2 spheres creted (one single visible at a time).
Organized around BABYLON.Mesh.CreateIcoSphere and BABYLON.VertexData.CreateIcoSphere functions

Let me know your feedback ...
G'kar

Link to comment
Share on other sites

Wow!  Great function, great explanation, great playground, well-commented, and on the first forum post here!

 

Nice nice nice, and ... a little more NICE!!!  Yeah, welcome, G'kar! 

 

Boy oh boy, when you make an entry into a room, you don't fool around, do you?  :D  You just attained mini-superhero status... afaic.

 

Don't you ever ever ever leave this forum or this framework, ok? 

 

Quick, somebody build G'kar a mansion to stay-in, and get him ANYTHING HE WANTS!  (including vice)  :)

 

(Wingnut begins buffing G'kar's boots and dusting-off his uniform.)  heh

Link to comment
Share on other sites

If you do a PR, just a suggestion : could you please implement the options signature instead of the list of parameters ?

BABYLON.Mesh.CreateIcoSphere("name", {radius: number, flat: boolean, subdivide: number, updatable: boolean, sideOrientation: number}, scene);

all properties being optional :

BABYLON.Mesh.CreateIcoSphere("name", {}, scene); // this call creates a default IcoSphere

This would be easier for some further hypothetical extension then.

Link to comment
Share on other sites

  • 3 weeks later...

Sa race velue !!!

 

Did you know that Enstein assumed that the light celerity was unsurpassable to establish his Theory of the Relativity ?

This theory works quite well so far to explain many very complex things in the universe.

 

So please, respect this speed limit when coding a new feature in BJS.

 

(I said that because we were just talking about this in PM when he achieved it in seconds)

Link to comment
Share on other sites

  • 2 weeks later...

Hi guys. I didn't have time to react, and the test code is already merged in the project !

Impressive, thanks for the support.

Sorry I didn't keep up your pace. (training on git, typescript, gulp to prepare my contrib in the background, and so no much time available)

Trying to catch up (hopefully).

Updated my bench with current v2.3.0-alpha. The icosphere is still living well :)

 

Now I am back to a question on texture and UV mapping of icosphere:

- first icosphere tentative is using a mapping on the 20 triangle on a square texture. But only 31% of the texture image is actually usefull (big waste IMHO)

- I prepare an improvement to get at least 63% expected usage (remapping UV differently on the texture). Sound worth to give try.

 

The question is about size of texture.

Is the texture size OK to use non power of 2 ?

  No impact on (U,V) that stay in range [0,1], just curious about how to prepare texture file for BabylonJS.

Is it important to use square texture ?

I found different options from different context on the web. I am not sure about the impact for babylonJS (GPU memory cost important). This square/rectangle option would change my approach probably.

 

I can have different approach on my UV layout according to these constraints.

A square texture as power of 2 (like 1024x1024) should be OK anyway (cost a bit more memory may be).

And if a rectangle texture is just rounded to the containing square bitmap under the hood, then no need to optimize at babylon lib level as rectangle.

 

I will give more details and show my code a bit later (not ready yet).

Link to comment
Share on other sites

Hey, this looks awesome!

 

Re: textures, WebGL requires power-of-two sizes, but BJS will convert automatically if you pass it something else. I don't think square/rectangular makes any difference.

 

As for UV mappings, does anyone know if there's a mapping Blender supports for icosphere by default? If so, that would be useful. Otherwise, I think layouts like this are reasonably standard but I'm no expert.

Link to comment
Share on other sites

Thanks for pointing out the BJS code that convert non powerOf2 texture. This mean a real re-interpolation of image take place if an exotic size texture is provided.

Then I will focus on getting a UV texture as square (like 1024x1024).

 

With respect to blender (made my initial experiment of icosphere with blender). I didn't any way to get a default usable UV mapping of icosphere. I had to explicitly add "seams" discontinuities to allow the unwrap to get non distorded uv map. I get something similar to the initial UV map I use for BJS icosphere.

Look like in http://2.bp.blogspot.com/-5v3eTIQvNPg/Vdr_gziEYzI/AAAAAAAADzI/kMZ4nxNVgAU/s1600/d20-grid-ref-texture.png

 

As soon as you instanciate an icosphere in blender, when you unwrap it, you get a set of 20 triangles with defined UV. If you export it to BJS, the icosphere object concept is not there anymore. The triangle with its own UV is exported to BJS (if I am not misunderstood).

So the uv defined in BJS is just usefull if you create the icosphere object directly in BJS (right ?).

 

So your layout : "layouts like this" is a tilt version of my initial one. Good point the containing rectangle is saving about 30 % of unused texture compared to my initial one (use ratio from 31% to ~ 45%). intersting is it fit a 1:2 ration rectangle that could be powerOf2 as well.

 

Then pushing investigation a bit I reached this mapping:

http://1.bp.blogspot.com/-VfCBrerArDo/VkhyVtRTsjI/AAAAAAAAD0E/2T7ScUkiidA/s1600/d20-grid-ref-texture-opt.png

This use 2 islands of connected triangle sets, but reached a use ratio of 63%.

 

In a next step, I could reach better 71% with a 7/8 ratio rectangle

Just by cutting the right side of unused texture (but didn't think it is worth the effort for a marginal gain). And will cost a re-interpolation of texture insidde BJS.

So I will probably stick to square texture (keeping it simple for end user).

Link to comment
Share on other sites

  • 5 weeks later...

... reopen the thread to share more of my experiment on building UV texture for icosphere ...

 

Initially I worked on icosphere to enable mapping texture on sphere without the issue on singularity on the 2 poles of usual sphere.

So now Icosphere only have 1/20 of the spherical surface that is flatten to a triangle on the UV texture. This way the distortion is minimum.

Unfortunately, the drawback is the 20 triangles mapped on the texture do not have contiguous connection with neighbor triangle.

So I wanted to check it is really achievable to craft my own texture to get nice sphere without discontinuity in final rendering.

I outline hereafter how I proceed and share a playground with the result (not so bad).

 

Step 1:

Pick up a 2D texture that fit your taste.

Recommended : best to have texture :

- no specific direction (hatch based texture will be difficult to handle)

- uniform parameter (thing like blur, brightness, ...) when you have to craft the pixel at discontinuous edge to match the neighbour, it will be hard.

In my example, I picked up a stone field

 

Step 2:

Open in bitmap editor : using gimp for that.

I use only square texture (1024x1024 as first test, but 2048x2048 or higher should be OK, smaller as well)

Open the UV texture reference grid as a layer above your texture (to be used to get good idea of where the triangle edge are)

The ref guide with transparent background can be found here:

http://3.bp.blogspot.com/-ICnsyjX3LIs/VnWHB3vAW-I/AAAAAAAAD0Y/dWP5vFQ9U4A/s1600/icosphere-ref-uv-transparent.png

 

 

There is 30 edges on icosphere. 18 are already shared between contiguous triangle on the texture. But 12 are not, these is the issue (using basic texture for direct UV mapping of icosphere without fine tuning the texture gives ugly rendering, where these 12 edges appear as cut lines on the sphere)

So for each edge, I pick a copy of other side with enough pixel overlapping margin, rotate and align on other triangle edge as separate layer. then paint transparent pixel to remove unwanted pixel, following the natural texture boundary (subjective and artistic skill are very helpful here, sorry, do your best ...)

I used the stone boundary as the new artificial border between triangle (not a line so almost invisible in final rendering)

Export the texture to get a rendering inside babylonJS icosphere in your browser give status of progress, and allow to pixel align the overlapping part better).

Ok the process is very experimental, and can probably be optimized/automated, but I want to get a first result to see, so the hand crafting at pixel level in gimp was my solution.

Merge the overlapping texture part with the main texture when happy with the result.

 

Step 3:

Export the final texture to bitmap to be used in the icosphere UV material texture used for icosphere.

I get something like this:

http://1.bp.blogspot.com/-t-JuloAY8hU/VnWHr6W6oOI/AAAAAAAAD0k/hF8wnQ54FKc/s1600/gravel-ico-uv.png

Low res embedded below (256x256)

 

or like this (with the ref guide overlay active):

http://3.bp.blogspot.com/-lO6sxV5x9fk/VnWH5t-98ZI/AAAAAAAAD0w/nfeB3hLW6jk/s1600/gravel-with-ref.png

 

The final texture can be called an "icospherical texture".

 

And the final result in the playground is :

http://www.babylonjs-playground.com/#17XYSP#0

 

At least one edge have 1 or 2 pixel mis-alignment (you need to search a bit in the playground to find it), but otherwise look good enough for me.

Higher resolution and also more consistent blur over all the initial picture would help as well for better quality.

Link to comment
Share on other sites

One more test with earth map.

 

Icosphere UV mapping appear to be very similar to a kind of projection used for earth mapping : Fuller projection or Dymaxion map.

Commented out as : "This view of the Earth minimizes the distortion of size and shape."

A few reference for the curious guys ...

https://en.wikipedia.org/wiki/Dymaxion_map

https://en.wikipedia.org/wiki/List_of_map_projections

https://en.wikipedia.org/wiki/Map_projection

http://odt.org/hdp/

http://odt.org/Pictures/dymaxion.jpg

 

I use this svg :

https://en.wikipedia.org/wiki/Dymaxion_map#/media/File:Fuller_projection_rotated.svg

to convert to bitmap, and re-order triangle to fit the icospherical UV texture format.

(using gimp again for the bitmap processing).

I get a 2048x2048 texture (unintentionally downscaled to 1600x1600 when uploaded to my blog storage) as:

http://2.bp.blogspot.com/-sTvFL0vGFXE/VncKTkHuR7I/AAAAAAAAD1A/vDokBOMvxqk/s1600/Fuller-ico-uv.jpg

 

The final babylonjs render in playground gives:

http://www.babylonjs-playground.com/#17XYSP#1

 

Again, not perfect pixel accuracy for edge alignment, but more or less OK (at least to show the idea).

Would take much more time to really improve it now.

The remaining dotted lines are remnants of only original SVG file I used (please ignore it).

Link to comment
Share on other sites

  • 8 months later...

This is fantastic! I literally jumped into 3D about a week ago.. And I've learned so much from these forums it's insane!

Any chance anyone can shed light on how to apply proper physics to an IcoSphere? I have it running now as a true sphere.. but I'd like it to sort of bump along all these faces when forces are applied.

 

Hope I don't get slapped for resurrecting an old thread :P

Link to comment
Share on other sites

Hi and welcome to BJS forum, we don't do slapping. Nothing wrong about resurrecting an old thread except your question might get lost. Never got round to using physics engines myself but have you considered them? You can search for cannon or oimo in the Q&A forum. Also it might be worth looking at the examples on the home page of BabylonJS, you will find this one.

You also might be better if you start a new topic, you can always reference an old thread within your question if you wish. Including a playground showing what you have got (icoSphere running as true sphere) and being clear about what you want always goes down well and get plenty of answers.

Good luck and here's hoping you become a BJS forum regular.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...