I’ve been wanting to try this out for a while so I experimented a bit. I’m pretty sure this is quite doable with the right material. That being said, you may not consider this solution quick or sensible I created some materials and summed up my thoughts below. It’s by no means a perfect solution and could use a lot of work, but it may be suitable from a distance. Hopefully what I’ve written below is a good jumping off point to help you build what you need.
I created a material that adds procedural windows to tilesets. It’s pretty rough and could be improved in a lot of ways.
Here it is on the Denver tileset:
And here it is on OSM buildings:
Note that in my scene I have an additional directional light with an intensity of 0.4 lux - this might be a moon or other ambient light, but you’ll probably want at least one light source to turn on at night.
There is also a Post Process Volume with these exposure settings:
The Post Process volume is set to Infinite Extent. The Post Process volume is important for controlling the automatic exposure of the scene to make sure it isn’t too bright or too dark. You can read more about post processing volumes with Cesium here.
Procedural window material details
This material is largely based off of the grid material in the Cesium for Unreal Samples. That material creates a grid based on world position. The window material will do something similar, but inverted.
The Cesium for Unreal Material Editing tutorial might be helpful if you’re looking to learn more about material concepts with Cesium for Unreal.
The material instance is very simple. It uses a custom Material Layer and Material Layer blend, which are explained below. The Material Layer has a lot of parameters that can be tweaked to adjust the look and size of the windows.
Modifying WindowBrightness would let the windows appear to fade in over time, though depending on the light levels of your scene, you might not even need to animate this.
The material is a modified version of ML_CesiumGrid found in the Samples. The parameters you saw on the material instance are defined here. There are three main parts of the layer.
First, the windows are created with a Material Function named MF_Windows (that will be detailed in the next section.)
These nodes allow you to control the brightness and color of the windows. The color could be set to white, but I found yellow was just a better look.
The WorldAlignedBlend node is used to make sure the windows don’t appear on the tops of buildings or on the street. On horizontal surfaces, the window pattern will be replaced with black.
The output of the Lerp node is connected to the EmissiveColor of the material attributes.
MF_Windows is a material function modified from MF_GridLines in the Samples. While MF_GridLines uses only the R and G channels of Absolute World Position for a horizontal grid, MF_Windows also uses the B channel. The R and G channels are multiplied by the WindowProportion input. When WindowProportion is set to 1, the windows will be square. Values lower than 1 will make vertical windows.
It also inverts the grid.
Material Layer Blend
The MLB is pretty straightforward. It multiplies the Emissive color of the Material Layer by the Base Color of the tileset. You could skip that altogether and just connect Emissive Color of Input Top layer directly to Emissive Color of the output, but multiplying by the base color might produce some nice variance.
As mentioned above, there are a lot of ways this could be improved. If you decide to try this out and see how you can improve the material, please let me know how it goes!
Limitations of the procedural window material
- The windows are very uniform. You might be able to get some good variation by multiplying the window effect by noise textures, but it would likely involve a lot of tweaking to get it to look good.
- The material has no awareness of what a building is, so windows might end up in odd places like trees, the sides of hills, and steep roofs.
- The grid is world-aligned and world space. What this means functionally is that depending on the shape and orientation of the building, there may be visual issues like weirdly narrow or wide windows, windows that change shape along the building, or no windows at all. For example:
One building in this image is on a slight slant compared to the world grid, so the left side of it is in a position where the “window padding” is, and appears to fade off. Further to the left, a side of a building is completely inside of the window padding, so no windows render at all.
Photogrammetry might work better or worse with this, depending on it’s LOD and how it is triangulated.
- Faraway windows may create flickering effects due to aliasing.
Lights on the land
You also mentioned wanting lights scattered across the land. One low-res but fairly geographically correct solution could be to use the Earth at Night imagery to drive the emissive channel of a material.
I tested this out and it works ok, but it’s so low res that it might not be useful to you.
You’d need to add a new Ion Raster Overlay to Cesium World Terrain. Set the Ion asset ID to 3812 and the Material Layer Key to the name of the material layer that you’ll be modifying.
From high over Colorado you can see it brightens up the areas near cities.
Up close, it’s not very precise, and some hard edges between pixels are visible.
Material Layer Blend:
I hope this is helpful to you in some way - let me know if you have any further questions on this. I’d love to improve Cesium for Unreal’s night lighting.