Sky-rendering techniques

Started by
137 comments, last by Filip 20 years, 2 months ago
Ah, I totally understand, that''s an cool implementation of Perlin Noise. I have it running 100% on the GPU but it doesn''t look nearly as good as when it was running on the CPU (though faster). But still tweaking it, hopefully can compare my results with yours soon (NO doubt yours will look better ) Thanks so much
Advertisement
You have to do some tweaking to make it look good on the GPU. The problem is the limited precision and dynamic range you have available. Also make sure that your octave base-textures have best possible quality. You could try to fiddle around with some regcom tricks, if you want, I guess you could configure the pipeline to get more precision than 8/9 bit. Just an idea: you could add two(four) octaves on the green and two(four) octaves on the blue channel, separately. That would double your dynamic range on the high frequencies. Then, later on the exponentiation pass, use something like DEPENDENT_GB_TEXTURE_2D_NV (NV_texture_shader) to access a 2D exponentiation texture, that would do the octave addition, amplitude modulation and exponentiation as a 2D lookup operation. I guess that would allow for better precision.

/ Yann
I'm using direct3d, what's the connection between texture shaders and it? Or what's the equivalent to the OpenGL extensions?
edit: I'm asking this because I can't find any reference for texture shaders and Direct3d

[edited by - okonomiyaki on January 29, 2003 1:52:04 PM]
quote:
I'm using direct3d, what's the connection between texture shaders and it? Or what's the equivalent to the OpenGL extensions?
edit: I'm asking this because I can't find any reference for texture shaders and Direct3d

Oh, hmm, good question. I've never done any pixelshader related stuff in D3D. IIRC, OpenGL texture shaders = texture addressing operators in Direct3D (tex, texm3x2tex, texcoord, texkill, etc). And regcoms = texture blending operations (dot3, mul, mad, etc). Perhaps someone with more Direct3D experience can help here. On older nVidia hardware at least. With newer DX9-level hardware, D3D HLSL and OpenGL Cg (using ARB_fragment_program, or OGL2) shaders are pretty much the same. Good thing.

Hmm, thinking of it, I should really rewrite the cloud shaders in Cg, if I find some spare time.


[edited by - Yann L on January 29, 2003 2:33:21 PM]
Oh, that clears up SO much! Heh I feel like I understand the concept well enough to implement in in d3d vs 1.1. I don''t have a card that supports the HLSL (in fact.. doesn''t only the radeon 9700 support it right now?) and I never got into CG (I don''t know why).
In D3D, it''s not so different.
the vertex shader is just as easy, set it up so that it tiles correctly (and maybe a certain projection matrix to generate tex coords, then tile accordingly).
For the pixel shader, set the two(four) textures of (3 or higher) octaves in the respective texture units (t0, t1, t2, ...). The operations are easy, multiply each by the amplitude factor, then add it all up (I use add_sat for this step to clamp it between 0 and 1). Then subtract the cloud_cover value. Then a step to see if it''s less than 0, clamp to 0. Now we have finished the first pass of your technique. But I go ahead and exponentiate it here instead of doing a second pass. We can only have 4 textures set at a time, so that limits us to 3 textures of perlin noise, but that''s enough for me. So the 4th texture is the 256x1 exponetial lookup table. I haven''t gotten to the exponential part of my pixel shader yet, but I''m guessing I can transform the texcoords within my pixel shader to slide around it. Look it up, grab the value from the texture lookup table, and that''s cfinal.
As I said before, I''ve only gotten to the subtracing of cloud cover. It looks alright, a little blurry, but there''s much more I can do with it. If I get it looking good with the DX pixels shaders I''ll post a screenshot.
Yann, thanks for the reply. I was refereing to the low-sun case. IIRC, you didn''t mention the self-shadowing issues for noon-time sun. I see your point now.

A few other issues though:
1. That textured trapesoid technique you use for atmospheric shadows - I understand how it works for when the sun is partially obstructed by clouds. But suppose you have a cloud that doesn''t obstruct the sun at all. At least under some conditions, you would see a shadow extending down from the cloud (or sidewards, or even up - depending on the relative position of the sun). How would you handle this with your cloud technique?
2. Do your coulds cast shadows on the terrain? If so, do you use shadow maps for this (using the generated perlin noise), some extension of the cloud-shading system, or some other solution?
3. In the real world, when one looks at the sun through a thin cloud layer, one sees an area of very brighty lit clouds where the sun should be (much more bright than the nearby clouds). Does your shading technique produce that result? If not, how might this be acheived?

Michael K.,
Designer and Graphics Programmer of "The Keepers"


We come in peace... surrender or die!
Michael K.
quote:
So the 4th texture is the 256x1 exponetial lookup table. I haven''t gotten to the exponential part of my pixel shader yet, but I''m guessing I can transform the texcoords within my pixel shader to slide around it. Look it up, grab the value from the texture lookup table, and that''s cfinal.

What 3D hardware do you have ? Chances are, that this will not work. On GF4 and below, a texture addressing op cannot follow a blending op. In the pipeline, both are independent subsystems, and texture addressing operations will produce an RGBAZ result, which can be used by blending operations. But it doesn''t work the other way round: you cannot compute the clamped noise on the first 3 texture stages, and then feed that RGBA value back to a tex addressing op. You''ll need a fully configurable pipeline (Radeon 9700, GFfx) to do able to do that.

