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\$
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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.