Skip to content

Commit ec76cc5

Browse files
committed
fix up sdf example - scaling index bug resolved
1 parent 9af7a65 commit ec76cc5

File tree

1 file changed

+26
-31
lines changed

1 file changed

+26
-31
lines changed

examples/raymarch/run.cpp

+26-31
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ struct Params {
2424
};
2525
2626
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;
2928
}
3029
3130
@compute @workgroup_size(16, 16)
@@ -34,44 +33,40 @@ fn main(@builtin(global_invocation_id) GlobalInvocationID: vec3<u32>) {
3433
|| GlobalInvocationID.y >= params.screenHeight) {
3534
return;
3635
}
36+
let id: u32 = GlobalInvocationID.y * params.screenWidth + GlobalInvocationID.x;
3737
3838
let x: f32 = f32(GlobalInvocationID.x);
3939
let y: f32 = f32(GlobalInvocationID.y);
4040
4141
// 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,
4343
(y / f32(params.screenHeight)) * 2.0 - 1.0,
4444
params.focalLength);
4545
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
4847
4948
// 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;
5652
let c: vec3<f32> = vec3<f32>(params.sphereCenterX + offsetX,
5753
params.sphereCenterY + offsetY,
5854
params.sphereCenterZ + offsetZ);
5955
6056
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;
6458
59+
let maxIter: u32 = 30;
6560
// march the ray in the direction of dir by length derived by the SDF
6661
for (var i: u32 = 0; i < maxIter; i++) {
6762
// largest step we can take w/o intersection is = SDF value at point
6863
let step : f32 = sdf(p, c, params.sphereRadius);
6964
if (abs(step) < .001) {
7065
return;
7166
}
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) {
7570
return;
7671
}
7772
p = p + dir * step;
@@ -103,13 +98,13 @@ int main(int argc, char **argv) {
10398
float sphereCenterY;
10499
float sphereCenterZ;
105100
uint32_t time;
106-
} params = {/* focal length */ 0.2,
101+
} params = {/* focal length */ 1.0,
107102
NCOLS,
108103
NROWS,
109-
/* radius */ 2.0,
104+
/* radius */ 1.0,
110105
/* x */ 0.0,
111106
/* y */ 0.0,
112-
/* z */ 5.0,
107+
/* z */ 2.5,
113108
0};
114109

115110
std::fill(begin(screen), end(screen), 0.0f);
@@ -122,36 +117,36 @@ int main(int argc, char **argv) {
122117
params.time = getCurrentTimeInMilliseconds() - zeroTime;
123118
Kernel render =
124119
CreateKernel(ctx, CreateShader(kSDF), {}, 0, devScreen, params);
125-
// ToGPU(ctx, &params, render.buffers[render.numBuffers - 1],
126-
// sizeof(params));
127120
DispatchKernel(ctx, render);
128121
Wait(ctx, render.future);
129122
ToCPU(ctx, devScreen, screen.data(), sizeof(screen));
130123

131-
static const char intensity[] = "@%#*+=-:. ";
124+
static const char intensity[] = "@%#8X7x*+=-:^~'.` ";
125+
132126
// clear the screen, move cursor to the top
133127
printf("\033[2J\033[H");
134128

135129
fprintf(stdout, "%s",
136130
show<float, NROWS, NCOLS>(screen, "Raw values").c_str());
137131

138132
// 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
143135

144136
for (size_t i = 0; i < screen.size(); ++i) {
145137
screen[i] = (screen[i] - min) / (max - min);
146138
}
147139
fprintf(stdout, "%s",
148-
show<float, NROWS, NCOLS>(screen, "Normalized").c_str());
140+
show<float, NROWS, NCOLS>(screen, "Scaled").c_str());
149141

150142
// index into intensity array
151-
std::array<char, NROWS *(NCOLS + 1)> raster;
143+
std::array<char, screen.size()> raster;
152144
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];
155150
}
156151

157152
for (size_t row = 0; row < NROWS; ++row) {

0 commit comments

Comments
 (0)