Hmm, I just browsed the GF4 pipeline specs on texture shading opeartions. It seems that they added a mode to map RGB to a three dimensional texture coordinate. Nice. You could use a 3D texture as lookup, to get extended precision on the higher octaves, and at the same time, being able to select the exponentiation factor by hand, without reuploading a new exp texture. Or you use a fixed exponent, but use the 3rd dimension to get even higher precision. Hmm, I have to try that, it could really be cool. I wonder about the performance of that operation.

quote:
1. That textured trapesoid technique you use for atmospheric shadows - I understand how it works for when the sun is partially obstructed by clouds. But suppose you have a cloud that doesn''t obstruct the sun at all. At least under some conditions, you would see a shadow extending down from the cloud (or sidewards, or even up - depending on the relative position of the sun). How would you handle this with your cloud technique?

It can never go upwards, due to the positioning of the trapezoid. But it can happen downwards, on a more distant cloud. It''s a question about fine tuning: the width of the trapezoid at the intersection with the cloud plane must be wide enough to give nice rays, but still be narrow enough to avoid stray rays. It can''T always be avoided, but most of the time it looks pretty nice. The alternative is a fully volumetric atmosphere model, which looks awesome (as it also includes atmospherical terrain shadows, esp if the sun is low), but takes much more performance.

quote:
2. Do your coulds cast shadows on the terrain? If so, do you use shadow maps for this (using the generated perlin noise), some extension of the cloud-shading system, or some other solution?

I use simple projective mask textures on the terrain (just a projected greyscale texture, that modulates the lighting). And I use a per-vertex approach on the other geometry (I can''t spare a texture unit just for the cloud-shadows).

quote:
3. In the real world, when one looks at the sun through a thin cloud layer, one sees an area of very brighty lit clouds where the sun should be (much more bright than the nearby clouds). Does your shading technique produce that result? If not, how might this be acheived?

Kind of, but not the real thing. I simply add an adaptive glow at the sun position (both before drawing the cloud layer, and in the cloud lighting itself), with a morphinmg shape dependent on sun elevation. For that to work, your sun intensity must by HDR (high dynamic range, means the RGB range must be higher than the standard 0-255. for example 16 bit per component). That way, you can slowly saturate the atmosphere and clouds at the sun position. It looks pretty OK, although it''s not the real thing. But well, the sky model shouldn''t suck up 50% of the framerate either

/ Yann
quote:Original post by Yann L
What 3D hardware do you have ? Chances are, that this will not work. On GF4 and below, a texture addressing op cannot follow a blending op. In the pipeline, both are independent subsystems, and texture addressing operations will produce an RGBAZ result, which can be used by blending operations. But it doesn't work the other way round: you cannot compute the clamped noise on the first 3 texture stages, and then feed that RGBA value back to a tex addressing op. You'll need a fully configurable pipeline (Radeon 9700, GFfx) to do able to do that.

Hmm, I just browsed the GF4 pipeline specs on texture shading opeartions. It seems that they added a mode to map RGB to a three dimensional texture coordinate. Nice. You could use a 3D texture as lookup, to get extended precision on the higher octaves, and at the same time, being able to select the exponentiation factor by hand, without reuploading a new exp texture. Or you use a fixed exponent, but use the 3rd dimension to get even higher precision. Hmm, I have to try that, it could really be cool. I wonder about the performance of that operation.


You are correct, I have a GF4. I did see the operation but I'm still trying to figure out how to look up the specific value in the pixel shader. Why would I need the 3d? I can't quite comprehend how to use it to increase accuracy..
*thinks*
oh! wait! I think I see what you're saying!
(doesn't this require a 2 pass technique? of course, that's what your technique required in the first place. now I know why)
I have the perlin noise texture generated on HW. Second pass. I have t0 with the 3 rgb values. do a 3d texcoord conversion. This will be my first time using 3d textures- but I make one with all of the exponentiation values (256x256x256). Use the texcoords I now have to address this texture and I have the values!
Awesome . just awesome! I'll be staying up late tonight great job, as always, Yann!

Edit: Everything's going great but I can't for the life of me calculate the texture coordinates right to tile the octaves correctly. I have two textures with 3 octaves each, one with a frequency of 64 and one with a frequency of 16. Whichever way I try to tile it I can't get rid of the lines created by tiling.

[edited by - okonomiyaki on January 29, 2003 12:04:27 AM]
I too, am getting the tile lines although I used a different method and haven''t gotten around to implementing it in the GPU..

I basically followed the cloud cover article on
thewww//freespace.virgin.net/hugo.elias/models/m_clouds.htm

so basically I created different maps and combined them all into a 256x256 texture, but i am getting tiling lines, maybe they will go away when i apply the exponential filter...
I don''t see why they would. You''d still see the line artifacts, maybe not as profusely, but they''d definitely still be there..
oh well, I''m working on exponentiation on the GPU right now anyhow.
wouldn''t a 3d texture of 256x256x256 of 32-bit precision take up 64 megs? dang that''s a lot of memory.

This topic is closed to new replies.

Advertisement