Skip to main content
GameDev.net gamedev.net
🔒 Locked

Procedural GPU-Generated Normal Map Artifacts

Started by SkavenPlanet Jun 26, 2015 at 4:40 AM 1 replies 3.5k views
Original Post
SkavenPlanet
SkavenPlanet

This is sort of a continuation of this thread: http://www.gamedev.net/topic/660629-procedural-planet-gpu-normal-map-artifacts/ which details the problem of running out of precision when generating normal maps on the GPU for procedural planets and ending up with noisy artifacts at high subdivision levels (>15):

Screen%20Shot%202015-06-25%20at%209.17.3

In the original thread linked above Ysaneya stated that double precision GPU emulation (storing the high and low parts of the "emulated" double as separate floats) was the solution that he used in the I-Novae engine which I attempted to use and implemented double precision emulation for generating the inputs for my noise functions however I haven't seen any noticeable changes in my results. The problem is that once the positions have to be plugged into the noise functions they have to go from emulated doubles to single floats meaning that the extra precision gets lost anyway which is probably why my results don't look noticeably different; Ysaneya mentioned that this is the extent to which emulated double precision is used for I-Novae, however, and most of the noise generation is done with non-emulated arithmetic but I'm really unsure as to how this fixes the issue because as I stated it seems like the extra precision gets lost before it's plugged into the noise function anyway. After checking the rest of the maths involved in generating the normal maps I'm not quite sure where the precision issue really is and trying to pin it down has left me going in circles. Help?

SkavenPlanet
SkavenPlanet

Well, I decided to rewrite the procedural noise function (properly this time) to use emulated double precision until it was no longer relevant (until the values tied to the input positions get floored and converted to integers) and I noticed no improvement, the artifacts are still very much present. Then I also rewrote the normal map generation code to use emulated double precision (this required using two 256x256 floating point textures which I don't think is suitable for an actual implementation) for most of the process but after a few tests I figured that this wasn't improving anything anyway. Still, help?

SkavenPlanet
SkavenPlanet

After replicating my normal map shader on the CPU I decided to convert basically everything to double precision and carefully began re-replacing the doubles with singles while avoiding loosing precision in the resultant normal map and surprisingly I wasn't too far off from getting everything right when I rewrote the procedural noise function and normal generation code, there were only a few more things that needed to use doubles... I found that the ultimate result of the procedural noise function and the procedural noise input both need to be in double precision when being sent to the normal map generation shader which isn't ideal because, as I stated above, this requires using two 259x259 (not 256 actually, because the shader needs some extra texels) floating point textures - one to store the high parts of the input position components and the height (highX, highY, highZ, highHeight -> r, g, b,a) and one to store the low parts (lowX, lowY, lowZ, lowHeight -> r,g,b,a). Fortunately, both textures get deleted from video memory after the normal map is generated however the amount of required texture lookups is doubled in the normal map generation shader. More texture lookups and having to use emulated double math will unfortunately slow the normal map shader down but it's not too bad of a price to pay for artifact-free normal maps. Still I wonder how Ysaneya got his system to work without having to do a lot of the additional double emulation required for my system to work. I still have to apply my fixes to the shaders so hopefully, once I do, these annoying artifacts will finally go away.

PS: Really wish every GPU could use doubles...

EDIT: Apparently I can go even higher than 18 depth levels (although I probably won't ever have to)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.