Skip to content

Commit

Permalink
Moving examples
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Jan 30, 2024
1 parent 1d6113c commit 4011e13
Show file tree
Hide file tree
Showing 7 changed files with 1,928 additions and 1,934 deletions.
4 changes: 2 additions & 2 deletions apps/yconverts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
using namespace yocto;
using namespace std::string_literals;

vector<string> shape_stats(const shape_data& shape, bool verbose) {
vector<string> shape_stats(const shape_data& shape, bool verbose = false) {
auto format = [](auto num) {
auto str = std::to_string(num);
while (str.size() < 13) str = " " + str;
Expand Down Expand Up @@ -71,7 +71,7 @@ vector<string> shape_stats(const shape_data& shape, bool verbose) {
return stats;
}

vector<string> fvshape_stats(const fvshape_data& shape, bool verbose) {
vector<string> fvshape_stats(const fvshape_data& shape, bool verbose = false) {
auto format = [](auto num) {
auto str = std::to_string(num);
while (str.size() < 13) str = " " + str;
Expand Down
330 changes: 0 additions & 330 deletions libs/yocto/yocto_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,333 +181,3 @@ image_t<vec4b> resize_image(const image_t<vec4b>& img, vec2i resize) {
}

} // namespace yocto

// -----------------------------------------------------------------------------
// IMAGE EXAMPLES
// -----------------------------------------------------------------------------
namespace yocto {

// Comvert a bump map to a normal map.
void bump_to_normal(
image_t<vec4f>& normalmap, const image_t<vec4f>& bumpmap, float scale) {
if (normalmap.size() != bumpmap.size()) normalmap = {bumpmap.size()};
auto dx = 1.0f / bumpmap.size().x, dy = 1.0f / bumpmap.size().y;
auto size = bumpmap.size();
for (auto [i, j] : range(size)) {
auto i1 = (i + 1) % size.x, j1 = (j + 1) % size.y;
auto p00 = bumpmap[{i, j}], p10 = bumpmap[{i1, j}], p01 = bumpmap[{i, j1}];
auto g00 = (p00.x + p00.y + p00.z) / 3;
auto g01 = (p01.x + p01.y + p01.z) / 3;
auto g10 = (p10.x + p10.y + p10.z) / 3;
auto normal = vec3f{
scale * (g00 - g10) / dx, scale * (g00 - g01) / dy, 1.0f};
normal.y = -normal.y; // make green pointing up, even if y axis
// points down
normal = normalize(normal) * 0.5f + vec3f{0.5f, 0.5f, 0.5f};
normalmap[{i, j}] = {normal.x, normal.y, normal.z, 1};
}
}
image_t<vec4f> bump_to_normal(const image_t<vec4f>& bumpmap, float scale) {
auto normalmap = image_t<vec4f>{bumpmap.size()};
bump_to_normal(normalmap, bumpmap, scale);
return normalmap;
}

template <typename Shader>
static image_t<vec4f> make_proc_image(vec2i size, Shader&& shader) {
auto image_ = image_t<vec4f>{size};
auto scale = 1.0f / max(size);
for (auto ij : range(size)) {
image_[ij] = shader((vec2f)ij * scale);
}
return image_;
}

// Make an image
image_t<vec4f> make_grid(vec2i size, float scale, vec4f color0, vec4f color1) {
return make_proc_image(size, [=](vec2f uv) {
uv *= 4 * scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
auto thick = 0.01f / 2;
auto c = uv.x <= thick || uv.x >= 1 - thick || uv.y <= thick ||
uv.y >= 1 - thick ||
(uv.x >= 0.5f - thick && uv.x <= 0.5f + thick) ||
(uv.y >= 0.5f - thick && uv.y <= 0.5f + thick);
return c ? color0 : color1;
});
}

image_t<vec4f> make_checker(
vec2i size, float scale, vec4f color0, vec4f color1) {
return make_proc_image(size, [=](vec2f uv) {
uv *= 4 * scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
auto c = uv.x <= 0.5f != uv.y <= 0.5f;
return c ? color0 : color1;
});
}

image_t<vec4f> make_bumps(vec2i size, float scale, vec4f color0, vec4f color1) {
return make_proc_image(size, [=](vec2f uv) {
uv *= 4 * scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
auto thick = 0.125f;
auto center = vec2f{
uv.x <= 0.5f ? 0.25f : 0.75f,
uv.y <= 0.5f ? 0.25f : 0.75f,
};
auto dist = clamp(length(uv - center), 0.0f, thick) / thick;
auto val = uv.x <= 0.5f != uv.y <= 0.5f ? (1 + sqrt(1 - dist)) / 2
: (dist * dist) / 2;
return lerp(color0, color1, val);
});
}

image_t<vec4f> make_ramp(vec2i size, float scale, vec4f color0, vec4f color1) {
return make_proc_image(size, [=](vec2f uv) {
uv *= scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
return lerp(color0, color1, uv.x);
});
}

image_t<vec4f> make_gammaramp(
vec2i size, float scale, vec4f color0, vec4f color1) {
return make_proc_image(size, [=](vec2f uv) {
uv *= scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
if (uv.y < 1 / 3.0f) {
return lerp(color0, color1, pow(uv.x, 2.2f));
} else if (uv.y < 2 / 3.0f) {
return lerp(color0, color1, uv.x);
} else {
return lerp(color0, color1, pow(uv.x, 1 / 2.2f));
}
});
}

image_t<vec4f> make_uvramp(vec2i size, float scale) {
return make_proc_image(size, [=](vec2f uv) {
uv *= scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
return vec4f{uv.x, uv.y, 0, 1};
});
}

image_t<vec4f> make_uvgrid(vec2i size, float scale, bool colored) {
return make_proc_image(size, [=](vec2f uv) {
uv *= scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
uv.y = 1 - uv.y;
auto hsv = vec3f{0, 0, 0};
hsv.x = (clamp((int)(uv.x * 8), 0, 7) +
(clamp((int)(uv.y * 8), 0, 7) + 5) % 8 * 8) /
64.0f;
auto vuv = uv * 4;
vuv -= vec2f{(float)(int)vuv.x, (float)(int)vuv.y};
auto vc = vuv.x <= 0.5f != vuv.y <= 0.5f;
hsv.z = vc ? 0.5f - 0.05f : 0.5f + 0.05f;
auto suv = uv * 16;
suv -= vec2f{(float)(int)suv.x, (float)(int)suv.y};
auto st = 0.01f / 2;
auto sc = suv.x <= st || suv.x >= 1 - st || suv.y <= st || suv.y >= 1 - st;
if (sc) {
hsv.y = 0.2f;
hsv.z = 0.8f;
} else {
hsv.y = 0.8f;
}
auto rgb = (colored) ? hsv_to_rgb(hsv) : vec3f{hsv.z, hsv.z, hsv.z};
return vec4f{rgb.x, rgb.y, rgb.z, 1};
});
}

image_t<vec4f> make_colormapramp(vec2i size, float scale) {
return make_proc_image(size, [=](vec2f uv) {
uv *= scale;
uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y};
auto rgb = vec3f{0, 0, 0};
if (uv.y < 0.25) {
rgb = colormap(uv.x, colormap_type::viridis);
} else if (uv.y < 0.50) {
rgb = colormap(uv.x, colormap_type::plasma);
} else if (uv.y < 0.75) {
rgb = colormap(uv.x, colormap_type::magma);
} else {
rgb = colormap(uv.x, colormap_type::inferno);
}
return vec4f{rgb.x, rgb.y, rgb.z, 1};
});
}

// Add image border
image_t<vec4f> add_border(
const image_t<vec4f>& image, float width, vec4f color) {
auto result = image;
auto scale = 1.0f / max(image.size());
for (auto ij : range(image.size())) {
auto uv = (vec2f)ij * scale;
if (uv.x < width || uv.y < width || uv.x > image.size().x * scale - width ||
uv.y > image.size().y * scale - width) {
result[ij] = color;
}
}
return result;
}

// Implementation of sunsky modified heavily from pbrt
image_t<vec4f> make_sunsky(vec2i size, float theta_sun, float turbidity,
bool has_sun, float sun_intensity, float sun_radius, vec3f ground_albedo) {
auto zenith_xyY = vec3f{
(+0.00165f * pow(theta_sun, 3.f) - 0.00374f * pow(theta_sun, 2.f) +
0.00208f * theta_sun + 0.00000f) *
pow(turbidity, 2.f) +
(-0.02902f * pow(theta_sun, 3.f) + 0.06377f * pow(theta_sun, 2.f) -
0.03202f * theta_sun + 0.00394f) *
turbidity +
(+0.11693f * pow(theta_sun, 3.f) - 0.21196f * pow(theta_sun, 2.f) +
0.06052f * theta_sun + 0.25885f),
(+0.00275f * pow(theta_sun, 3.f) - 0.00610f * pow(theta_sun, 2.f) +
0.00316f * theta_sun + 0.00000f) *
pow(turbidity, 2.f) +
(-0.04214f * pow(theta_sun, 3.f) + 0.08970f * pow(theta_sun, 2.f) -
0.04153f * theta_sun + 0.00515f) *
turbidity +
(+0.15346f * pow(theta_sun, 3.f) - 0.26756f * pow(theta_sun, 2.f) +
0.06669f * theta_sun + 0.26688f),
1000 * (4.0453f * turbidity - 4.9710f) *
tan((4.0f / 9.0f - turbidity / 120.0f) * (pif - 2 * theta_sun)) -
.2155f * turbidity + 2.4192f,
};

auto perez_A_xyY = vec3f{-0.01925f * turbidity - 0.25922f,
-0.01669f * turbidity - 0.26078f, +0.17872f * turbidity - 1.46303f};
auto perez_B_xyY = vec3f{-0.06651f * turbidity + 0.00081f,
-0.09495f * turbidity + 0.00921f, -0.35540f * turbidity + 0.42749f};
auto perez_C_xyY = vec3f{-0.00041f * turbidity + 0.21247f,
-0.00792f * turbidity + 0.21023f, -0.02266f * turbidity + 5.32505f};
auto perez_D_xyY = vec3f{-0.06409f * turbidity - 0.89887f,
-0.04405f * turbidity - 1.65369f, +0.12064f * turbidity - 2.57705f};
auto perez_E_xyY = vec3f{-0.00325f * turbidity + 0.04517f,
-0.01092f * turbidity + 0.05291f, -0.06696f * turbidity + 0.37027f};

auto perez_f = [](vec3f A, vec3f B, vec3f C, vec3f D, vec3f E, float theta,
float gamma, float theta_sun, vec3f zenith) -> vec3f {
auto num = ((1 + A * exp(B / cos(theta))) *
(1 + C * exp(D * gamma) + E * cos(gamma) * cos(gamma)));
auto den = ((1 + A * exp(B)) * (1 + C * exp(D * theta_sun) +
E * cos(theta_sun) * cos(theta_sun)));
return zenith * num / den;
};

auto sky = [&perez_f, perez_A_xyY, perez_B_xyY, perez_C_xyY, perez_D_xyY,
perez_E_xyY, zenith_xyY](
float theta, float gamma, float theta_sun) -> vec3f {
return xyz_to_rgb(xyY_to_xyz(
perez_f(perez_A_xyY, perez_B_xyY, perez_C_xyY, perez_D_xyY,
perez_E_xyY, theta, gamma, theta_sun, zenith_xyY))) /
10000;
};

// compute sun luminance
auto sun_ko = vec3f{0.48f, 0.75f, 0.14f};
auto sun_kg = vec3f{0.1f, 0.0f, 0.0f};
auto sun_kwa = vec3f{0.02f, 0.0f, 0.0f};
auto sun_sol = vec3f{20000.0f, 27000.0f, 30000.0f};
auto sun_lambda = vec3f{680, 530, 480};
auto sun_beta = 0.04608365822050f * turbidity - 0.04586025928522f;
auto sun_m = 1.0f /
(cos(theta_sun) + 0.000940f * pow(1.6386f - theta_sun, -1.253f));

auto tauR = exp(-sun_m * 0.008735f * pow(sun_lambda / 1000, -4.08f));
auto tauA = exp(-sun_m * sun_beta * pow(sun_lambda / 1000, -1.3f));
auto tauO = exp(-sun_m * sun_ko * .35f);
auto tauG = exp(
-1.41f * sun_kg * sun_m / pow(1 + 118.93f * sun_kg * sun_m, 0.45f));
auto tauWA = exp(-0.2385f * sun_kwa * 2.0f * sun_m /
pow(1 + 20.07f * sun_kwa * 2.0f * sun_m, 0.45f));
auto sun_le = sun_sol * tauR * tauA * tauO * tauG * tauWA * 10000;

// rescale by user
sun_le *= sun_intensity;

// sun scale from Wikipedia scaled by user quantity and rescaled to at
// the minimum 5 pixel diamater
auto sun_angular_radius = 9.35e-03f / 2; // Wikipedia
sun_angular_radius *= sun_radius;
sun_angular_radius = max(sun_angular_radius, 2 * pif / size.y);

// sun direction
auto sun_direction = vec3f{0, cos(theta_sun), sin(theta_sun)};

auto sun = [has_sun, sun_angular_radius, sun_le](auto theta, auto gamma) {
return (has_sun && gamma < sun_angular_radius) ? sun_le / 10000
: vec3f{0, 0, 0};
};

// Make the sun sky image
auto img = image_t<vec4f>{size};
for (auto j = 0; j < size.y / 2; j++) {
auto theta = pif * ((j + 0.5f) / size.y);
theta = clamp(theta, 0.0f, pif / 2 - flt_eps);
for (int i = 0; i < size.x; i++) {
auto phi = 2 * pif * (float(i + 0.5f) / size.x);
auto w = vec3f{cos(phi) * sin(theta), cos(theta), sin(phi) * sin(theta)};
auto gamma = acos(clamp(dot(w, sun_direction), -1.0f, 1.0f));
auto sky_col = sky(theta, gamma, theta_sun);
auto sun_col = sun(theta, gamma);
auto col = sky_col + sun_col;
img[{i, j}] = {col.x, col.y, col.z, 1};
}
}

if (ground_albedo != vec3f{0, 0, 0}) {
auto ground = vec3f{0, 0, 0};
for (auto j = 0; j < size.y / 2; j++) {
auto theta = pif * ((j + 0.5f) / size.y);
for (int i = 0; i < size.x; i++) {
auto pxl = img[{i, j}];
auto le = vec3f{pxl.x, pxl.y, pxl.z};
auto angle = sin(theta) * 4 * pif / (size.x * size.y);
ground += le * (ground_albedo / pif) * cos(theta) * angle;
}
}
for (auto j = size.y / 2; j < size.y; j++) {
for (int i = 0; i < size.x; i++) {
img[{i, j}] = {ground.x, ground.y, ground.z, 1};
}
}
} else {
for (auto j = size.y / 2; j < size.y; j++) {
for (int i = 0; i < size.x; i++) {
img[{i, j}] = {0, 0, 0, 1};
}
}
}

// done
return img;
}

// Make an image of multiple lights.
image_t<vec4f> make_lights(vec2i size, vec3f le, int nlights, float langle,
float lwidth, float lheight) {
auto img = image_t<vec4f>{size};
for (auto j = 0; j < size.y / 2; j++) {
auto theta = pif * ((j + 0.5f) / size.y);
theta = clamp(theta, 0.0f, pif / 2 - 0.00001f);
if (fabs(theta - langle) > lheight / 2) continue;
for (int i = 0; i < size.x; i++) {
auto phi = 2 * pif * (float(i + 0.5f) / size.x);
auto inlight = false;
for (auto l : range(nlights)) {
auto lphi = 2 * pif * (l + 0.5f) / nlights;
inlight = inlight || fabs(phi - lphi) < lwidth / 2;
}
img[{i, j}] = {le.x, le.y, le.z, 1};
}
}
return img;
}

} // namespace yocto
Loading

0 comments on commit 4011e13

Please sign in to comment.