-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathhumanshader.c
113 lines (98 loc) · 2.69 KB
/
humanshader.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// C version of humanshader
// See https://humanshader.com/
// (using a computer is clearly not as fun, but it is interesting to have
// a small not too computationally expensive raytracing program that
// can run on small softcores for PGAs).
// Using the 16-bits version with no divide from here: https://www.shadertoy.com/view/XflXDs
#define GL_width 71
#define GL_height 40
#include "GL_tty.h"
void human_shader(
int x, int y, uint8_t* r_out, uint8_t* g_out, uint8_t* b_out
) {
int R, B;
//-------------------------
// Section A (2 MUL, 3 ADD)
//-------------------------
int u = x-36;
int v = 18-y;
int u2 = u*u;
int v2 = v*v;
int h = u2 + v2;
//-------------------------
if( h < 200 )
{
//-------------------------------------
// Section B, Sphere (4/7 MUL, 5/9 ADD)
//-------------------------------------
R = 420;
B = 520;
int t = 5200 + (h<<3);
int p = (t*u)>>7;
int q = (t*v)>>7;
// bounce light
int w = 18 + (((p*5-q*13))>>9);
if( w>0 ) R += w*w;
// sky light / ambient occlusion
int o = q + 900;
R = (R*o)>>12;
B = (B*o)>>12;
// sun/key light
if( p > -q )
{
int w = (p+q)>>3;
R += w;
B += w;
}
//-------------------------
}
else if( v<0 )
{
//-------------------------------------
// Section C, Ground (5/9 MUL, 6/9 ADD)
//-------------------------------------
R = 150 + (v<<1);
B = 50;
int p = h + (v2<<3);
int c = 240*(-v) - p;
// sky light / ambient occlusion
if( c>1200 )
{
int o = (25*c)>>3;
o = (c*(7840-o)>>9) - 8560;
R = (R*o)>>10;
B = (B*o)>>10;
}
// sun/key light with soft shadow
int r = c + u*v;
int d = 3200 - h - (r<<1);
if( d>0 ) R += d;
//-------------------------
}
else
{
//------------------------------
// Section D, Sky (1 MUL, 2 ADD)
//------------------------------
int c = x + (y<<2);
R = 132 + c;
B = 192 + c;
//-------------------------
}
//-------------------------
// Section E (3 MUL, 1 ADD)
//-------------------------
if(R > 255) R = 255;
if(B > 255) B = 255;
int G = (R*11 + 5*B)>>4;
//-------------------------
*r_out = (uint8_t)R;
*g_out = (uint8_t)G;
*b_out = (uint8_t)B;
}
int main() {
GL_init();
GL_scan_RGB(GL_width, GL_height, human_shader);
GL_terminate();
return 0;
}