~zjm/Moon3D

93e67e2d43ced33af4b83b2a149dc631b1105335 — Zack Michener 5 months ago b120dcf
improve ordered dithering
2 files changed, 30 insertions(+), 29 deletions(-)

M src/3d/dither.c
M src/3d/dither.h
M src/3d/dither.c => src/3d/dither.c +29 -28
@@ 1,5 1,6 @@
#include "dither.h"
#include <stdlib.h>
#include <math.h>

void Dither(Viewport frame)
{


@@ 10,8 11,8 @@ void Dither(Viewport frame)
		}
	}

	// Ordered(output, frame.width, frame.height);
	FloydSteinberg(output, frame.width, frame.height);
	Ordered(output, frame.width, frame.height);
	// FloydSteinberg(output, frame.width, frame.height);
	// Atkinson(output, frame.width, frame.height);

	for (int y = 0; y < frame.height; y++) {


@@ 27,7 28,7 @@ void FloydSteinberg(Color *output, int w, int h)
	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			Color oldPixel = output[y*w + x];
			Color newPixel = ClosestColor(oldPixel);
			Color newPixel = (oldPixel < 0.5) ? BLACK : WHITE;
			output[y*w + x] = newPixel;
			double error = oldPixel - newPixel;



@@ 48,7 49,7 @@ void Atkinson(Color *output, int w, int h)
	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			Color oldPixel = output[y*w + x];
			Color newPixel = ClosestColor(oldPixel);
			Color newPixel = (oldPixel < 0.5) ? BLACK : WHITE;
			output[y*w + x] = newPixel;
			double error = oldPixel - newPixel;



@@ 69,29 70,35 @@ void Atkinson(Color *output, int w, int h)
	}
}

double *BayerMatrix(int n)
{
	double *map = malloc(sizeof(double)*n*n);

	int M = 0;
	int N = n;
	while (N >>= 1) M++;
	for(int y = 0; y < n; ++y) {
		for(int x = 0; x < n; ++x) {
			int v = 0, mask = M - 1, xc = x ^ y, yc = y;
			for(int bit = 0; bit < 2*M; --mask) {
				v |= ((yc >> mask)&1) << bit++;
				v |= ((xc >> mask)&1) << bit++;
			}
			map[y*n+x] = (double)v/(double)(n*n);
		}
	}

	return map;
}

void Ordered(Color *output, int w, int h)
{
	double map[4][4];
	map[0][0] = 0;
	map[0][1] = 8;
	map[0][2] = 2;
	map[0][3] = 10;
	map[1][0] = 12;
	map[1][1] = 4;
	map[1][2] = 14;
	map[1][3] = 6;
	map[2][0] = 3;
	map[2][1] = 11;
	map[2][2] = 1;
	map[2][3] = 9;
	map[3][0] = 15;
	map[3][1] = 7;
	map[3][2] = 13;
	map[3][3] = 5;
	int n = 8;
	double *map = BayerMatrix(n);

	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (output[y*w+x] < (map[x%4][y%4]/16.f)) {
			if (output[y*w+x] < map[(y%n)*n+(x%n)]) {
				output[y*w+x] = BLACK;
			} else {
				output[y*w+x] = WHITE;


@@ 99,9 106,3 @@ void Ordered(Color *output, int w, int h)
		}
	}
}

Color ClosestColor(Color c)
{
	if (c < 0.5) return BLACK;
	else return WHITE;
}

M src/3d/dither.h => src/3d/dither.h +1 -1
@@ 7,4 7,4 @@ void Dither(Viewport frame);
void FloydSteinberg(Color *output, int w, int h);
void Atkinson(Color *output, int w, int h);
void Ordered(Color *output, int w, int h);
Color ClosestColor(Color p);
double *BayerMatrix(int n);