Jump to content

Multiple Cloud Layers


photo

Recommended Posts

Hi,

 

I'm trying to implement the effect of multiple cloud layers for a flight simulation. Because the airfcraft must be able to transit through each cloud layer, I'm using volumetric clouds.

 

We need to be able to demonstrate 4 cloud layers for certification. Each must have controllable altitude, depth, wind speed/direction and type (e.g. overcast/broken/scattered/few).

 

I've implemented this using 4 'sky object' nodes. However there seem to be some issues (other than performance!). The first is that, although I'm only setting one 'Layer' slider, all 4 sky objects seem to be modified simulataneously. I.e. it doesn't seem to be possible to have overcast cloud at one altitude, and scattered cloud at another altitude at the same time.

 

Am I doing something wrong? What is the best way to create multiple layers of volumetric clouds?

 

Kind regards,

Paul

Link to comment

Hi Paul,

 

Unfortunately, only a single ObjectSky node can be used at once. You can check this forum thread for more suggestions: https://developer.unigine.com/forum/topic/3173-multiple-instances-of-objectsky-for-multiple-cloud-layers/

 

Sorry for the inconvenience caused.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Thanks, silent.

 

I saw that. I have actually found a convenient way of adjusting the draw order so I don't have visual artefacts.

 

The only problem that remains is that when I change the Layer option (selecting the different parts of the mask), this seems to change for all ObjectSky layers. Is this intended/expected behaviour?

 

I'll experiment with VolumeObjects, but there are far fewer parameters to play with to achieve the effects we're looking for.

 

Kind regards,

 

Paul

Link to comment

Experimenting with ObjectVolumeBox and reading the forums, I find there are problems with the visual artefacts created as a result of the box being too large. Ideally we want to have the ObjectVolumeBox the same dimensions as the terrain (e.g. at least 100000m x 100000m). 

 

See: [WONTFIX] Rendering artefact inside fog.

 

This provides 3 possible solutions:

 

1. Increase near/far clipping planes.

2. Use multiple ObjectVolumeBox nodes in a grid.

3. Attach ObjectVolumeBox to the camera.

 

These work fine when it comes to fog, however with multiple cloud layers it's not so straightforward:

 

Option 1. isn't a great solution for us because we need to maintain a consistent 60Hz.

Option 2. presents the problem that clouds would appear and become extinct in an obvious grid.

Option 3. isn't an option because we need to be able to transition between cloud layers - i.e. we need to be able to move the camera wrt the ObjectVolumeBox.

 

The other issue I see is that there does not appear to be an easy way to animate object volume box or materials. This has to be done in the .cpp file I think. Certainly the example (/Samples/Materials/Volume_01/) uses this method.

 

I'd be very grateful to hear your thoughts on how best to create/control multiple cloud layers. 

 

Kind regards,

Paul

Link to comment

I'd be very grateful to hear your thoughts on how best to create/control multiple cloud layers.

 

Hi Paul,

 

it would be helpful to get more detailed information on the actual cloud system requirements (cloud layer count, required cloud types/styles (Cirrus, Cumulus,..), only-flat 2D or full-fledged volumetric 3D, required view distances, static/dynamic cloud texture to simulate regional cloud density variations,..).

 

In general the UNIGINE ObjectSky flat/volumetric cloud implementation might not be really suitable for your complex flight simulation use case. Instead a custom cloud system implementation might be the right approach, in any case I would doubt that you will be able to get convincing/high-performance results for large game worlds just by usage of some ObjectVolumeBox instances (as an example see this old paper on microsoft flight simulator cloud system implementation or some other research work).     

Link to comment

Hi there,

 

I'm just thinking..

Is it possible to change the associated image at runtime? I mean, if we could change the specific image referenced at <density_image>../cloud.png</density_image> for the different layers at runtime, we wouldn't need to used the different layers.

 

