Skip to content

Commit

Permalink
Add 9 lights.
Browse files Browse the repository at this point in the history
  • Loading branch information
kugimasa committed Aug 26, 2023
1 parent 819d7ac commit 81c1576
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 26 deletions.
94 changes: 77 additions & 17 deletions resources/shader/compute-sample.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ struct SphereLights {
l2 : Sphere,
l3 : Sphere,
l4 : Sphere,
l5 : Sphere,
l6 : Sphere,
l7 : Sphere,
l8 : Sphere,
l9 : Sphere,
}

fn fabs(x: f32) -> f32 {
Expand Down Expand Up @@ -165,26 +170,60 @@ fn sample_direction(hit: HitInfo) -> vec3f {
fn sample_from_light(hit: HitInfo) -> vec3f {
// ヒット位置とライト位置を比較
// FIXME: ライトの個数分追加が必要
var l1_dist = distance(hit.pos, sphere_lights.l1.center);
let l1_dist = distance(hit.pos, sphere_lights.l1.center);
let l2_dist = distance(hit.pos, sphere_lights.l2.center);
let l3_dist = distance(hit.pos, sphere_lights.l3.center);
let l4_dist = distance(hit.pos, sphere_lights.l4.center);
let l1_w = 1.0 / (l1_dist * l1_dist);
let l2_w = 1.0 / (l2_dist * l2_dist);
let l3_w = 1.0 / (l3_dist * l3_dist);
let l4_w = 1.0 / (l4_dist * l4_dist);
let sum = l1_w + l2_w + l3_w + l4_w;
var l5_dist = distance(hit.pos, sphere_lights.l5.center);
let l6_dist = distance(hit.pos, sphere_lights.l6.center);
let l7_dist = distance(hit.pos, sphere_lights.l7.center);
let l8_dist = distance(hit.pos, sphere_lights.l8.center);
let l9_dist = distance(hit.pos, sphere_lights.l9.center);
let l1_w = select(0.0, 1.0 / (l1_dist * l1_dist), sphere_lights.l1.emissive > 0.0f);
let l2_w = select(0.0, 1.0 / (l2_dist * l2_dist), sphere_lights.l2.emissive > 0.0f);
let l3_w = select(0.0, 1.0 / (l3_dist * l3_dist), sphere_lights.l3.emissive > 0.0f);
let l4_w = select(0.0, 1.0 / (l4_dist * l4_dist), sphere_lights.l4.emissive > 0.0f);
let l5_w = select(0.0, 1.0 / (l5_dist * l5_dist), sphere_lights.l5.emissive > 0.0f);
let l6_w = select(0.0, 1.0 / (l6_dist * l6_dist), sphere_lights.l6.emissive > 0.0f);
let l7_w = select(0.0, 1.0 / (l7_dist * l7_dist), sphere_lights.l7.emissive > 0.0f);
let l8_w = select(0.0, 1.0 / (l8_dist * l8_dist), sphere_lights.l8.emissive > 0.0f);
let l9_w = select(0.0, 1.0 / (l9_dist * l9_dist), sphere_lights.l9.emissive > 0.0f);
let sum = l1_w + l2_w + l3_w + l4_w + l5_w + l6_w + l7_w + l8_w + l9_w;
let l1_t = l1_w / sum;
let l2_t = l1_t + l2_w / sum;
let l3_t = l2_t + l3_w / sum;
let l4_t = l3_t + l4_w / sum;
let l5_t = l4_t + l5_w / sum;
let l6_t = l5_t + l6_w / sum;
let l7_t = l6_t + l7_w / sum;
let l8_t = l7_t + l8_w / sum;
let l9_t = l8_t + l9_w / sum;
let rand = rand();
var sphere = sphere_lights.l1;
if (l1_w / sum < rand && rand <= (l1_w + l2_w) / sum) {
if (l1_t < rand && rand <= l2_t) {
sphere = sphere_lights.l2;
}
if ((l1_w + l2_w) / sum < rand && rand <= (l1_w + l2_w + l3_w) / sum) {
if (l2_t < rand && rand <= l3_t) {
sphere = sphere_lights.l3;
}
if ((l1_w + l2_w + l3_w) / sum < rand && rand <= 1.0) {
if (l3_t < rand && rand <= l4_t) {
sphere = sphere_lights.l4;
}
if (l4_t < rand && rand <= l5_t) {
sphere = sphere_lights.l5;
}
if (l5_t < rand && rand <= l6_t) {
sphere = sphere_lights.l6;
}
if (l6_t < rand && rand <= l7_t) {
sphere = sphere_lights.l7;
}
if (l7_t < rand && rand <= l8_t) {
sphere = sphere_lights.l8;
}
if (l8_t < rand && rand <= l9_t) {
sphere = sphere_lights.l9;
}
return sample_from_sphere(sphere, hit.pos);
}

Expand Down Expand Up @@ -218,19 +257,34 @@ fn sample_from_cosine(hit: HitInfo) -> vec3f {

fn mixture_pdf(hit: HitInfo, dir: vec3f) -> f32 {
// FIXME: ライトの個数分追加が必要
var l1_dist = distance(hit.pos, sphere_lights.l1.center);
let l1_dist = distance(hit.pos, sphere_lights.l1.center);
let l2_dist = distance(hit.pos, sphere_lights.l2.center);
let l3_dist = distance(hit.pos, sphere_lights.l3.center);
let l4_dist = distance(hit.pos, sphere_lights.l4.center);
let l1_w = 1.0 / (l1_dist * l1_dist);
let l2_w = 1.0 / (l2_dist * l2_dist);
let l3_w = 1.0 / (l3_dist * l3_dist);
let l4_w = 1.0 / (l4_dist * l4_dist);
let sum = l1_w + l2_w + l3_w + l4_w;
var l5_dist = distance(hit.pos, sphere_lights.l5.center);
let l6_dist = distance(hit.pos, sphere_lights.l6.center);
let l7_dist = distance(hit.pos, sphere_lights.l7.center);
let l8_dist = distance(hit.pos, sphere_lights.l8.center);
let l9_dist = distance(hit.pos, sphere_lights.l9.center);
let l1_w = select(0.0, 1.0 / (l1_dist * l1_dist), sphere_lights.l1.emissive > 0.0f);
let l2_w = select(0.0, 1.0 / (l2_dist * l2_dist), sphere_lights.l2.emissive > 0.0f);
let l3_w = select(0.0, 1.0 / (l3_dist * l3_dist), sphere_lights.l3.emissive > 0.0f);
let l4_w = select(0.0, 1.0 / (l4_dist * l4_dist), sphere_lights.l4.emissive > 0.0f);
let l5_w = select(0.0, 1.0 / (l5_dist * l5_dist), sphere_lights.l5.emissive > 0.0f);
let l6_w = select(0.0, 1.0 / (l6_dist * l6_dist), sphere_lights.l6.emissive > 0.0f);
let l7_w = select(0.0, 1.0 / (l7_dist * l7_dist), sphere_lights.l7.emissive > 0.0f);
let l8_w = select(0.0, 1.0 / (l8_dist * l8_dist), sphere_lights.l8.emissive > 0.0f);
let l9_w = select(0.0, 1.0 / (l9_dist * l9_dist), sphere_lights.l9.emissive > 0.0f);
let sum = l1_w + l2_w + l3_w + l4_w + l5_w + l6_w + l7_w + l8_w + l9_w;
let light_pdf = l1_w * sphere_pdf(hit, sphere_lights.l1, dir) +
l2_w * sphere_pdf(hit, sphere_lights.l2, dir) +
l3_w * sphere_pdf(hit, sphere_lights.l3, dir) +
l4_w * sphere_pdf(hit, sphere_lights.l4, dir);
l4_w * sphere_pdf(hit, sphere_lights.l4, dir) +
l5_w * sphere_pdf(hit, sphere_lights.l5, dir) +
l6_w * sphere_pdf(hit, sphere_lights.l6, dir) +
l7_w * sphere_pdf(hit, sphere_lights.l7, dir) +
l8_w * sphere_pdf(hit, sphere_lights.l8, dir) +
l9_w * sphere_pdf(hit, sphere_lights.l9, dir);
return 0.5 * cosine_pdf(hit, dir) + 0.5 * light_pdf / sum;
}

Expand Down Expand Up @@ -285,8 +339,9 @@ fn raytrace(path: Path, depth: i32) -> Path {
// 光源の場合、トレースを終了
if (emissive) {
if (depth == 0) {
var light_col = hit.col / length(hit.col);
var light_col = hit.col;
let dist = distance(camera.start.xyz, hit.pos.xyz);
light_col = light_col / dist;
return Path(r, light_col, true);
}
// 照明計算
Expand Down Expand Up @@ -323,6 +378,11 @@ fn sample_hit(r: Ray) -> HitInfo {
hit = intersect_sphere(r, sphere_lights.l2, hit);
hit = intersect_sphere(r, sphere_lights.l3, hit);
hit = intersect_sphere(r, sphere_lights.l4, hit);
hit = intersect_sphere(r, sphere_lights.l5, hit);
hit = intersect_sphere(r, sphere_lights.l6, hit);
hit = intersect_sphere(r, sphere_lights.l7, hit);
hit = intersect_sphere(r, sphere_lights.l8, hit);
hit = intersect_sphere(r, sphere_lights.l9, hit);
return hit;
}

Expand Down
3 changes: 2 additions & 1 deletion src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ void Camera::InitBindGroup(Device &device) {

void Camera::Update(Queue &queue, float t, float aspect) {
// カメラ: [前半]InQuart, [後半]等速
float move_dist = t < 0.2f ? 8.0f * EaseInQuart(t / 0.2f) : 8.0f * EaseInQuart((t - 0.2f) / 0.8f + 1.0f);
float end_dist = 8.0f * EaseInQuart((0.95f - 0.2f) / 0.8f + 1.0f);
float move_dist = t < 0.2f ? 8.0f * EaseInQuart(t / 0.2f) : t < 0.95f ? 8.0f * EaseInQuart((t - 0.2f) / 0.8f + 1.0f) : end_dist;
Point3 origin = Vec3(0, 0, 0.01f - move_dist);
Point3 target = Vec3(0, 0, 15 + move_dist);
// fovy変化: 増加は 0.0 ~ 0.15, 減少は 0.95 ~ 1.0
Expand Down
10 changes: 8 additions & 2 deletions src/include/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ class Scene {
Sphere l2_;
Sphere l3_;
Sphere l4_;

SphereLights(Sphere l1, Sphere l2, Sphere l3, Sphere l4) : l1_(l1), l2_(l2), l3_(l3), l4_(l4) {};
Sphere l5_;
Sphere l6_;
Sphere l7_;
Sphere l8_;
Sphere l9_;

SphereLights(Sphere l1, Sphere l2, Sphere l3, Sphere l4, Sphere l5, Sphere l6, Sphere l7, Sphere l8, Sphere l9)
: l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6), l7_(l7), l8_(l8), l9_(l9) {};
};

void Release();
Expand Down
45 changes: 39 additions & 6 deletions src/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Scene::Scene(Device &device) {

/// Sphereの追加
spheres_.emplace_back(Point3(-1.0, 0, -9), 0.3, Color3(0.8, 0.8, 0.8));
// TODO: 光源に変更
// 最終位置
float end_pos = 128;
spheres_.emplace_back(Point3(0.0, 2.0, -(30 + end_pos)), 0.3, Color3(0.8, 0.8, 0.8));
Expand Down Expand Up @@ -335,10 +334,44 @@ void Scene::InitBindGroup(Device &device) {
* SphereLightの更新
*/
void Scene::UpdateSphereLights(Queue &queue, float t) {
Sphere l1(Point3(0.0, 2.0, -120), 0.3, Color3(500, 500, 500), true);
Sphere l2(Point3(0.0, 2.0, -30), 0.3, Color3(2, 150, 2), true);
Sphere l3(Point3(0.0, 2.0, -60), 0.3, Color3(150, 2, 2), true);
Sphere l4(Point3(0.0, 2.0, -90), 0.3, Color3(2, 2, 150), true);
SphereLights lights(l1, l2, l3, l4);
float cam_pos = t < 0.2f ? 8.0f * EaseInQuart(t / 0.2f) : 8.0f * EaseInQuart((t - 0.2f) / 0.8f + 1.0f);
float dist_from_cam = 5.0f;
float move_dist = cam_pos + dist_from_cam;
bool is_on = t < 0.95f;
bool l1_on = is_on && move_dist > 15 - dist_from_cam;
bool l2_on = is_on && move_dist > 30 - dist_from_cam;
bool l3_on = is_on && move_dist > 45 - dist_from_cam;
bool l4_on = is_on && move_dist > 60 - dist_from_cam;
bool l5_on = is_on && move_dist > 75 - dist_from_cam;
bool l6_on = is_on && move_dist > 90 - dist_from_cam;
bool l7_on = is_on && move_dist > 105 - dist_from_cam;
bool l8_on = is_on && move_dist > 120 - dist_from_cam;
Color3 light_col = Color3(1000, 1000, 1000);
Color3 light_off_col = Color3(0.2, 0.2, 0.2);
Color3 move_light_col = Color3(2000, 2000, 2000);
Color3 col1 = l1_on ? light_col + Color3(250, 0, 0) : light_off_col;
Color3 col2 = l2_on ? light_col + Color3(0, 250, 0) : light_off_col;
Color3 col3 = l3_on ? light_col + Color3(0, 0, 250) : light_off_col;
Color3 col4 = l4_on ? light_col + Color3(250, 250, 0) : light_off_col;
Color3 col5 = l5_on ? light_col + Color3(0, 250, 250) : light_off_col;
Color3 col6 = l6_on ? light_col + Color3(250, 0, 250) : light_off_col;
Color3 col7 = l7_on ? light_col + Color3(500, 0, 250) : light_off_col;
Color3 col8 = l8_on ? light_col + Color3(250, 0, 500) : light_off_col;
Sphere l1(Point3(0.0, 2.0, -15), 0.3, col1, l1_on);
Sphere l2(Point3(0.0, 2.0, -30), 0.3, col2, l2_on);
Sphere l3(Point3(0.0, 2.0, -45), 0.3, col3, l3_on);
Sphere l4(Point3(0.0, 2.0, -60), 0.3, col4, l4_on);
Sphere l5(Point3(0.0, 2.0, -75), 0.3, col5, l5_on);
Sphere l6(Point3(0.0, 2.0, -90), 0.3, col6, l6_on);
Sphere l7(Point3(0.0, 2.0, -105), 0.3, col7, l7_on);
Sphere l8(Point3(0.0, 2.0, -120), 0.3, col8, l8_on);
// float end_pos = 8.0f * EaseInQuart((0.95f - 0.2f) / 0.8f + 1.0f);
// float theta = (is_on ? cam_pos / 12.0f : Lerp(end_pos / 12.0f, 360.0f, (t - 0.95f) / 0.05f)) * (float) (M_PI * 2.0f);
float theta = cam_pos / 12.0f * (float) (M_PI * 2.0f);
float x = cos(theta);
float y = sin(theta);
Point3 origin = Vec3(x, y, 0.01f - move_dist);
Sphere move_l(origin, 0.1, move_light_col, true);
SphereLights lights(l1, l2, l3, l4, l5, l6, l7, l8, move_l);
queue.writeBuffer(sphere_light_buffer_, 0, &lights, sizeof(SphereLights));
}

0 comments on commit 81c1576

Please sign in to comment.