• Advertisement
Sign in to follow this  

Desperate: Antialiasing/Filtering of Procedural Texture

This topic is 886 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

 

Well, first off, I'm not sure what exactly my question is anymore. I've asked on StackOverflow but got no answers. I'm at my wit's end here and slowly losing my sanity. So any comment whatsoever about any part of this post is appreciated, I guess.

 

I've been obsessing about the topic of procedural antialiasing (filtering) lately. I've been trying to get into procedural texturing (i.e. creating texture patterns algorithmically in a shader, as opposed to just applying some pixel image) and I found you can do a lot of interesting stuff with it. But filtering these procedural textures is giving me profound nightmares.

I've been reading "Texturing & Modeling: A Procedural Approach" and understand the basic concepts of frequency clamping, analytic prefiltering and the like. But whenever I'm dealing with something more complicated than an isolated noise/turbulence call, none of this seems to make any sense.

 

For example, I have a shader based on Perlin-style gradient noise. But I'm only interested in areas where it has very high values (I'm trying to create random spots of "holes" on a tree surface), so I'm feeding it into a smoothstep function like this (excerpt from a GLSL shader):

float hole = smoothstep(holeThreshold.x, holeThreshold.y, gnoise(sp*holeFrequency)*0.5 + 0.5);

The output of gnoise varies from -1 to 1. holeThreshold.x/y are the begin and end of the smoothstep ramp (when the gnoise value is lower than holeThreshold.x, "hole" will be 0. When it's greater than holeThreshold.y, "hole" will be 1. Between these two it will be something in between 0 and 1. hole = 0 means no hole, hole = 1 means hole of full depth, anything in between is the "slope" on the sides of the hole.

 

Now of course, when a texture based on this is viewed from far away, aliasing will occur because of the high-frequency content of both gnoise and smoothstep (the hole's slope is too steep). So how am I supposed to antialias this?

All I could think of was fading the "holes" out based on some magic formula involving viewing distance (sampling rate) and frequency content of gnoise/smoothstep. But first of all, just fading this stuff out feels like cheating. Secondly, it did not seem to work (what are the maximum frequencies of these functions? Do they have maximum frequencies at all? And what if I combine them the way I did?). I don't want to go into too much detail of what I tried because I've been researching this stuff for far too long and every minute I feel like my understanding of the topic decreases...

 

So, do you have any tips on how to filter a texture like this? Or tips on procedural antialiasing in general? Something I could read that clears my confusion?

 

For those interested, I posted a more complete excerpt from the shader I'm using in my original question.

 

 

Thanks a lot in advance!

Share this post


Link to post
Share on other sites
Advertisement

Temporal supersampling might be a start, also known as temporal anti-aliasing.

 

 

I don't know much about temporal supersampling, but isn't it just for moving objects/moving camera? I want antialiasing to work for stationary scenes, too.

 

 

 

Instead of sampling the function for a single point, you need to integrate the value of your function over an area, based on the area of your pixel

 

 

I thought about that, too. I just assumed that noise functions are incredibly difficult/impossible to integrate analytically in most cases so I didn't think this could work. Maybe I should look at this a bit more in-depth. It's not only the noise function though. It's also the smoothstep or whichever function(s) I decide to apply to the noise afterwards, so I have to integrate more than just pure noise.

 

 

 

Brute force approach is just to take a lot of samples within that domain and average them

 

 

This feels a bit like cheating, as it doesn't really fix the problem but only makes it a bit less noticeable (it's still aliasing, only at higher distances/frequencies).

 

 

 

If any noise octave has a wavelength smaller than this quad's size, then it will just be contributing noisy/aliased data -- fade those octaves out as they shink towards this minimal area, and replace them with their average

 

 

That's what I was trying to do and it works fine for a simple noise (or turbulence/fractal noise). But when I apply some other functions to the noise value afterwards (like smoothstep), the resulting function might have higher frequencies than the basic noise, and so the cutoff frequency for the noise function becomes lower. But just how much lower? I guess I would have to know about the frequency content of all the functions I'm feeding my noise through.

Maybe it's just best to add a constant factor to the cutoff frequency and find this factor by experiments (see at which value aliasing disappears)? There doesn't seem to be an easy theoretical solution.

 

 

Thanks for your help!

Share this post


Link to post
Share on other sites

but you can also apply the theory that you mention. If any noise octave has a wavelength smaller than this quad's size, then it will just be contributing noisy/aliased data -- fade those octaves out as they shink towards this minimal area, and replace them with their average (if the noise octaves are waves that are centered at 0, then that's nice and easy). Depending on the noise functions in use, there may or may not be an analytical solution to discover the integral of some arbitrary range...

I've used this trick for procedural planet rendering before. Basically, if you design your fractal such that each successive octave has roughly twice the frequency and half the magnitude of the preceding octave, you can just increase/decrease the number of octaves to match your zoom level.

Obviously you have to design your fractals with this use in mind, but when we are talking 60 octaves of noise for a single heightmap sample, it's a worthwhile optimisation.

Share this post


Link to post
Share on other sites

I thought I'd give finding an analytical solution to the integral a try and am currently trying to force Mathematica (which I've never used before) into giving me the answer, but integrating noise does seem hard. I'll see if I can get anything out.

 

 

Thanks for your help!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement