Based on the built in ProceduralMesh component, ProceduralIcosphere is built entirely in blueprints for ease of examination and modification.
Why use an Icosphere over a UV sphere? In some cases the difference is semantic, but the Icosphere has a more even distribution of vertices in terms of density of spacing, and the lack of grid symmetry can look better in applications such as terrain or water.
A set of pre-generated static icosphere meshes is provided that can be easily scaled to meet most needs. For use cases where those provided meshes aren’t enough, BP_ProceduralIcosphere can be used. Drop the blueprint in the world, tweak the parameters as appropriate, and save the resulting generated mesh as a static mesh. This should not be done at runtime.
Assorted prebuilt Icosphere meshes, made using this asset
A UV test Material – texture courtesy https://github.com/mrdoob/three.js under the MIT License (https://github.com/mrdoob/three.js/blob/dev/LICENSE)
- Radius – the radius of the sphere in Unreal units. Default is 100.
- Tessellation Level – the number of subdivisions of each triangle face of the icosahedron. 0 is an icosahedron. Default is 2.
- Material – a reference to a material for the mesh. Default is the UV Grid Material Instance.
- Invert Normals – this changes the triangle winding so that the face normal of the sphere point toward the center. Why would you do this? It is useful in certain applications such as skyspheres, or if you want to create a sort of hollow effect.
- Spherize – Pushes the vertices of the icosahedron out to the surface of the sphere the icosphere is approximating. You generally want this turned on, otherwise you just end up with a highly tessellated icosahedron. Default is enabled\
- Fix UVs Zipper – repairs a UV discontinuity running from pole to pole that is created with the base spherical UVs calculated. A vertex in the triangle has a U of 0.9, for example, and another has a U of 0.1, so the entire texture is drawn backwards between them. Disabling this is only suggested if your material is using the vertex UVs and is deforming the mesh, unless your deformation code is guaranteed to keep the duplicated vertices in sync. Default is enabled.
- Fix UVs Polar – repairs a UV issue at the poles that is a side effect of the vertex at the top needing to represent a U coordinate that spans the entire range from 0 to 1. This option creates copies of the vertex and assigns them a U coordinate that is the simple average of the U coordinates of the other two vertices in the triangle. This option introduces hard discontinuities to fix weird swirls and stretching, but often looks better for many textures. Disabling this is only suggested if your material is using the vertex UVs and not deforming the mesh, unless your deformation code is guaranteed to keep the duplicated vertices in sync.
- Polar Tolerance – the amount of error tolerance (slop) allowed when determining which vertices are the north and south poles. This should only need to be adjusted if the sphere has a very small radius. Default is 0.1.
- Show Vert Indices – floats text labels of indices near the vertices, along with some other info, mostly for troubleshooting. Disabled by default.
- Text Distance Offset – adjusts the positioning of the floating text.
Yes, I know doing it in C++ would be faster/better/stronger, and I could use ParallelFor. However, the Blueprint is hopefully easier for users to parse and understand; and this blueprint might serve as a guide to others who would want to build meshes procedurally.
There’s a lot of spaghetti!
Yeah, many operations in Blueprints are far less concise than the equivalent in C++, especially when it comes to arrays or addressing members of structs.
This blueprint makes my game run slow!
The Blueprint should not be left in a production build, especially with a tessellation level >= 3. Drop the Blueprint in the world, set the parameters, use it to generate your sphere mesh once, and then remove it from the world.
Note that the output of the component is intended to be saved to a static mesh for use at runtime.