Update project files and enhance rendering system

Added:
- Updated `.gitignore` to ignore the `[Bb]uild/` directory.
- Additional tasks added to the roadmap in `README.md` for light unit standardization and GPU backend support.

Changed:
- Removed line in `settings.json` that disabled error squiggles for C/C++ code.
- Modified `Triangle.h` to include `material_id` in `triangle_t` and reorganized properties.
- Reordered parameters in `triangle_collection_init` for clarity.
- Updated `shading_context_t` in `Material.h` and added size parameter to `material_create`.
- Streamlined initialization in `scene_init` and updated `scene_free` for proper resource management.
- Updated `window_create` in `Window.h` to accept a `render_job_t` parameter.
- Introduced `renderer_start` in `Renderer.c` to handle rendering jobs and optimized pixel rendering logic.
This commit is contained in:
2025-04-23 22:24:02 +09:00
parent 9cc420693c
commit 17872804c5
24 changed files with 523083 additions and 807 deletions

View File

@@ -3,8 +3,6 @@
#include <svpng.inc>
#include "Algorithm/Sobol.h"
#include "Debug.h"
// #include "Geometry/GeometryUtilities.h"
#include "Geometry/Mesh.h"
#include "Lighting/SkyLight.h"
#include "Material/SimpleLit.h"
@@ -12,26 +10,169 @@
#include "Rendering/Scene.h"
#include "Window.h"
static void save_img(render_target_t* source, uint32_t width, uint32_t height, const char* filename)
#define TITLE "Path Tracing"
#define SPONZA_PATH "./assets/sponza.obj"
static bool scene_setup(scene_t* scene)
{
FILE* file_stream;
fopen_s(&file_stream, filename, "wb");
if (file_stream == NULL)
if (!scene_init(scene, 67000, 8, 1))
{
return false;
}
scene->camera.position = (vec3s){-7.5f, 2.0f, 0.0f};
scene->camera.rotation = euler_to_quat(10.0f, -90.0f, 0.0f);
// TODO: Standardize light unit
light_entity_t sun = light_create_directional_light(&scene->lights);
directional_light_t* sun_light = &scene->lights.directional_lights[sun.id];
sun_light->direction = glms_vec3_normalize((vec3s){-0.5f, 1.0f, 0.15f});
sun_light->color = (vec3s){1.0f, 0.93f, 0.87f};
sun_light->intensity = 2.0f;
sun_light->angular_diameter = 0.53f;
scene->lights.sky_light = sky_create_constant_sky(&(constant_sky_data_t)
{
.color = (vec3s){0.73f, 0.82f, 1.0f},
.intensity = 1.0f,
});
return true;
}
static bool load_assets(scene_t* scene)
{
simple_lit_data_t floor_lit_data =
{
.albedo = (vec3s){1.0f, 1.0f, 1.0f},
.roughness = 0.95f,
.metallic = 0.0f,
};
material_entity_t floor_material = material_create_simple_lit(&floor_lit_data, &scene->materials);
mesh_load(SPONZA_PATH, floor_material.id, &scene->triangles, &scene->materials);
return scene_build_bvh(scene);
}
static bool initialize_renderer(const rendering_config_t* config, render_job_t** outJob, render_target_t* outImg, scene_t* outScene)
{
if (!scene_setup(outScene))
{
return false;
}
if (!load_assets(outScene))
{
return false;
}
if (!scene_build_bvh(outScene))
{
return false;
}
if (!render_target_init(config->width, config->height, outImg))
{
return false;
}
render_job_t* job = malloc(sizeof(render_job_t));
if (job == NULL)
{
return false;
}
*job = (render_job_t){
.scene = outScene,
.render_target = outImg,
.config = config,
.rendering_type = TILE_BASED,
.rendering_flag = DEBUG_NONE,
.is_done = false,
};
sobol_init();
*outJob = job;
return true;
}
static void shutdown_renderer(render_job_t* job, render_target_t* img, scene_t* scene)
{
if (job != NULL)
{
free(job);
}
render_target_free(img);
scene_free(scene);
}
static void update_pixel_buffer(render_target_t* render_target)
{
if (render_target == NULL || render_target->buffer == NULL)
{
fprintf(stderr, "Failed to open file for writing: %s\n", filename);
return;
}
unsigned char* img_buffer = render_target_to_char(source);
svpng(file_stream, width, height, img_buffer, 1);
for (uint32_t y = 0; y < render_target->height; y++)
{
for (uint32_t x = 0; x < render_target->width; x++)
{
vec4s pixel = render_target_get_pixel(render_target, x, y);
pixel = gamma_correct(pixel, 2.2f);
pixel = aces_tone_map(pixel);
window_update_pixel(pixel, x, y);
}
}
fclose(file_stream);
free(img_buffer);
window_refresh_region(0, 0, render_target->width, render_target->height);
}
static int run_main_loop(render_job_t* job, render_target_t* img)
{
MSG msg;
bool running = true;
while (running)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
switch (msg.message)
{
case WM_QUIT:
case WM_CLOSE:
{
running = false;
job->is_done = true;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (!job->is_done && running)
{
update_pixel_buffer(img);
}
}
return 0;
}
// int main()
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR pCmdLine, _In_ int nCmdShow)
{
omp_set_num_threads(16);
scene_t scene;
render_target_t img;
render_job_t* job = NULL;
rendering_config_t config = {
.width = 1920 / 4,
.height = 1080 / 4,
@@ -40,166 +181,22 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
.bucket_size = 64,
};
int result = window_create("Path Tracing", hInstance, config.width, config.height);
if (result != 0)
if (!initialize_renderer(&config, &job, &img, &scene))
{
fprintf(stderr, "Failed to create window\n");
shutdown_renderer(job, &img, &scene);
return -1;
}
if (!window_create(TITLE, hInstance, config.width, config.height, job))
{
shutdown_renderer(job, &img, &scene);
return -1;
}
#pragma region SceneSetup
omp_set_num_threads(16);
sobol_init();
int result = run_main_loop(job, &img);
scene_t scene;
if (!scene_init(67000, 8, 1, &scene))
{
return -1;
}
window_close();
shutdown_renderer(job, &img, &scene);
scene.camera.position = (vec3s){-7.5f, 2.0f, 0.0f};
scene.camera.rotation = euler_to_quat(10.0f, -90.0f, 0.0f);
light_entity_t sun = light_create_directional_light(&scene.lights);
directional_light_t* sun_light = &scene.lights.directional_lights[sun.id];
sun_light->direction = glms_vec3_normalize((vec3s){-0.5f, 1.0f, 0.15f});
sun_light->color = (vec3s){1.0f, 0.93f, 0.87f};
sun_light->intensity = 2.0f;
sun_light->angular_diameter = 0.53f;
scene.lights.sky_light = sky_create_constant_sky(&(constant_sky_data_t){
.color = (vec3s){0.73f, 0.82f, 1.0f},
.intensity = 1.0f,
});
// simple_lit_data_t gray_lit_data =
// {
// .albedo = (vec3s){0.73f, 0.73f, 0.73f},
// .roughness = 0.5f,
// .metallic = 0.0f,
// };
// simple_lit_data_t blue_lit_data =
// {
// .albedo = (vec3s){0.0f, 0.0f, 1.0f},
// .roughness = 0.5f,
// .metallic = 0.0f,
// };
// simple_lit_data_t red_lit_data =
// {
// .albedo = (vec3s){1.0f, 0.0f, 0.0f},
// .roughness = 0.5f,
// .metallic = 0.0f,
// };
// simple_lit_data_t green_lit_data =
// {
// .albedo = (vec3s){0.0f, 1.0f, 0.0f},
// .roughness = 0.5f,
// .metallic = 0.0f,
// };
simple_lit_data_t floor_lit_data = {
.albedo = (vec3s){1.0f, 1.0f, 1.0f},
.roughness = 0.95f,
.metallic = 0.0f,
};
// material_entity_t gray_material = material_create_simple_lit(&gray_lit_data, &scene.materials);
// material_entity_t gray_light_material = material_create_simple_lit(&gray_lit_data, &scene.materials);
// material_entity_t blue_material = material_create_simple_lit(&blue_lit_data, &scene.materials);
// material_entity_t red_material = material_create_simple_lit(&red_lit_data, &scene.materials);
// material_entity_t green_material = material_create_simple_lit(&green_lit_data, &scene.materials);
material_entity_t floor_material = material_create_simple_lit(&floor_lit_data, &scene.materials);
// scene.materials.buffer[gray_light_material.id].emission = (vec3s){10.0f, 10.0f, 10.0f};
mesh_load("./assets/sponza.obj", floor_material.id, &scene.triangles, &scene.materials);
// quad_create(
// (vec3s){0.0f, 3.95f, 0.0f},
// (vec3s){0.0f, -1.0f, 0.0f},
// (vec3s){0.0f, 0.0f, 1.0f},
// 1.0f, gray_light_material.id, &scene.triangles
// );
// quad_create(
// (vec3s){0.0f, 0.0f, 0.0f},
// (vec3s){0.0f, 1.0f, 0.0f},
// (vec3s){0.0f, 0.0f, 1.0f},
// 4.0f, floor_material.id, &scene.triangles
// );
// quad_create(
// (vec3s){0.0f, 4.0f, 0.0f},
// (vec3s){0.0f, -1.0f, 0.0f},
// (vec3s){0.0f, 0.0f, 1.0f},
// 4.0f, gray_material.id, &scene.triangles
// );
// quad_create(
// (vec3s){0.0f, 2.0f, -2.0f},
// (vec3s){0.0f, 0.0f, 1.0f},
// (vec3s){0.0f, 1.0f, 0.0f},
// 4.0f, green_material.id, &scene.triangles
// );
// quad_create(
// (vec3s){-2.0f, 2.0f, 0.0f},
// (vec3s){1.0f, 0.0f, 0.0f},
// (vec3s){0.0f, 1.0f, 0.0f},
// 4.0f, blue_material.id, &scene.triangles
// );
// quad_create(
// (vec3s){2.0f, 2.0f, 0.0f},
// (vec3s){-1.0f, 0.0f, 0.0f},
// (vec3s){0.0f, 1.0f, 0.0f},
// 4.0f, red_material.id, &scene.triangles
// );
#pragma endregion
render_target_t img;
render_target_init(config.width, config.height, &img);
if (!scene_build_bvh(&scene))
{
fprintf(stderr, "Failed to build BVH\n");
goto exit;
}
MSG msg;
uint16_t tile_index = 0;
tile_t current_tile = {0};
rendering_context_t ctx = {0};
while (true)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
goto exit;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// TODO: This hurt performance a lot, need to be optimized
if (scene_render_tile(&scene, &ctx, config, tile_index, DEBUG_NONE, &img, &current_tile))
{
for (uint32_t y = current_tile.y; y < current_tile.y + current_tile.height; y++)
{
for (uint32_t x = current_tile.x; x < current_tile.x + current_tile.width; x++)
{
vec4s pixel = render_target_get_pixel(&img, x, y);
pixel = gamma_correct(pixel, 2.2f);
pixel = aces_tone_map(pixel);
window_update_pixels(pixel, x, y);
}
}
window_refresh_region(current_tile.x, current_tile.y, current_tile.width, current_tile.height);
tile_index++;
}
}
exit:
render_target_free(&img);
scene_free(&scene);
return 0;
return result;
}