Geometry and Compute Shaders

Hmm, I suppose it would be best to find out first is someone haven’t already done it before & talk with core devs regarding contributions.

Also, if your goal is volumetric clouds, will not offscreen Framebuffer + Texture fullfill your needs? That’s what I do in SevenSky volumetric clouds implementation and it requires GL 2 only I think.

I am sure I could achieve a similar look as the project I linked without a compute, but I doubt I would get the same frame rate if I use a fragment shader.

Can anyone from the core team comment on this? @jayfella @pspeed

I don’t know much about the compute shader work already done… I know folks have managed to use it before but I don’t know how much tweaking that they had to do to the engine.

Can’t say I know a great deal about it either if I’m honest. I’ve not come across a need for it yet.

All that being said, those volumetric clouds look really sweet and it would be great to see them in JME. :slight_smile:


I don’t know much about compute shaders. So far my experience is limited to issue 1045.

After some research, I think I am going to stick with a fragment shader and try to follow this approach:

@The_Leo I am checking out SevenSky now. I see your fragment shader CloudVolume.frag. Is that what you are referencing? I don’t see an example of volume clouds, just 2d clouds.

Check CloudPost.frag, here is the link
At line 700 starts the integration process.

@The_Leo ah ok. Excellent! I am trying to mimic the lighting from this talk. I think will need to introduce the 3 phase light scattering that is discussed around 16:35

1 Like

I will be watching your progress very closely… volumetric clouds have been on my to-do list forever.

I understand the math much better than I get all the shader tricks, but I am making some progress. I am using this project as an example and trying to implement the ray march. ( As you can see, the FPS is not great, but the code is pretty hacky at the moment. (Just slapped into SevenSky for testing)

I also got the book Physically Based Rendering for the holiday, so we’ll see where this goes…


Here is a pic of SevenSky:

Isn’t this one implemented in CloudPost.frag, lines 707-709 ?

700: for(int i = 0; i < steps; i++) {
701:	//float v = cnoise(p * 0.1)*wmap(p);
702:	//float density = noisee(p);//map2(p);
703:	float density = Density(p);
704:	//vec3 Light = Sunlight(p);
706:	if(density > 0.0){
707:        float extinCoeff = ExtinctionFactor*density;
708:        float T = exp(-extinCoeff*add);
709:        vec3 Light = Sunlight(p)*(phase*(1.0-exp(-extinCoeff*add*2.0)));

I’ll tell you the similarities/difference between the implementation in the video you posted and SevenSky implementation:
The implementation in video:

  • uses 2 noise textures to create cloud shape
  • uses top down weather map
  • uses at most 120 samples, switches from cheap sampling to expensive sampling when cloud is found
  • for each expensive sample in cloud does another 6 density samples towards the sun
  • thus theoretical worst case would be 120+120*6 = 840 samples per ray

SevenSky implementation:

  • uses 1 noise texture to create cloud shape, second one is commented out (CloudPost.frag, line 419)
  • uses top down weather map
  • uses at most 16 samples
  • does not sample towards the sun, but for additional detail you can do this, check CloudPost.frag, line 478, where integration towards sun is commented out
  • theoretical worst case: 16 samples per ray

Not exactly. Looks like you have scattering phase, but the light model in that video has beer lambert (Out Scattering) and In scattering to give those dark edges. There are also some other techniques, but the three main ones are those.

The project I linked has a very good example this and I borrowed heavily from it to modeify CloudPost.frag to create more realistic looking clouds. I adjusted line 709 to calculate the light using all three functions.

Below is the result:

I did not add any other texture samples, just light calculations. As you can see, the edges are not blended well with the background. I changed the blend mode of cloudPost material to alphaAdditive and the result is more pleasing:

I think there is still a good amount of progress to be made, but I have happy with the results so far. If you would like to integrate what I have done into sevenSky, I would be happy to share.


That image is really pretty.

…but the clouds look inverted somehow… like they are backwards sorted or something.

The first image has two cloud layers, and the high clouds are not blending at all with the volume clouds. I’m still experimenting with premultiplied blend mode.

The second image is closer, but I agree, something isn’t quite right.

This is what I see:

1 looks like it’s in front of 2… but it feels like it should be behind 2.

I don’t know enough about how these are being rendered… if these were quads, I’d say they were rendered/sorted in the wrong order.

Looks like this sky system is using full screen quad. I am not sure why the sky system is using an inverted projection matrix. I will have to dig into SevenSky

Geometry skypost = createFullScreenQuad(cam.getWidth() / (float) cam.getHeight(), cam.getProjectionMatrix().invert());

Here is a shot with the above invert() removed on the quad. Not sure if it is different. What do you think?

To me, it still feels like we are looking at the tops of the clouds and not the bottoms:

Or here, maybe this is clearer. If you saw this next pic on its own without context, would you think we were flying above the clouds or standing on the ground below them?

Ok, yeah. It’s much more clear looking at that snippet. Also, comparing these images against the GitHub project images of the reference project.

I wonder if I messed up the in-scattering function or if it’s a draw issue. I’m leaning towards the former. I’ll have to keep working on it.

1 Like

It’s looking really good. I wrote a patch that roughly implemented compute shaders in jme. Would you be interested in that? It was a really long time ago but I think it would still work…

1 Like