Through the editor instance, I get access to the "sky" node, but I'm searching for a way to set the parameters of the node, named as "Mask". I was looking for a method to access the ObjectSky in C++ or casting it if nescessary from the node.

 

Kind regards,

Renato

Link to comment

Thanks, Ulf.

 

The links are helpful.

 

The system we're looking to implement needs to meet the following specifications:

 

1. Must be able to simulate up to 4 cloud layers simultaneously.

2. Aircraft must be able to transit cloud layers (i.e. volumetric)

3. Must be able to set altitudes of top and bottom cloud layers.

4. Must be able to select from 4 cloud types per layer: overcast/broken/scattered/few (and none/off)

5. Must be able to set wind direction (/cloud animation) independently across all 4 layers.

 

The ObjectSky node works really well in all instances, with the exception that changing the cloud layer mask in a single layer affects all 4 layers changing. It seems that there is some sort of bug that results in the superimposition of each mask on top of the previous. This works fine if all layers have the same cloud type, but we cannot (for example) set one layer to overcast and another to scattered. The masks seem to sum the greyscale values of all layers, so all layers display as overcast. 

 

Accurate weather modelling is quite a big issue for use of Unigine in certifiable flight training devices, so we'd really like to find a workable solution. 

 

I've overcome the draw order issue by setting these according to a track. (e.g. 0 = draw order settings below 1st cloud layer, 1 = draw order settings inside first cloud layer, 2 = draw order settings between cloud layers 1 and 2, and so on...) We will then do a basic calculation to determine the altitude of the aircraft wrt the cloud and use this to select the appropriate step in the track. 

 

Please let me know if you need anything further. 

 

Kind regards,

Paul

Link to comment

Hi Renato,

 

I'm not sure I follow. Would you not still need multiple cloud layers to be able to control the altitude/depth of each layer? 

 

Kind regards,

Paul

Link to comment

Regarding gaining access to the 'Mask' - could you do this by exporting the skyobject to an external node reference and replacing the original skyobject node in the editor with it? You could then control the <density_image> in your code by accessing the node referenced (see attached).

hzn_environment.rar

Link to comment

Hi Paul

 

I'd like to keep the four mentioned cloud layer, but instead of using the layer switch from the Nodes->Parameters, I'm looking for a way the dynamically change the associated image at runtime.

 

A possible workaround could also be to provide clouds without different layers. You would there need to create up to 16 ObjectSky's (4 layers with each 4 different styles: few/scattered/broken/overcast) and toggle them on and off. Therefore we wouldn't have to switch between different layer...

 

Unfortunately, adding an external node doesn't helps, since the node class doesn't provides a method to access the <density_image>.

 

Kind regards,

Renato

Link to comment
  • 2 weeks later...

Hi all,

 

I’ve done some further investigation into the behaviour of the ObjectSky for use as cloud layers, as well as VolumeObjectBox. Here are my findings:

Test 1. Single ObjectSky (single cloud layer):
    - Full control over altitude/depth/density/animation/direction/speed/colour/type of cloud. Simple tracks used to provide control over each element/parameter. Solution works.

Test 2. 3 x ObjectSky objects (three cloud layers):
    - Full control over altitude/depth/direction/speed/colour of each cloud layer.
    - Tracks created to control colour according to time of day/weather required.
    - Draw order issues dependent on relative altitude of cloud layer to observer camera (aircraft) - all overcome through the use of draw order/poly offset modifications.

Limitations:
Control of cloud type by layer (i.e. layer 0 = few clouds/layer 1 = scattered/layer 2 = overcast) does not appear to work as expected. With a single ObjectSky node (cloud layer), you would change the cloud layer type by choosing which part of the mask to use on that layer. (See clouds.png - this shows 4 different cloud layer masks representing overcast to few clouds in the same image. By choosing type 0, Unigine selects the bottom 1/4 of the image, by choosing 1, it selects the next 1/4 of the image and so on.)

