Unity asteroid shader documentation

Material shader (asteroid.shadergraph)

This shader gives the sphere a highly detailed asteroid appearance. It is recommended to use subdivided enough icosphere geometry for body as its vertices are displaced during rendering and rest of mimic is done by normal mapping. Resulting height map is sum of base heightmap and random heightmap generated by shader. Normals for base heightmap are calculated during rendering based on heightmap. Normals for generated heightmap are calculated approximately by shader and combined with the base heightmap normals.

Albedo - Cubemap with albedo of body.
Tint - Overall color of body.
Heightmap - Base heightmap of body (grayscale cubemap).
Range - Base heightmap scale.
Metallic - Metalic parameter of body.
Smoothness - Smoothness parameter of body.
Denoise - Level of denoising when rendering surface at angle (tradeoff between normals strength/scale and visual artefacts). Depends on render scale (URP settings). Weakens normals based on surface angle inside camera coordinate system.
Start octave - scale of first level of generated noise.
Seed - Random generator seed, changes generated heightmap and normals for body. (0.000..100.000)
Use mesh normals - denoise is based on the normals in camera coordinate system. For lowpoly icosphere it can give better results for precalculated vertex displacement and recalculated normals. This parameter lets mix normals calculated by shader (for highly detailed geometry) and normals of used mesh. Influences only denoising, not needed if icosphere is highly subdivided.

Compute shader (asteroid.compute)

Computes displaced position of surface and normal for sphere points (normalizes points in input array before applying height). Requires _TexHeightmap (greyscaled cubemap), _StartOctave (int), _Range (float) and _Seed (float in range 0.000 .. 100.000). Their meaning is the same as for the material shader.

Script (stones.cs)

Generates collider mesh if MeshCollider component is attached to scene node. Adjusts vertex positions and normals if Use mesh normals is checked. Generates rocks all over the surface of body if rock prefab is present in the corresponding slot (pyramid-like prefab can be used to visualize asteroid normals in positions of rock instances). Values of shader parameters should be the same as values of material parameters to obtain same surface otherwise rocks will be placed above or under the surface.

stonePrefab - prefab for stone
computeShader - asteroid.compute
cubemapHeightmap - grayscale heightmap cubemap
StartOctave, Range, Seed - should be equal to material ones
Use mesh normals in the script displaces geometry of mesh and recalculates mesh normals at Start() to make correct normals for shader’s Use mesh normals and therefore requires read/write flag for the mesh to be set in import parameters if turned on. Rocks can also be above or under the surface if asteroid geometry is not subdivided enough or if rocks are too small because mesh geometry can’t be exactly aligned to resulting heightmap.

Usage

Import subdivided enough (> 6 times) icosphere (more is better for appearance and worse for performance). Create material based on material shader. Apply material to icosphere, select required cubemaps (bigger values on heightmap mean lower places on body so that abcence of base heightmap wouldn’t shrink body) and adjust material parameters. You can optionally attach stones.csscript to scene node if you want to use some of its functionality and/or mesh collider component. If so make sure that values of parameters that define body variant (Cubemap heightmap, StartOctave, Range, Seed) are the same as values of material parameters and select asteroid.compute as compute shader for script. Render scale equal to 1.5..2 (in URP settings) lets you adjust denoiser to lower values without too much visual artifacts.

Video tutorial

Requirements

Shader is rather lightweight, it runs in 1366x768 resolution on Intel HD Graphics 520.

TODO:

  • Find another way to lower visual artifacts to avoid loss of detail
  • Make use of tesselation