Created
August 3, 2017 17:29
-
-
Save alaingalvan/46366c71a62459ef7b8d0407c8cd0c5e to your computer and use it in GitHub Desktop.
Some bevel shader magic. :3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void rng_seed(output int rng, int seed) | |
{ | |
int chash = seed; | |
if (chash == 0) chash = 1; | |
rng = chash * 30391861; | |
} | |
float rng_uniform(output int rng) | |
{ | |
float res = rng / float(2137483647) * 0.5 + 0.5; | |
rng *= 30391861; | |
return res; | |
} | |
void to_unit_disk(float x, float y, output float x_out, output float y_out) | |
{ | |
float r, phi; | |
float a = 2.0 * x - 1.0; | |
float b = 2.0 * y - 1.0; | |
if(a > -b) | |
{ if(a > b) | |
{ r = a; | |
phi = M_PI_4 *(b/a); | |
} | |
else | |
{ r = b; | |
phi = M_PI_4 *(2.0 - a/b); | |
} } | |
else | |
{ if(a < b) | |
{ r = -a; | |
phi = M_PI_4 *(4.0 + b/a); | |
} | |
else | |
{ r = -b; | |
if(b != 0.0) phi = M_PI_4 *(6.0 - a/b); | |
else phi = 0.0; | |
} } | |
x_out = r * cos(phi); | |
y_out = r * sin(phi); | |
} | |
void make_orthonormals(vector N, output vector a, output vector b) | |
{ | |
if(N[0] != N[1] || N[0] != N[2]) a = cross(vector(1, 1, 1), N); | |
else a = cross(vector(-1, 1, 1), N); | |
a = normalize(a); | |
b = cross(N, a); | |
} | |
vector sample_cos_hemisphere(vector N, float randu, float randv) | |
{ | |
vector T, B; | |
make_orthonormals(N, T, B); | |
to_unit_disk(randu, randv, randu, randv); | |
float costheta = sqrt(max(1.0 - randu * randu - randv * randv, 0.0)); | |
return randu * T + randv * B + costheta * N; | |
} | |
shader node_occlusion2( | |
color Effect = color(0), | |
color No_Effect = color(1), | |
int Mode = 0, /* 0: Concave (AO) 1:Convex (Wear) 2:Both */ | |
int InvertEffect = 0, | |
float Distance = 0.2, | |
int Samples = 1, | |
output color Color = 0, | |
output float Fac = 0, | |
output normal outNormal = N | |
) | |
{ | |
int i, rng; | |
float f, randu, randv, ray_t, hits = 0; | |
vector ray_P, ray_R; | |
normal hit_normal = N; | |
float hit_dist; | |
f = fmod(cellnoise(P*123456.0), 1.0); | |
rng_seed(rng, int(f * 21374647)); | |
for(i = 0; i < Samples; i++) | |
{ randu = rng_uniform(rng); | |
randv = rng_uniform(rng); | |
ray_P = P; | |
ray_R = sample_cos_hemisphere(-N, randu, randv); | |
ray_t = Distance; | |
if (!Mode) | |
{ if(trace(ray_P, -ray_R, "maxdist", ray_t)) { | |
hits += 1.0; | |
int HitNormal = getmessage ("trace", "N", hit_normal); | |
outNormal = outNormal + (hit_normal); | |
} | |
} | |
else if (Mode == 1) | |
{ if(trace(ray_P, ray_R, "maxdist", ray_t)) { | |
hits += 1.0; | |
int HitNormal = getmessage ("trace", "N", hit_normal); | |
outNormal = outNormal - (hit_normal); | |
} | |
} | |
else { | |
if(trace(ray_P, -ray_R, "maxdist", ray_t)) { | |
hits += 1.0; | |
int HitNormal = getmessage ("trace", "N", hit_normal); | |
outNormal = outNormal + (hit_normal); | |
} | |
if(trace(ray_P, ray_R, "maxdist", ray_t)) { | |
hits += 1.0; | |
int HitNormal = getmessage ("trace", "N", hit_normal); | |
outNormal = outNormal - (hit_normal); | |
} | |
} | |
} | |
Fac = 1.0 - (hits/Samples); | |
if(InvertEffect) Color = mix(No_Effect, Effect, Fac); | |
else Color = mix(Effect, No_Effect, Fac); | |
outNormal = normalize(outNormal); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment