Create halftone effect with a diamond shape

I am trying to recreate a halftone effect with a diamond shape. The original half-tone effect was applied to an image in Gimp and looks like this.

I am trying to reproduce this effect in three.js using the HalftonePass (which uses the HalftoneShader). That has been pretty successful, but it uses a circle shape instead of the diamonds:

The HalftoneShader supports four shapes (dot, ellipse, line, square). I believe that the dot shape used in the image above is calculated in the following code in distanceToDotRadius:

rad = pow( abs( rad ), 1.125 ) * rad_max;

Other shape functions are handled in adjacent lines, but honestly I wouldn’t know where to begin to figure out how to define a diamond shape. Does anyone know how I could define a diamond shape here or have any links I could follow to try to figure this out? I may be well out of my depth here…

As it seems to me correctly, a diamond is a kicked square… so why do you start from a point and not from a square, rotating it by 45 degrees?

(shape == SHAPE_DIAMOND) {
    float angle45 = 3.14159265 / 4.0; // 45°
    float theta = atan(p.y - coord.y, p.x - coord.x) - angle45;
    float sin_t = abs(sin(theta));
    float cos_t = abs(cos(theta));
    rad = pow(abs(rad), 1.4);
    rad = rad_max * (rad + ((sin_t > cos_t) ? rad - sin_t * rad : rad - cos_t * rad));
}

No need to change anything in the shader. It has uniforms (a kind of parameters). There are uniforms for rotation (rotateR, rotateG and rotateB), so use them. Here is the default square pattern:

And here is the same, but with rotations of \pi /4, which is 45^{\circ}

3 Likes

Whats this gui from these screenshots?

1 Like

Oops

Halftone

2 Likes

Wow, I’m really blown away by all the help. Thanks everyone! @Lukasz_Mestales’s approach of the “kicked square” did the trick:

I just had to apply both the angle and the angle45 to get the diamonds aligned correctly along the tilted axis. This is the final function (- angle - angle45):

} else if ( shape == SHAPE_DIAMOND ) {

	float angle45 = 3.14159265 / 4.0;
	float theta = atan( p.y - coord.y, p.x - coord.x ) - angle - angle45;
	float sin_t = abs( sin( theta ) );
	float cos_t = abs( cos( theta ) );
	rad = pow( abs( rad ), 1.4 );
	rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );
}

@PavelBoytchev thanks for that tip! I did try the rotation uniforms, but I think part of the diamond effect I want relies on how gaps between the diamonds are positioned. The square shape with rotation left even gaps around all four edges. I’m not sure if I understand it properly but something looks slightly different about the diamond effect that I wanted.

The PR was merged so this feature be available as an option in r183.

1 Like