4
\$\begingroup\$

I know that it is possible to make a shader that uses procedural hatching instead of pre-designed tonal art maps. But is it possible to make that procedural hatching in the fragment shader? I would like to know some algorithm to achieve that, it doesn't need to be in GLSL, some pseudo-code would be nice

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Yes, in fact I'm not sure of any other way you'd do it other than in the fragment shader. Here's some examples I found:

  • This ShaderToy uses a noise texture and another function to generate the hatching. It's not exactly like artistic gradiential hatching but I think it's definitely a start. You'd specifically want to look at the texh() function, the rest is how he generates the scene, lighting, objects, etc...

.

//Excerpt from https://www.shadertoy.com/view/4lfXDM
//By nmz, https://www.shadertoy.com/user/nmz
//texh is the function that generates the Hatching TEXture
//p seems to be the uv for hatching, str seems to be the strength
float texh(in vec2 p, in float str)
{
    p*= .7; //Scale p
    float rz= 1.;
    for (int i=0;i<10;i++)
    {
        float g = texture2D(iChannel0,vec2(0.025,.5)*p).x;
        g = smoothstep(0.-str*0.1,2.3-str*0.1,g);
        rz = min(1.-g,rz);
        p.xy = p.yx;
        p += .07;
        p *= 1.2;
        if (float(i) > str)break;
    }
    return rz*1.05;
}
  • This GLSL example seems more inline with artistic hatching but is only demonstrated on a 2D image. The relevant code can be found below...

.

/*
    Straight port of code from
    http://learningwebgl.com/blog/?p=2858
*/

uniform sampler2D Texture;

void main()
{
    float lum = length(texture2D(Texture, gl_TexCoord[0].xy).rgb);

    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

    if (lum < 1.00) {
        if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {
            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
        }
    }

    if (lum < 0.75) {
        if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {
            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
        }
    }

    if (lum < 0.50) {
        if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {
            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
        }
    }

    if (lum < 0.3) {
        if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {
            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
        }
    }
}
\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .