Skip to content

Commit

Permalink
EaseInOutExpo inside the box.
Browse files Browse the repository at this point in the history
  • Loading branch information
kugimasa committed Aug 25, 2023
1 parent f3b0128 commit aed7de4
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 26 deletions.
48 changes: 36 additions & 12 deletions resources/shader/compute-sample.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const kYup = vec3f(0.0, 1.0, 0.0);
const kRayDepth = 5;
const kRayMin = 1e-6;
const kRayMax = 1e20;
const kSPP = 150;
const kSPP = 10;
const kZero = vec3f(0.0, 0.0, 0.0);
const kOne = vec3f(1.0, 1.0, 1.0);

Expand Down Expand Up @@ -70,6 +70,8 @@ struct Sphere {
struct SphereLights {
l1 : Sphere,
l2 : Sphere,
l3 : Sphere,
l4 : Sphere,
}

fn fabs(x: f32) -> f32 {
Expand Down Expand Up @@ -161,13 +163,24 @@ fn sample_direction(hit: HitInfo) -> vec3f {
}

fn sample_from_light(hit: HitInfo) -> vec3f {
// MEMO: 今はSphereLightのみ
// FIXME: 境界が目立つ
// ヒット位置とライト位置を比較
let l1_dist = distance(hit.pos, sphere_lights.l1.center);
var dist = distance(hit.pos, sphere_lights.l1.center);
var sphere = sphere_lights.l1;
let l2_dist = distance(hit.pos, sphere_lights.l2.center);
var sphere = sphere_lights.l2;
if (l1_dist < l2_dist) {
sphere = sphere_lights.l1;
let l3_dist = distance(hit.pos, sphere_lights.l3.center);
let l4_dist = distance(hit.pos, sphere_lights.l4.center);
if (l2_dist < dist) {
dist = l2_dist;
sphere = sphere_lights.l2;
}
if (l3_dist < dist) {
dist = l3_dist;
sphere = sphere_lights.l3;
}
if (l4_dist < dist) {
dist = l4_dist;
sphere = sphere_lights.l4;
}
return sample_from_sphere(sphere, hit.pos);
}
Expand Down Expand Up @@ -201,11 +214,21 @@ fn sample_from_cosine(hit: HitInfo) -> vec3f {
}

fn mixture_pdf(hit: HitInfo, dir: vec3f) -> f32 {
/// FIXME: 暗くなってしまう
let l1_dist = distance(hit.pos, sphere_lights.l1.center);
let l2_dist = distance(hit.pos, sphere_lights.l2.center);
let l1_w = l2_dist / (l1_dist + l2_dist);
let l2_w = l1_dist / (l1_dist + l2_dist);
return 0.5 * cosine_pdf(hit, dir) + 0.5 * (l1_w * sphere_pdf(hit, sphere_lights.l1, dir) + l2_w * sphere_pdf(hit, sphere_lights.l2, dir));
let l3_dist = distance(hit.pos, sphere_lights.l3.center);
let l4_dist = distance(hit.pos, sphere_lights.l4.center);
let dist_sum = l1_dist + l2_dist + l3_dist + l4_dist;
let l1_w = (l2_dist + l3_dist + l4_dist) / dist_sum;
let l2_w = (l1_dist + l3_dist + l4_dist) / dist_sum;
let l3_w = (l1_dist + l2_dist + l4_dist) / dist_sum;
let l4_w = (l1_dist + l2_dist + l3_dist) / dist_sum;
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);
return 0.5 * cosine_pdf(hit, dir) + 0.5 * light_pdf;
}

fn sphere_pdf(hit: HitInfo, sphere: Sphere, dir: vec3f) -> f32 {
Expand Down Expand Up @@ -260,9 +283,8 @@ fn raytrace(path: Path, depth: i32) -> Path {
if (emissive) {
if (depth == 0) {
var light_col = hit.col / length(hit.col);
let vdotn = dot(-r.dir.xyz, hit.norm.xyz);
// TODO: 正しい計算&Bloom...?
light_col = light_col + light_col * schlick_fresnel(vec3f(0.02), vdotn);
let dist = distance(camera.start.xyz, hit.pos.xyz);
light_col = hit.col / max(dist * dist, 1.0);
return Path(r, light_col, true);
}
// 照明計算
Expand Down Expand Up @@ -299,6 +321,8 @@ fn sample_hit(r: Ray) -> HitInfo {
// 光源との交差判定
hit = intersect_sphere(r, sphere_lights.l1, hit);
hit = intersect_sphere(r, sphere_lights.l2, hit);
hit = intersect_sphere(r, sphere_lights.l3, hit);
hit = intersect_sphere(r, sphere_lights.l4, hit);
return hit;
}

Expand Down
5 changes: 3 additions & 2 deletions src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ void Camera::InitBindGroup(Device &device) {
}

void Camera::Update(Queue &queue, float t, float aspect) {
float move_dist = lerp(0.0, 40.0, t);
t = EaseInOutExpo(t);
float move_dist = Lerp(0.0, 40.0, t);
float fovy = t < 0.5 ? Lerp(40, 90, t / 0.5f) : Lerp(90, 40, (t - 0.5f) / 0.5f);
Point3 origin = Vec3(0, 0, 0.01f - move_dist);
Point3 target = Vec3(0, 0, 15 + move_dist);
float time = 0.0f;
float fovy = 90.0f;
CameraParam param(origin, target, aspect, fovy, time, RandSeed());
queue.writeBuffer(uniform_buffer_, 0, &param, sizeof(CameraParam));
}
2 changes: 1 addition & 1 deletion src/include/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Renderer {
private:
static const uint32_t WIDTH = 640;
static const uint32_t HEIGHT = 480;
static const uint32_t MAX_FRAME = 1;
static const uint32_t MAX_FRAME = 300;
Camera camera_{};
Scene scene_{};
bool hasWindow_ = false;
Expand Down
8 changes: 7 additions & 1 deletion src/include/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ class Scene {
struct SphereLights {
Sphere l1_;
Sphere l2_;
Sphere l3_;
Sphere l4_;

SphereLights(Sphere l1, Sphere l2) : l1_(l1), l2_(l2) {};
SphereLights(Sphere l1, Sphere l2, Sphere l3, Sphere l4) : l1_(l1), l2_(l2), l3_(l3), l4_(l4) {};
};

void Release();
Expand All @@ -46,6 +48,10 @@ class Scene {

void InitBindGroup(Device &device);

size_t inline GetSphereLightsNum() {
return sizeof(SphereLights) / sizeof(Sphere);
};

public:
std::vector<Triangle> tris_;
std::vector<Quad> quads_;
Expand Down
13 changes: 12 additions & 1 deletion src/include/utils/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ inline int RandInt(int min, int max) {
}

// 線形補間
inline float lerp(float a, float b, float t) {
inline float Lerp(float a, float b, float t) {
return a + t * (b - a);
}

inline float EaseInQuart(float t) {
return t * t * t * t;
}

inline float EaseInOutExpo(float t) {
if (t == 0 || t == 1) {
return t;
}
return t < 0.5 ? pow(2.0f, 20.0f * t - 10.0f) / 2.0f : (2.0f - pow(2.0f, -20.0f * t + 10.0f)) / 2.0f;
}
4 changes: 2 additions & 2 deletions src/render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ bool Renderer::InitDevice() {
// Setting up required limits
RequiredLimits requiredLimits = Default;
requiredLimits.limits.maxBindGroups = 3;
requiredLimits.limits.maxUniformBuffersPerShaderStage = 1;
requiredLimits.limits.maxUniformBufferBindingSize = 16 * sizeof(float);
requiredLimits.limits.maxUniformBuffersPerShaderStage = 2;
requiredLimits.limits.maxUniformBufferBindingSize = sizeof(Scene::SphereLights);
// origin(3), target(3), aspect(1), time(1), seed(1)
// Without this, wgpu-native crashes
requiredLimits.limits.maxVertexAttributes = 3;
Expand Down
14 changes: 7 additions & 7 deletions src/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Scene::Scene(Device &device) {
cb.PushToQuads(quads_);

/// Sphereの追加
spheres_.emplace_back(Point3(-1.0, 0, -9), 0.3, Color3(0.0, 0.2, 0.5));
spheres_.emplace_back(Point3(-1.0, 0, -9), 0.3, Color3(0.8, 0.8, 0.8));
/// バッファのバインド
InitBindGroupLayout(device);
InitBuffers(device);
Expand Down Expand Up @@ -151,7 +151,7 @@ void Scene::InitBindGroupLayout(Device &device) {
void Scene::InitBuffers(Device &device) {
quad_buffer_ = CreateQuadBuffer(device);
sphere_buffer_ = CreateSphereBuffer(device, spheres_.size(), BufferUsage::Storage, true);
sphere_light_buffer_ = CreateSphereBuffer(device, 2, BufferUsage::Uniform | BufferUsage::CopyDst, false);
sphere_light_buffer_ = CreateSphereBuffer(device, GetSphereLightsNum(), BufferUsage::Uniform | BufferUsage::CopyDst, false);
}

/*
Expand Down Expand Up @@ -328,10 +328,10 @@ void Scene::InitBindGroup(Device &device) {
* SphereLightの更新
*/
void Scene::UpdateSphereLights(Queue &queue, float t) {
Sphere l1(Point3(0, 0, -40), 0.5, Color3(20, 20, 20), true);
auto x = lerp(-2.0, 2.0, t);
auto z = lerp(0.0, 30.0, t);
Sphere l2(Point3(x, 1.0, -10 - z), 0.3, Color3(20, 150 + 30.0f * t, 20), true);
SphereLights lights(l1, l2);
Sphere l1(Point3(0, 0, -50), 0.5, Color3(2000, 2000, 2000), true);
Sphere l2(Point3(1.0, 2.0, -10), 0.3, Color3(20, 1500, 20), true);
Sphere l3(Point3(0.0, 2.0, -20), 0.3, Color3(1500, 20, 20), true);
Sphere l4(Point3(-1.0, 2.0, -30), 0.3, Color3(20, 20, 1500), true);
SphereLights lights(l1, l2, l3, l4);
queue.writeBuffer(sphere_light_buffer_, 0, &lights, sizeof(SphereLights));
}

0 comments on commit aed7de4

Please sign in to comment.