Files
SimpleRayTracing/source/Geometry/Mesh.c
Misaki e1693764f7 Add mipmap support and refactor texture handling
Note: Currently version still have lots of fireflies after applying normal map. And those fireflies are mostly coming from the nee sky. Need to double check the sky cdf and ray intersection.

Changed the `hit_result_t` structure to rename a parameter in `RayIntersection.h`.
Removed the `normal` field from the `path_output` structure in `Common.h`.
Added new fields `screen_size`, `camera_position`, and `camera_direction` in `Material.h`.
Changed the `mipmap_t` structure in `Texture.h` to include a `max_mip` field and modify the `data` field.
Changed the `texture_load` function in `Texture.c` to include a `mipmap` parameter and improve texture data handling.
Changed the `path_trace` function in `PathTracing.c` to update the `shading_context_t` structure and ray creation.
Changed the `evaluate_bsdf_directional` function in `LightEvaluation.c` to modify angular radius calculation.
Changed the `sky_create_hdr_sky` and `evaluate_bsdf_hdr_sky` functions in `SkyLight.c` to enhance texture sampling.
Changed the `get_surface_data` function in `SimpleLit.c` to incorporate camera distance and view direction in calculations.
Changed the `texture_get_pixel` function in `Texture.c` to improve pixel data retrieval.
Changed the `warp_uv` function to use a `vec2s` structure for UV coordinates.
Changed the `texture_sample` function to include additional parameters for improved sampling accuracy.
Changed the `scene_setup` function in `main.c` to adjust sun light intensity and HDRI texture loading.
2025-05-06 17:46:42 +09:00

119 lines
4.4 KiB
C

#include "Geometry/Mesh.h"
#include "Common/String.h"
#include "Material/SimpleLit.h"
#include "assimp/cimport.h"
#include "assimp/scene.h"
#include "assimp/postprocess.h"
static texture_entity_t load_material_texture(const struct aiMaterial* material, enum aiTextureType type, const char* filename, scene_t* scene)
{
struct aiString path;
if (AI_SUCCESS == aiGetMaterialTexture(material, type, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL))
{
if (!is_absolute_path(path.data))
{
char directory[1024];
get_path_directory(filename, directory, 1024);
char image_path[1024];
memcpy(image_path, path.data, 1024);
string_join(directory, image_path, path.data, 1024);
}
return texture_load(path.data, true, true, UINT_8, &scene->textures);
}
return invalid_texture_entity();
}
mesh_entity_t mesh_load(const char* filename, scene_t* scene)
{
mesh_entity_t entity = {0};
const struct aiScene* mesh_scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_Quality);
if (mesh_scene == NULL)
{
perror(aiGetErrorString());
return entity;
}
entity.triangle_id = scene->triangles.count;
entity.material_id = scene->materials.count;
for (uint32_t i = 0; i < mesh_scene->mNumMaterials; i++)
{
const struct aiMaterial* src = mesh_scene->mMaterials[i];
struct aiColor4D base_color = {0.73f};
aiGetMaterialColor(src, AI_MATKEY_COLOR_DIFFUSE, &base_color);
float roughness = 0.75f;
aiGetMaterialFloat(src, AI_MATKEY_ROUGHNESS_FACTOR, &roughness);
float metallic = 0.0f;
aiGetMaterialFloat(src, AI_MATKEY_METALLIC_FACTOR, &metallic);
texture_entity_t albedo_entity = load_material_texture(src, aiTextureType_DIFFUSE, filename, scene);
texture_entity_t normal_entity = load_material_texture(src, aiTextureType_NORMALS, filename, scene);
texture_entity_t roughness_entity = load_material_texture(src, aiTextureType_DIFFUSE_ROUGHNESS, filename, scene);
texture_entity_t metallic_entity = load_material_texture(src, aiTextureType_METALNESS, filename, scene);
simple_lit_properties_t prop =
{
.albedo = {base_color.r, base_color.g, base_color.b},
.roughness = roughness,
.metallic = metallic,
.albedo_texture = albedo_entity,
.normal_texture = normal_entity,
.roughness_texture = roughness_entity,
.metallic_texture = metallic_entity,
};
material_create_simple_lit_default(&prop, &scene->materials);
entity.material_count++;
}
for (uint32_t i = 0; i < mesh_scene->mNumMeshes; i++)
{
const struct aiMesh* mesh = mesh_scene->mMeshes[i];
//TODO: Handle all primitive types, not just triangles
if (mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)
{
continue;
}
bool has_uv = mesh->mTextureCoords[0] != NULL && mesh->mNumUVComponents[0] >= 2;
for (uint32_t j = 0; j < mesh->mNumFaces; j++)
{
const struct aiFace* face = &mesh->mFaces[j];
if (face->mNumIndices != 3)
{
continue;
}
uint32_t index0 = face->mIndices[0];
uint32_t index1 = face->mIndices[1];
uint32_t index2 = face->mIndices[2];
vertex_t vertices[3] = {0};
for (uint32_t k = 0; k < 3; k++)
{
vertices[k].position = (vec3s){mesh->mVertices[face->mIndices[k]].x, mesh->mVertices[face->mIndices[k]].y, mesh->mVertices[face->mIndices[k]].z};
vertices[k].normal = (vec3s){mesh->mNormals[face->mIndices[k]].x, mesh->mNormals[face->mIndices[k]].y, mesh->mNormals[face->mIndices[k]].z};
vertices[k].tangent = (vec3s){mesh->mTangents[face->mIndices[k]].x, mesh->mTangents[face->mIndices[k]].y, mesh->mTangents[face->mIndices[k]].z};
if (has_uv)
{
vertices[k].uv = (vec2s){mesh->mTextureCoords[0][face->mIndices[k]].x, mesh->mTextureCoords[0][face->mIndices[k]].y};
}
}
triangle_create(vertices[0], vertices[1], vertices[2], entity.material_id + mesh->mMaterialIndex, &scene->triangles);
entity.triangle_count++;
}
}
aiReleaseImport(mesh_scene);
return entity;
}