The problem however is that when you introduce a second cloud layer, Unigine gets confused about what to do with the masks. I have attached a second version of the cloud type layer called ‘clouds_test.png’. This has some readily identifiable formations.

The behaviour observed is that grey values in the masks sum together to form a combined mask which is then used in all layers. Screenshot1.jpg shows the result when the bottom layer uses layer 3 (clear) and the top layer uses type 0 (the cross). We should see no clouds in the lower layer and crossed clouds at the top layer. Instead we see crosses in both cloud layers.

Another example of this is Screenshot2.jpg. This shows the bottom layer cloud type set to 0 (the cross) and the top cloud layer set to type 1 (the circle). As you can see, both the circle and the cross show in both layers.

I have also tried using different images that contain only a single cloud type (see clouds_scattered.png, clouds_few.png, clouds_overcast.png and clouds_broken.png). The behaviour I observed here was that Unigine uses only the mask image on which the type slider was last set. I.e. Unigine acknowledges only a single cloud mask. For example, if I have 2 cloud layers and one uses clouds_test.png, and the other uses clouds_overcast.png, both layers will show the cross if type 0 is set last on the layer using clouds_test.png. It will show overcast on both layers if the cloud type is selected on the layer using the clouds_overcast.png mask.

What this tells me is that in order to use ObjectSky for cloud layers, we would need Unigine to fix the limitations whereby either only a single mask can be used, and where the cloud mask is summed through the different ObjectSky layers.

I have also experimented again with the VolumeBox objects. These suffer from the limitations mentioned in previous posts due to scale and also that the animation can not be set using tools in Unigine - it needs to be coded into the .cpp file.

My conclusion is that, as is, it's very difficult to create multiple cloud layers to a level that could be certified for flight training. In my opinion, objectsky would be the best way to go, if the masks for each layer were treated distinctly.

 

Please could you advise how we should overcome this issue? Without being able to accurately represent multiple cloud layers, we cannot achieve certification for the visual system and without certification, we cannot use Unigine for flight simulation...

 

Thanks and kind regards,

Paul

ELITE_Clouds_Test.rar

Link to comment

It should be noted that the Unigine ObjectSky object has never been designed to be used for creation of multiple volumetric cloud layers, just a single one.

 

I am not fully sure, but on a technical level the described effects might be related to the fact that volume material within ObjectSky currently does not use per-instance texture images (once again not sure if this will already be fully sufficient, but maybe a starting point)

 

engine/objects/ObjectsSky.cpp

void ObjectSky::flush(float ifps) {
....
  // simulate volume
  if((getSimulation() || isEnabled(SURFACE_VOLUME)) && volume_material && volume_material->getShader(RENDER_PASS_AMBIENT,OBJECT_SKY)) {
		
  ....
    int id = volume_material->findTexture("volume");
    if(id != -1) {
	create_clouds();
	if(clouds->update(ifps) && isEnabled(SURFACE_VOLUME)) {
	    const Image *volume = clouds->getCloudsImage();
	    volume_material->setImageTextureImage(id,*volume);  // no per-instance texture,(id, *volume, 1) might solve issue 
	    id = volume_material->findTexture("density");
	    if(id != -1) {
		Image density;
		....
		volume_material->setImageTextureImage(id,density);   // no per-instance texture,(id, density, 1) might solve issue
	    }
	}
     }
  }
  ....
}
Link to comment

In general I think it would be much better to extract the volumetric cloud layer rendering from ObjectSky to some stand-alone ObjectClouds object. The engine should automatically support proper rendering of multiple ObjectClouds instances based on the per-instance parameters and texture images. For larger simulation setups ObjectClouds should support synchronized multi-channel rendering as described in this old post.

Link to comment

Hi Ulf,

 

Thanks very much for your thoughts.

 

Just to be clear, I didn't mean to imply that the use of multiple ObjectSky layers was a failure of meeting specifications - far from it. It makes creating very realistic sky simulations incredibly easy. It's a great feature, which is why I'm so keen to use it multiple times!

 

