Make the shadow actually gaussian
The old shadow kernel formula is not "wrong" per se, as the only judge is if it looks good. However, the formula used is not really gaussian. Also, the kernel size calculation doesn't really make sense to me. This commit change the kernel formula to actually use a gaussian distribution. As far as I can tell, there is no perceivable difference. Except now the effective shadow radius is smaller for the same config. Also, made that part of code a bit more mordern. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
da3df75a8c
commit
dffde065b1
|
@ -426,7 +426,7 @@ typedef uint32_t glx_prog_main_t;
|
||||||
|
|
||||||
typedef struct conv {
|
typedef struct conv {
|
||||||
int size;
|
int size;
|
||||||
double *data;
|
double data[];
|
||||||
} conv;
|
} conv;
|
||||||
|
|
||||||
/// Linked list type of atoms.
|
/// Linked list type of atoms.
|
||||||
|
|
|
@ -569,36 +569,42 @@ check_fade_fin(session_t *ps, win **_w) {
|
||||||
|
|
||||||
static double __attribute__((const))
|
static double __attribute__((const))
|
||||||
gaussian(double r, double x, double y) {
|
gaussian(double r, double x, double y) {
|
||||||
return ((1 / (sqrt(2 * M_PI * r))) *
|
// Formula can be found here:
|
||||||
exp((- (x * x + y * y)) / (2 * r * r)));
|
// https://en.wikipedia.org/wiki/Gaussian_blur#Mathematics
|
||||||
|
// Except a special case for r == 0 to produce sharp shadows
|
||||||
|
if (r == 0)
|
||||||
|
return 1;
|
||||||
|
return exp(-0.5*(x*x+y*y)/(r*r))/(2*M_PI*r*r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static conv *
|
static conv *
|
||||||
make_gaussian_map(double r) {
|
make_gaussian_map(double r) {
|
||||||
conv *c;
|
conv *c;
|
||||||
int size = ((int) ceil((r * 3)) + 1) & ~1;
|
int size = r*2+1;
|
||||||
int center = size/2;
|
int center = size/2;
|
||||||
int x, y;
|
|
||||||
double t;
|
double t;
|
||||||
double g;
|
|
||||||
|
|
||||||
c = malloc(sizeof(conv)+size*size*sizeof(double));
|
c = malloc(sizeof(conv)+size*size*sizeof(double));
|
||||||
c->size = size;
|
c->size = size;
|
||||||
c->data = (double *) (c + 1);
|
|
||||||
t = 0.0;
|
t = 0.0;
|
||||||
|
|
||||||
for (y = 0; y < size; y++) {
|
/*printf_errf("(): %f", r);*/
|
||||||
for (x = 0; x < size; x++) {
|
for (int y = 0; y < size; y++) {
|
||||||
g = gaussian(r, x - center, y - center);
|
for (int x = 0; x < size; x++) {
|
||||||
|
double g = gaussian(r, x-center, y-center);
|
||||||
t += g;
|
t += g;
|
||||||
c->data[y*size+x] = g;
|
c->data[y*size+x] = g;
|
||||||
|
/*printf("%f ", c->data[y*size+x]);*/
|
||||||
}
|
}
|
||||||
|
/*printf("\n");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < size; y++) {
|
for (int y = 0; y < size; y++) {
|
||||||
for (x = 0; x < size; x++) {
|
for (int x = 0; x < size; x++) {
|
||||||
c->data[y*size+x] /= t;
|
c->data[y*size+x] /= t;
|
||||||
|
/*printf("%f ", c->data[y*size+x]);*/
|
||||||
}
|
}
|
||||||
|
/*printf("\n");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
@ -4227,7 +4233,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
|
||||||
|
|
||||||
// Range checking and option assignments
|
// Range checking and option assignments
|
||||||
ps->o.fade_delta = max_i(ps->o.fade_delta, 1);
|
ps->o.fade_delta = max_i(ps->o.fade_delta, 1);
|
||||||
ps->o.shadow_radius = max_i(ps->o.shadow_radius, 1);
|
ps->o.shadow_radius = max_i(ps->o.shadow_radius, 0);
|
||||||
ps->o.shadow_red = normalize_d(ps->o.shadow_red);
|
ps->o.shadow_red = normalize_d(ps->o.shadow_red);
|
||||||
ps->o.shadow_green = normalize_d(ps->o.shadow_green);
|
ps->o.shadow_green = normalize_d(ps->o.shadow_green);
|
||||||
ps->o.shadow_blue = normalize_d(ps->o.shadow_blue);
|
ps->o.shadow_blue = normalize_d(ps->o.shadow_blue);
|
||||||
|
|
Loading…
Reference in New Issue