9

So I've been delving into "Texturing & Modeling: A Procedural Approach" recently and started writing my first procedural textures in GLSL. What gives me the most headaches though is the topic of antialiasing. It's obvious how to do it in simple cases like very regular patterns (analytical averaging using integration) or spectral synthesis (frequency clamping), but whenever it's something else, none of the methods seem to work.

I have the following code which is just one part of a procedural wood (tree) texture:

vec4 TreeTexCompute(in vec2 sp)
{
    const float holeFrequency = 1.0;
    const vec2 holeThreshold = vec2(0.6, 0.85);

    vec2 vfw = fwidth(sp);
    float fw = max(vfw.x, vfw.y);

    float holeNyquist = 0.5 * holeFrequency * (1.0 / fw);

    // Upper bound for the frequencies in the function to compute 'hole' below
    float holeHighestFreq = 1.0 / (0.5 * (holeThreshold.y-holeThreshold.x));

    // Spawn a hole where gnoise has its "maximum" values
    float hole = smoothstep(holeThreshold.x, holeThreshold.y, gnoise(vec3(sp*holeFrequency, -3.75))*0.5 + 0.5);

    // Gradually fade out the hole as we approach the nyquist frequency
    float t = mix(hole, 0.0, smoothstep(0.5*holeNyquist, holeNyquist, holeHighestFreq));

    return vec4(t, t, t, 1.0);
}

What it does is randomly place small "holes" by feeding the output of a Perlin-style gradient noise (float gnoise(vec3)) into the smoothstep function, creating light spots only around the maximum values of gnoise. Antialiasing is done by gradually fading this value out to black as we approach the nyquist frequency. However, it seems that the fadeout happens WAY too early. The camera basically has to touch the texture surface to see any holes at all. This doesn't seem right and when I disable the fadeout I can't see any aliasing until I'm much farther away.

So what am I doing wrong? I thought about my frequency calculations for a while and can't find anything wrong with them. The nyquist frequency is half the sample rate, and the highest frequency (an upper bound, really) of the function used to compute 'hole' results from the maximum frequency of gnoise (which I believe is about 2.0) and smoothstep (which if I understand correctly is approximately the inverse of its ramp width).

And by the way: What would you say is the preferred way to antialias such a texture of randomly placed holes? Fading them out entirely is the only thing I could think of, but it doesn't seem very satisfying. Supersampling I assume is just a hack and doesn't really solve the problem. I'm using similar techniques of feeding streched gradient noise to smoothstep functions to generate many other features of the wood texture, including larger fissures, so I really need good antialiasing for this.

Alemarius Nexus
  • 340
  • 3
  • 12
  • 1
    Have you tried using the `dFdx()` and `dFdy()` functions to get the neighbouring pixel's values and average them? This could provide a bit of anti aliasing. Alternatively you could also manually calculate the neighbouring pixel's values in your shader and average them. Or you can use a post process anti aliasing method like FXAA. – Tara Jul 31 '16 at 02:24
  • I find this website's tutorials on OpenGL to be very decent and this is a nice write up about anti-aliasing. https://learnopengl.com/#!Advanced-OpenGL/Anti-Aliasing – Francis Cugler Dec 05 '17 at 08:56
  • Screenshots cold be helpful too – Makogan Jan 17 '20 at 20:44

0 Answers0