Added a new function `blinn_phong_specular_exponent_to_roughness` in `BSDF.h` to convert a specular exponent to roughness. Added a `textures` member to the `shading_context_t` structure in `Material.h` for passing texture information during shading. Added a new member `textures` in the `light_shading_context_t` structure in `Light.h` to hold texture information. Added inline functions in `Texture.h` for handling texture entities, including `invalid_texture_entity`, `is_texture_entity_valid`, and `get_texture`. Changed the texture-related members in `simple_lit_properties_t` in `SimpleLit.h` from pointers to `texture_entity_t` to better manage texture entities. Changed the `sample_material_bsdf` and `sample_material_bsdf_pdf` functions in `Material.h` to accept a `shading_context_t` instead of individual parameters. Changed the `mesh_load` function in `Mesh.c` to use the new roughness calculation and texture entity handling. Changed the `path_trace` function in `PathTracing.c` to use the new structure and functions for handling materials and textures. Refactored the `sample_material_bsdf` and `sample_material_bsdf_pdf` functions in `Material.c` to utilize the new `shading_context_t` structure. Updated the `material_collection_init` function in `Material.h` to reflect changes in the material sampling functions. Updated the `evaluate_bsdf_directional` and `evaluate_bsdf_const_sky` functions to use the new shading context structure. Adjusted the `simple_lit_data_default` function in `SimpleLit.c` to work with the new texture handling approach. Added texture entity handling in `Texture.c` for managing invalid texture entities.
161 lines
3.9 KiB
C
161 lines
3.9 KiB
C
#ifndef LIGHT_H
|
|
#define LIGHT_H
|
|
|
|
#include "Algorithm/BVH.h"
|
|
#include "Algorithm/Sobol.h"
|
|
#include "Geometry/Triangle.h"
|
|
#include "Material/Material.h"
|
|
#include "cglm/struct/vec3.h"
|
|
|
|
#define SKY_DATA_CAPACITY 64
|
|
|
|
typedef enum {
|
|
SKY_TYPE_CONSTANT,
|
|
} sky_type_t;
|
|
|
|
typedef struct
|
|
{
|
|
vec3s normal;
|
|
vec3s hit_point;
|
|
vec3s wo;
|
|
vec2s uv;
|
|
|
|
uint16_t bounce_depth;
|
|
|
|
const bvh_tree_t* bvh_tree;
|
|
const material_t* material;
|
|
const texture_collection_t* textures;
|
|
} light_shading_context_t;
|
|
|
|
#ifdef __STDC_ALIGN__
|
|
#define SKY_ALIGN _Alignof(max_align_t)
|
|
#else
|
|
#define SKY_ALIGN (sizeof(void*))
|
|
#endif
|
|
|
|
typedef vec3s (*evaluate_bsdf_sky_f) (const void* data, const light_shading_context_t* context, vec3s throughput, uint32_t index);
|
|
|
|
typedef struct
|
|
{
|
|
evaluate_bsdf_sky_f evaluate_bsdf_sky;
|
|
sky_type_t type;
|
|
uint16_t data_size;
|
|
|
|
_Alignas(SKY_ALIGN)
|
|
char data[SKY_DATA_CAPACITY];
|
|
} sky_light_t;
|
|
|
|
typedef enum
|
|
{
|
|
LIGHT_TYPE_POINT,
|
|
LIGHT_TYPE_SPOT,
|
|
LIGHT_TYPE_AREA,
|
|
} punctual_light_type_e;
|
|
|
|
typedef struct
|
|
{
|
|
vec3s position;
|
|
vec3s color;
|
|
float intensity;
|
|
punctual_light_type_e type;
|
|
} punctual_light_t;
|
|
|
|
typedef struct
|
|
{
|
|
vec3s direction;
|
|
vec3s color;
|
|
float intensity;
|
|
float angular_diameter;
|
|
} directional_light_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t punctual_light_count;
|
|
uint32_t directional_light_count;
|
|
uint32_t max_punctual_lights;
|
|
uint32_t max_directional_lights;
|
|
|
|
sky_light_t sky_light;
|
|
punctual_light_t* punctual_lights;
|
|
directional_light_t* directional_lights;
|
|
} light_collection_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t id;
|
|
bool is_punctual;
|
|
} light_entity_t;
|
|
|
|
inline bool light_collection_create(uint32_t max_punctual_lights, uint32_t max_directional_lights, light_collection_t* collection)
|
|
{
|
|
if (max_punctual_lights == 0 || max_directional_lights == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
collection->max_punctual_lights = max_punctual_lights;
|
|
collection->max_directional_lights = max_directional_lights;
|
|
collection->punctual_light_count = 0;
|
|
collection->directional_light_count = 0;
|
|
|
|
collection->punctual_lights = (punctual_light_t*)malloc(max_punctual_lights * sizeof(punctual_light_t));
|
|
if (collection->punctual_lights == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
collection->directional_lights = (directional_light_t*)malloc(max_directional_lights * sizeof(directional_light_t));
|
|
if (collection->directional_lights == NULL)
|
|
{
|
|
free(collection->punctual_lights);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
inline light_entity_t light_create_punctual_light(light_collection_t* collection)
|
|
{
|
|
if (collection->punctual_light_count >= collection->max_punctual_lights)
|
|
{
|
|
return (light_entity_t){0};
|
|
}
|
|
|
|
punctual_light_t light = {0};
|
|
collection->punctual_lights[collection->punctual_light_count] = light;
|
|
light_entity_t entity = {.id = collection->punctual_light_count, .is_punctual = true};
|
|
collection->punctual_light_count++;
|
|
|
|
return entity;
|
|
}
|
|
|
|
inline light_entity_t light_create_directional_light(light_collection_t* collection)
|
|
{
|
|
if (collection->directional_light_count >= collection->max_directional_lights)
|
|
{
|
|
return (light_entity_t){0};
|
|
}
|
|
|
|
directional_light_t light = {0};
|
|
collection->directional_lights[collection->directional_light_count] = light;
|
|
light_entity_t entity = {.id = collection->directional_light_count, .is_punctual = false};
|
|
collection->directional_light_count++;
|
|
|
|
return entity;
|
|
}
|
|
|
|
inline void light_collection_free(light_collection_t* collection)
|
|
{
|
|
free(collection->punctual_lights);
|
|
free(collection->directional_lights);
|
|
|
|
collection->max_punctual_lights = 0;
|
|
collection->max_directional_lights = 0;
|
|
collection->punctual_light_count = 0;
|
|
collection->directional_light_count = 0;
|
|
collection->punctual_lights = NULL;
|
|
collection->directional_lights = NULL;
|
|
}
|
|
|
|
#endif // LIGHT_H
|