@@ -24,8 +24,7 @@ struct Params {
24
24
};
25
25
26
26
fn sdf(p: vec3<f32>, c: vec3<f32>, r: f32) -> f32 {
27
- let l: vec3<f32> = p - c;
28
- return sqrt(l.x * l.x + l.y * l.y + l.z * l.z) - r;
27
+ return length(p - c) - r;
29
28
}
30
29
31
30
@compute @workgroup_size(16, 16)
@@ -34,44 +33,40 @@ fn main(@builtin(global_invocation_id) GlobalInvocationID: vec3<u32>) {
34
33
|| GlobalInvocationID.y >= params.screenHeight) {
35
34
return;
36
35
}
36
+ let id: u32 = GlobalInvocationID.y * params.screenWidth + GlobalInvocationID.x;
37
37
38
38
let x: f32 = f32(GlobalInvocationID.x);
39
39
let y: f32 = f32(GlobalInvocationID.y);
40
40
41
41
// ray position, starting at the camera
42
- var p: vec3<f32> = vec3<f32>((x / f32(params.screenWidth)) * 2 .0 - 1 .0,
42
+ var p: vec3<f32> = vec3<f32>((x / f32(params.screenWidth)) * 4 .0 - 2 .0,
43
43
(y / f32(params.screenHeight)) * 2.0 - 1.0,
44
44
params.focalLength);
45
45
46
- let len: f32 = length(p);
47
- let dir: vec3<f32> = vec3<f32>(p.x / len, p.y / len, p.z / len);
46
+ let dir: vec3<f32> = p / length(p); // direction from focal point to pixel
48
47
49
48
// object dynamics
50
- // let offsetX: f32 = sin(f32(params.time) / 200) * 6.0;
51
- // let offsetY: f32 = cos(f32(params.time) / 200) * 6.0;
52
- let offsetX: f32 = 0.0;
53
- let offsetY: f32 = 0.0;
54
- let offsetZ: f32 = sin(f32(params.time) / 400) * 2.0;
55
- // let offsetZ: f32 = 0.0;
49
+ var offsetX: f32 = sin(f32(params.time) / 750) * 0.5;
50
+ var offsetY: f32 = cos(f32(params.time) / 750) * 0.5;
51
+ var offsetZ: f32 = sin(f32(params.time) / 1000) * 1.0;
56
52
let c: vec3<f32> = vec3<f32>(params.sphereCenterX + offsetX,
57
53
params.sphereCenterY + offsetY,
58
54
params.sphereCenterZ + offsetZ);
59
55
60
56
let dist: f32 = 0.0;
61
- out[GlobalInvocationID.y * params.screenWidth + GlobalInvocationID.x] = 0.0;
62
-
63
- let maxIter: u32 = 10;
57
+ out[id] = 0.0;
64
58
59
+ let maxIter: u32 = 30;
65
60
// march the ray in the direction of dir by length derived by the SDF
66
61
for (var i: u32 = 0; i < maxIter; i++) {
67
62
// largest step we can take w/o intersection is = SDF value at point
68
63
let step : f32 = sdf(p, c, params.sphereRadius);
69
64
if (abs(step) < .001) {
70
65
return;
71
66
}
72
- out[GlobalInvocationID.y * params.screenWidth + GlobalInvocationID.x ] =
73
- max(0, min(10 .0, out[GlobalInvocationID.y * params.screenWidth + GlobalInvocationID.x ] + step));
74
- if (out[GlobalInvocationID.y * params.screenWidth + GlobalInvocationID.x ] == 10.0) {
67
+ out[id ] =
68
+ max(0, min(5 .0, out[id ] + step));
69
+ if (out[id ] == 10.0) {
75
70
return;
76
71
}
77
72
p = p + dir * step;
@@ -103,13 +98,13 @@ int main(int argc, char **argv) {
103
98
float sphereCenterY;
104
99
float sphereCenterZ;
105
100
uint32_t time;
106
- } params = {/* focal length */ 0.2 ,
101
+ } params = {/* focal length */ 1.0 ,
107
102
NCOLS,
108
103
NROWS,
109
- /* radius */ 2 .0 ,
104
+ /* radius */ 1 .0 ,
110
105
/* x */ 0.0 ,
111
106
/* y */ 0.0 ,
112
- /* z */ 5.0 ,
107
+ /* z */ 2.5 ,
113
108
0 };
114
109
115
110
std::fill (begin (screen), end (screen), 0 .0f );
@@ -122,36 +117,36 @@ int main(int argc, char **argv) {
122
117
params.time = getCurrentTimeInMilliseconds () - zeroTime;
123
118
Kernel render =
124
119
CreateKernel (ctx, CreateShader (kSDF ), {}, 0 , devScreen, params);
125
- // ToGPU(ctx, ¶ms, render.buffers[render.numBuffers - 1],
126
- // sizeof(params));
127
120
DispatchKernel (ctx, render);
128
121
Wait (ctx, render.future );
129
122
ToCPU (ctx, devScreen, screen.data (), sizeof (screen));
130
123
131
- static const char intensity[] = " @%#*+=-:. " ;
124
+ static const char intensity[] = " @%#8X7x*+=-:^~'.` " ;
125
+
132
126
// clear the screen, move cursor to the top
133
127
printf (" \033 [2J\033 [H" );
134
128
135
129
fprintf (stdout, " %s" ,
136
130
show<float , NROWS, NCOLS>(screen, " Raw values" ).c_str ());
137
131
138
132
// normalize values
139
- // float min = *std::min_element(screen.begin(), screen.end());
140
- // float max = *std::max_element(screen.begin(), screen.end());
141
- float min = 0.0 ;
142
- float max = 10.0 ;
133
+ float min = *std::min_element (screen.begin (), screen.end ());
134
+ float max = min + params.sphereRadius ; // maximize dynamic range
143
135
144
136
for (size_t i = 0 ; i < screen.size (); ++i) {
145
137
screen[i] = (screen[i] - min) / (max - min);
146
138
}
147
139
fprintf (stdout, " %s" ,
148
- show<float , NROWS, NCOLS>(screen, " Normalized " ).c_str ());
140
+ show<float , NROWS, NCOLS>(screen, " Scaled " ).c_str ());
149
141
150
142
// index into intensity array
151
- std::array<char , NROWS *(NCOLS + 1 )> raster;
143
+ std::array<char , screen. size ( )> raster;
152
144
for (size_t i = 0 ; i < screen.size (); ++i) {
153
- raster[i] =
154
- intensity[static_cast <size_t >(screen[i] * (sizeof (intensity) - 1 ))];
145
+ size_t index =
146
+ std::min (sizeof (intensity) - 2 ,
147
+ std::max (0ul , static_cast <size_t >(screen[i] *
148
+ (sizeof (intensity) - 2 ))));
149
+ raster[i] = intensity[index ];
155
150
}
156
151
157
152
for (size_t row = 0 ; row < NROWS; ++row) {
0 commit comments