You're right about our specifications being a little more complex, but a key market for Unigine has to be flight simulation and for the minimum certification (for any simulator over a few tens of thousands of dollars to have value), we must be able to create multiple cloud layers.

 

These needn't all be volumetric, but I'm confident we can maintain the performance with the right system/settings and it would add a huge amount of value for our application (to which Unigine is otherwise almost perfectly suited).

 

Re the code, I did a quick search through the sdk and couldn't find objectsky.cpp. Is that from the source code? (We only have a binary license...)

 

I should also confess, I'm no programmer and I struggle to follow the code (I'd have no idea how to modify it), but using my basic (likely incorrect) understanding, would it be possible to break out the code that selects the texture into some sort of loop for each ObjectSky layer?

 

ObjectCloud and multi-channel sync would be great. In my naivety I'm assuming it would be easiest to modify what's there and might therefore be possible sooner... ;)

 

If objectsky/objectvolume box aren't appropriate, is there some other way we could achieve what we're seeking?

 

Kind regards,

Paul

Link to comment

 

Just to be clear, I didn't mean to imply that the use of multiple ObjectSky layers was a failure of meeting specifications - far from it. It makes creating very realistic sky simulations incredibly easy. It's a great feature, which is why I'm so keen to use it multiple times!

Fully understood, but at the moment this only works by "coincident", as ObjectSky design and implementation implicitely assumes only a single active rendering instance.

 

 

 

You're right about our specifications being a little more complex, but a key market for Unigine has to be flight simulation and for the minimum certification (for any simulator over a few tens of thousands of dollars to have value), we must be able to create multiple cloud layers.

 

That's exactly the reason why it would be helpful, to have a more flexible, multi-instance clouds rendering system implemented in its own ObjectClouds class.

 

 

 

Re the code, I did a quick search through the sdk and couldn't find objectsky.cpp. Is that from the source code? (We only have a binary license...)

 

Yes, its part of the Unigine source code. Provisioning of the above code excerpts was just meant to give Unigine crew some possible starting point for issue investigation.  

 

 

would it be possible to break out the code that selects the texture into some sort of loop for each ObjectSky layer

 

Based on my understanding (which might also be incorrect) the problem is more related to internal texture handling 

 

 

If objectsky/objectvolume box aren't appropriate, is there some other way we could achieve what we're seeking?

 

In older days multiple (flat) cloud layers have been implemented simply by some flat textured polygons with animated cloud layer texures, but of course this is no longer a state-of-the-art approach (maybe except for some cheap high cloud layer effect).

 

For a Level D certified flight simulator I would expect that a customized, much more complex cloud rendering system will be required (e.g. to include some regional variations/masking of cloud layers, storm cells, deterministic replay of cloud states, start/stop of cloud simulation, ..., ...,  ). But this will for sure require specialized low-level C++ render programming (sorry...)

 

Link to comment
  • 4 weeks later...

There were 2 sessions on volume cloud rendering on SIGGRAPH 2015  which might be of interest for your project

The Real-time Volumetric Cloudscapes of Horizon: Zero Dawn
A Novel Sampling Algorithm for Fast and Stable Real-Time Volume Rendering

Some session presentations still missing at the moment, but this might change soon.

Link to comment

Ulf, thank you for the links! Our guys were at that SIGGRAPH last week, but they never had a chance to visit talks because of the UNIGINE booth preparation.

We have planned the sky/clouds improvements for UNIGINE 2.1.

Link to comment
  • 1 month later...

Some session presentations still missing at the moment, but this might change soon.

 

Excellent presentation for The Real-time Volumetric Cloudscapes of Horizon: Zero Dawn is now available showing procedural algorithms and implementation details. Maybe a good inspiration for planned Unigine 2.1 sky/cloud improvements 

  • Like 1
Link to comment
×
×
  • Create New...