Geometry and Compute Shaders

I committed to github. Feedback welcome.

7 Likes

it took minutes, because you use Eclipse and no gradle, but i successfully run it .

found one simple issue in your shader :slight_smile:

how to fix: It work for me only if you add:
#import "MatDefs/Common/Compat.glsllib"
to:
Sky.frag

If i run your raw shader i get(and GLSLCompat solve it):

com.jme3.renderer.RendererException: compile error in: ShaderSource[name=MatDefs/Sky/Sky.frag, defines, type=Fragment, language=GLSL130]
0(39) : error C7533: global variable gl_FragColor is deprecated after version 120

i see you use GitHub - SudoPlayGames/Joise: Joise is a 2D, 3D, 4D and 6D modular noise library written in Java.
(compile “com.sudoplay.joise:joise:1.1.0”)

Apache license is fine too :slight_smile: was afraid it will be something else. (also i understand once finished you will describe texture licenses there - because im unsure from where you have them)

It looks nice :slight_smile: (but im unsure why it dont look exactly like in your examples)

with all filters i use:

But you are right, myself i have 80 FPS on good GPU(almost top tiers in past year) with raw skybox is low FPS i think? so some optimization would be nice.

Is there a way to optimize it by just disabling some features?

Also im not sure, but i see in above image “color scale lines”(or however name it) while in your images i dont see them. But its raw skybox related as i understand so nothing to worry i belive.

And also one question. Why need:
cam.setFrustumFar(400000);
?

cant solve it somehow similar how Skybox is done?
i see you use public Geometry applyQuad;
but im unsure if could be done without setting frustrum far

about g_time i recently received information from Riccardo that after 6 hours it can make artifacts due to accuracy loose, so it would be nice to have new render pipeline new time system applied here too.

And also last thing:

  • How can i change skybox? (i mean how can i customize background behind the clouds).
    initially i thought clouds are on some “transparent Quad” but my original SkyBox is replaced by blue-red blend skybox you have. And as i see you draw it directly on quad? maybe make Quad have just clouds with alpha-blend?

If you know your time will loop then it takes only a few minutes to add this yourself.

The issue with g_Time is that it’s a float. Making it a double (the only way to fix g_Time) would be tricky, I guess.

Until then, 99% of the time the shader is only using some period of g_Time and then it can define its own time parameter that never goes outside of the period (because it wraps outside of the shader).

Hi @oxplay2. Glad it’s working for you. The only way to improve performance easily is to lower the Ray March steps. There are other more involved ways that I plan to implement soon.

About the GL comparability, yes, I see that. I’ll fix that with an update. I copied and pasted everything from the project I’m working on into a new project.

About setFrustrum call, yes that is totally unnecessary. I was testing a very large plane of water in my other code and missed that. I’ll remove that in my next commit.

I won’t have any time to update the readme for a while, but the project I use to generate the textures is this project

I was trying to do that with joise but ran in to some issues that I’m still working through. The cloud shape and erosion textures are the most important thing for how the clouds look. I’d like to provide many different examples. Currently joise is just used for weather map generation.

As far as the look, try removing the phase in the light calculation in clouds.frag. Phase is always tricky and I’m still working on that too. Press 8/9 to add or remove coverage.

You can change sky by modifying the sky shader or just comment out the call to render the sky and do something custom with a dome or skybox. The sky shader I added is nothing great, just there for demo purposes.

As far as the g_time, I plan to implement blending/looping between different weather textures over time so there will eventually be a custom time var that resets periodically.

2 Likes

well light calculation in clouds.frag give nice result :slight_smile: and dont give that much difference in FPS (80 → 100) - so it could be just game option like “cloud quality”.

But when i look at shader, i see there a lot of “if” conditions. Im not shader specialist, but i also heard that if conditions should be replaced/get rid of to make shader work faster (because shader like compile(or something else) for each subcondition?) using clamp/mix/other functions.

Just wanted to say that first time i see shader using 10 if conditions.

The features you want to add sounds great :slight_smile:

soon you will get result like in here(looks like its more about dark/light side of clouds):
(if you will finish lightning work properly :slight_smile: )

2 Likes

Step converts a value to 1.0 or 0.0 - which is basically an if statement you can use in mix or w/e - that’s about 90% of converting if statements to glsl.

The if statement thing is from way back at the beginning of GLSL. I don’t know if jumps are actually a problem anymore on modern cards. It could be that we are just hanging onto vestigial lore. (Shaders use to not support them at all and then you HAD to use step.)

I think even when it’s bad, the bad part is that the shader will execute both branches and figure out which value to use (ie: convert to step internally). So replacing ifs with steps doesn’t necessarily help unless the logic manages to remove some of the work somehow.

I suspect that what @oxplay2 is concerned about with the ‘if’ thing is warp or wavefront divergence. See this post for a brief overview… Don’t know if the concept has a more common name:

(Skip down a paragraph to “why is branching on a GPU a big deal”)

1 Like

Yeah, so it either runs both halves of the branch in parallel or runs both sequentially. But if the work needs doing then the work needs doing.

