Writing texture for sky every frame, wrong?

Started by
5 comments, last by okonomiyaki 21 years, 8 months ago
Ok, usually I don''t make another thread so quickly so as to not have so much attention on me (especially when there was such an elaborate thread with people replying to me about skies a little while ago!) but I had to ask this. I finally have my geforce4 (and new computer in fact) and I''m surprised that I can''t get my program running any faster. I''m getting about 17 fps! I''ve narrowed it down to writing the sky texture every frame (I suppose locking a 1024x1024 texture and writing it would be kind of slow..) but how the heck else am I supposed to dynamically change the sky? I can''t just change it every 30 frames or so, it would be jolty and the sky change would be blocky. I can''t make a thread for it because the main process can''t access the texture until the thread is done writing it anyway. So how does one go about creating a dynamic sky with high fps? I don''t need real elaborate replies (unless you''re bored) but I''m totally lost on how to have fast dynamic skies. Don''t tell me you use TextureStageStates? Or.. do I need to learn vertex shaders?
Advertisement
Hmm, I suppose the answer is don''t lock a 1024x1024 texture! Is there any chance you could render to the texture versus direct writing to it? How about using a lower resolution even? Shaders are nice to, I reccomend them, but you don''t need to go that far yet.

"Love all, trust a few. Do wrong to none." - Shakespeare

Dirge - Aurelio Reis
www.CodeFortress.com
Current Causes:
Nissan sues Nissan
"Artificial Intelligence: the art of making computers that behave like the ones in movies."www.CodeFortress.com
just dealing with 1024x1024 array is 2MB of data at about 16bit and 4MB at 32bit. thats a lot of data. now agp 4x gets 1070 mega BITS per second or roughly 133 MB per second. so take 17 (the franerate) and mulitply by 4 MB and you get 68 MB per second. 34 MB per second is required if it was a 16bit texture. so the transfer is definatly the bottleneck. since you are rendering other things on the card you are not soly just letting the cpu transfer data. since you are doing other stuff the 133 MB per second is a dream since the cpu wont be transferring data all the time, and vertices will be transferred as well. most likly the actual animation of the 1024x1024 sky (ie drawing the clouds, sky, sun, etc to memory for transfer) is slowing things down as well (that is quite a large buffer)

you MUST drop the resolution of the texture if you want realtime action. its the ONLY way to make things faster. the numbers dont lie. video cards can scale things rather well and a 256x256 texture is not all that bad if its animated.

why do you need to render everything using pixel stuff? its wasteful at that resolution. no matter how fast the GPU is, transfers are limited by the agp bus. you CANT expect a geforce4 top of the line to outperform an old 4x agp card when they use the EXACT SAME technology to transfer data from the system ram to the vram.

[edited by - a person on July 30, 2002 4:56:48 AM]
okonomiyaki,

Well yes, as had been said, the AGP bus is the bottleneck. Transfering a 1024² texture every frame is going to slow you down, no matter what. But if your clouds look good, then you have reached the first important step: quality. Now it's time to optimize it

Solutions:

a) lower the texture resolution (duh...). I know, that's no option

b) lower the memory requirements of the cloud texture by compressing it (eg. do a realtime S3TC/DXTC compression on the CPU while creating the clouds, and upload that to the 3D card). This will cut your bandwidth requirements down tremendeously (assuming you're using a 32bit texture right now), but will probably require some well optimized ASM code in the realtime compressor.

c) Do the cloud generation on the GPU.

The later one is the key to fast dynamic skies. You don't need to create the clouds 100% on the GPU (although that's possible, see the other sky thread), but you should try to create as much as possible. Since I don't know exactly how you animate the clouds in the first place (animated Perlin noise ?), I can't give you any directed advice, but here are some general ideas:

Create two 1024² textures using your CPU, upload them both at startup, and use the GPU to slowly interpolate between both. Then every 10 frames or so, upload e new 1024² map. You don't have to do that upload in a single frame (will introduce an framrate glitch), you can upload a small part of that 1024² texture every frame, until it is finally complete after 10 frames or so.

Other idea: use 2 (or more) lower resolution textures, by separating the lower and higher Perlin octaves. Upload them every frame (no problem, since the required resolution is pretty low), and recompose the octaves on the GPU (by tiling and blending accordingly).

There are some other methods, but it ultimately depends on how you implemented the noise function. But using the GPU for as much as possible is definitely the key to fast special effects (esp. with an advanced card such as the GF4).

/ Yann

[edited by - Yann L on July 30, 2002 7:17:41 AM]
Well, I pretty much knew that there was a way for those high quality resolutions by reading the "high and mighty" sky thread where people could get a high resolution running fast. But I couldn''t really find how people did it, which is why, out of immense curiousity, I was forced to post.. But I guess the other thread really did cover it- the key is doing it on the GPU, and that''s what Yann talked about in the other thread. I guess that''s where I need to look up more info on- I''m not exactly sure which functions to call to make the GPU work. And Yann, I''m doing EXACTLY what you said as your first method of animation. I pre-compile two 1024x1024 perlin noise textures, and interpolate between them, and every frame it calculates n number of pixels of the next 1024x1024 texture, and by the time it''s done interpolating, it''s done calculating the next one, delete the first one, switch second to first, switch second to the new one, and bam, start interpolating again. This looks really good but the problem is I guess that I''m re-writing the texture and filling it according to the main updated array of pixels. I''ve gotta find out how to do the "uploading" with the GPU. I bet you that 0% of it right now is done the GPU (maybe I''m exaggerating) but I seriously haven''t been aiming towards that. Thanks a lot Yann, not only for this, but for always replying otherwise
Dirge- rendering the texture was another idea. I thought that process to set it up to render would be a little slow too. I may try that, but nonetheless I want to aim for as much work on the GPU as possible.
a person- I could never really get a 256x256 texture of noise to look very right. You just couldn''t see the fine details of high octaves good enough. I don''t know why, but I can''t stand anything less than 1024, and I''m willing to do anything before I have to drop it Although if I am forced to, I guess skies aren''t the biggest aspect of my game..
don''t do the uploading on the GPU.
do the interpolation.

how about multitexture and blend modes (alpha) ?



You mean SetTextureStageStates? That''s really the only way I can think of to make sure that it''ll happen on the GPU. I suppose it''d be easier to blend it with the sun and gradient map easier too. I''m actually trying to get that working right now. I''ll be very happy if simply that speeds it up (hopefully much).
I suppose I could use the D3DTOP_LERP to interpolate. I could do that in another pass with the gradient map- at least that''s what I plan to do. Thanks

This topic is closed to new replies.

Advertisement