Categories
Journals

This is how I know I’m getting the hang of this OSL malarkey – this procedural yin yang symbol took about 15 minutes to do.

Basically any number of points which are an even distance from another point form a circle. When they’re plotted, anything inside the circle forms a disc and anything else outside the circle is.. well.. something else.

The draw function checks if the point is within the top of the smaller circle first (less than 0.125 from X:0.0, Y:0.5 – Z isn’t relevant). Then it checks if the point is within the bottom circle (less than 0.125 from X:0.0, Y:0.5). Then it checks if it’s within the bottom larger circle (less than 0.5 from X:0.0, Y:-0.5). Then it checks if the point is within the top circle (less than 0.5 from X:0.0, Y:0.5). Then it checks if it’s in the right half of the circle (Po[0] is the X position). If it’s not within the right half of the circle where X is greater than 0, it must be in the left half where X is less than zero.

The shader itself checks to see whether the point being plotted is further than 1 away from point X:0.0 Y:0.0. If it is, 1 is output – in the rest of the shader, this makes the disc transparent. If it’s closer than 1, it goes down to another checkpoint – if we’re drawing a point less than 0.98 from the origin, it uses the draw function and returns either the yin or yang colour. If we’re not drawing that point (we’re between 0.98 and 1), we need to return the border colour.

Little bit rough I suppose but it’ll do. 🙂 It would be possible to hook input variables into things like the size of the dots and then slave those to an F-Curve driven by music to make them pump in time to music, but that would just be crass, wouldn’t it?

Here’s the code. You can figure out how to do the crass part yourself. (Hint: You need to pass a variable from the shader to the draw function to affect the value that’s currently set at 0.125 – maybe calculate the size of the smaller discs as 0.125 + (0.125 * Scale) before doing the region check.)

 float draw(point Po) {

    if (distance(Po, point(0.0, 0.5, 0.0)) < 0.125) {

        return 1;

    }

    else if (distance(Po, point(0.0, -0.5, 0.0)) < 0.125) {

        return 0;

    }

    else if (distance(Po, point(0.0, -0.5, 0.0)) < 0.5) {

        return 1;

    }

    else if (distance(Po, point(0.0, 0.5, 0.0)) < 0.5) {

        return 0;

    }

    else if (Po[0] > 0) {

        return 1;

    }

    else {

        return 0;

    }

}

shader yinyang(

    point Po = P,

    color Yin = (0.0),

    color Yang = (1.0),

    color Border = (0.0),

    output color Col = 0.0,

    output float Alpha = 0.0

) {

    float Dist = distance(Po, point(0.0,0.0,0.0));

    Alpha = (Dist > 1) ? 1.0 : 0.0;

    if (Dist < 0.98) {

        Col = draw(Po) ? Yang : Yin;

    }

    else {

        Col = Border;

    }

}

By quollism

A creator of quollity stuff.

Leave a Reply