It also concludes with: "it doesn’t make much sense to try to manually figure out the math to remove the branching ourselves, as the first architecture’s compiler may decide to compile to the second form instead of the faster form. "

So to me it still seems like the case of: go ahead and use branching if you have to but try to avoid it if you really don’t.

In the past, I’ve considered rewriting my trilinear texture stuff to use multiple passes instead of big branches but based on the article that you linked, I think it wouldn’t actually matter in the end.

I’ll have to review the shader but I don’t believe any of the expressions in the ifs vary per frag/vertex either.

1 Like

I tested some and I don’t think branching is a cause of any performance issue. I will need to actually dig deeper with metrics to know for sure. I did half size the framebuffer which improves performance a little but you might be able to notice it. I think it still looks pretty clear and I hardly notice the pixelation.

Updates:

  • Added GLSL compat to sky frag
  • I half sized the frame buffer
  • Blending sky color and ambient light

TODO list

  • better color and lighting blending
  • night colors/stars/moon
  • optimize to render incrementally over many frames (still looking for advice here).

5 Likes

@dreamwagon

Awesome work!

it make for me like 100 → 180 FPS with even better visual result! :slight_smile: :star_struck:

you even added light direction change in test to see how it works.

So i tested it.

But i see one issue, maybe its my GPU related, but i dont had it before.
(its visible only on “some areas of viewport” and only on clouds)

screenshot:

and when i press 1 and 2, it change ambient sky light intensity.

please in Test make tpf depend like “lightDir.y -=.1f * tpf;” it was like “press and get black or blue” for 1/2 buttons :slight_smile:

But when i make totally black light, it dont have issue from above screenshots, but imo Clouds should also be black? see below:

Is there a way i can help you test what cause this issue?

But i feel like its this

skyImageRaster = ImageRaster.create(skyViewTexture.getImage());

related?

Or just with something about sky light, because when make it black with 1 button in Test, there is no issue visible.

i will try remove some shader features to see (but im not sure what should i try first)

edit:

when i comment this line:


the issue artefact disappear

1 Like

Oh that image raster is unneeded. Forgot to remove that. Whoops! I don’t think it affects anything since it’s unused.

The color blending is very much a work in progress. That pixelation is definitely correctable in the shader. Play with different combinations at the end where color blending is applied. There are some really nice looks that can be generated.

Yes, sky color at night is definitely a work in progress. Eventually I want to be able to make it like this!

cubemaps_morrowind

4 Likes

Wow the screenshot effect looks nice, i hope you will be able make same or even better :slight_smile:

@dreamwagon

anyway About The issue, i found how to temporary fix artifact issue:

change:

skyViewTexture.getImage().setMipMapSizes(new int[]{0, 1});

to:

skyViewTexture.getImage().setMipMapSizes(new int[]{0});

but im not sure why mipmap sized cause issue and if its necessary.

still to let you know, some visual effects looks odd here examples:

Looks awesome, as i understand this dark cloud areas are high density of cloud so “light cant pass it” but in this example it looks odd with dark cloud.(or maybe its just my perception)

but i think when Bloom will take effect, it might not look odd.

3 Likes

@dreamwagon

Also small thing:

private Vector3f lightDir = new Vector3f(-1,0.1f,1).normalizeLocal();

i think Y should be Minus value :slight_smile: i mean it should work for inverted Y value in shader.

noticed it when tried use own light direction that “raycast down” not “up” :slight_smile:
had Black sky he he

@dreamwagon, I’ve been following this conversation quietly with quite some interest. I do have a question about using vcloud in reflection-heavy scenes. I noticed your approach uses a camera-aligned quad for the sky, which does not work well for scenes involving non-planar or off-screen reflection (wavy surfaces like water, glass reflecting to behind the camera view). For these scenarios, you need a skybox or skydome. How difficult would it be to replace the quad with another geometry, like a dome, or at least allow the end user to create the sky geometry themselves?

2 Likes

i thought also about PBR reflection before. its not about this topic, but snapshotting envmap and blending between them could simulate clouds moving too on reflection PBR metals.(or windows, well)

That’s a good idea - I guess you could snapshot an env map even with a quad for reflections. I’ll give it a shot. Blending should work well for cloud movement.

1 Like

I believe changing from a quad to a dome would not be that much of an undertaking. Probably just there vertex shader would need to be modified to provide the position differently. The current system. Uses a framebuffer and processor so that part would not work the same if you were to add a dome or skybox as a node. I have not been able to find any time to get back in to this (haven’t even had time to update the readme!) But when I do, I’ll see if I can put together something.

4 Likes

I played around with two ways to get the dome to work. One simply uses two domes, one for sky and one for clouds. This approach works fine, but then we lose the ability to half size the frame buffer.

The second way is leaving the sky and clouds as quads and changing the apply geometry to a dome. This will also work, but I need to figure out how to scale the texture the framebuffer generates to the dome the correct way. It is stretching the texture over the entire dome right now. Anyone have an example I could use? I thought it was just a multiplication of the view matrix, but I am missing something.

In any case, the first way works and is pretty easy to setup, just doesn’t have the performance boost of the smaller framebuffer.

7 Likes