Fixed cdf and added Standard Lit
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#include "ALgorithm/BSDF.h"
|
||||
#include "cglm/util.h"
|
||||
#include "cglm/struct/mat3.h"
|
||||
#include "cglm/util.h"
|
||||
|
||||
float power_heuristic(float pdf_a, float pdf_b)
|
||||
{
|
||||
@@ -39,23 +39,39 @@ vec3s normal_unpack(vec3s normal)
|
||||
|
||||
vec3s normal_ts_to_ws(vec3s normal, vec3s geo_normal, vec3s tangent)
|
||||
{
|
||||
// 1. Sanitize inputs
|
||||
tangent = glms_vec3_normalize(tangent);
|
||||
vec3s bitangent = glms_vec3_cross(geo_normal, tangent);
|
||||
|
||||
float w = (glms_vec3_dot(glms_vec3_cross(geo_normal, tangent), bitangent) < 0.0f) ? -1.0f : +1.0f;
|
||||
geo_normal = glms_vec3_normalize(geo_normal);
|
||||
|
||||
// 2. Gram-Schmidt with safety check
|
||||
float proj = glms_vec3_dot(geo_normal, tangent);
|
||||
vec3s t_prime = glms_vec3_normalize(glms_vec3_sub(tangent, glms_vec3_scale(geo_normal, proj)));
|
||||
vec3s b_prime = glms_vec3_scale(glms_vec3_cross(geo_normal, t_prime), w);
|
||||
vec3s t_prime_unorm = glms_vec3_sub(tangent, glms_vec3_scale(geo_normal, proj));
|
||||
|
||||
// Matrix in cglm is column-major, not row-major
|
||||
mat3s tbn =
|
||||
// SAFETY: If tangent is parallel to normal, t_prime is zero.
|
||||
// Fallback to original tangent or arbitrary axis to avoid NaN.
|
||||
if (glms_vec3_norm2(t_prime_unorm) < FLT_EPSILON)
|
||||
{
|
||||
t_prime.x, t_prime.y, t_prime.z,
|
||||
b_prime.x, b_prime.y, b_prime.z,
|
||||
geo_normal.x, geo_normal.y, geo_normal.z
|
||||
};
|
||||
t_prime_unorm = tangent;
|
||||
// If tangent was also bad, pick an arbitrary axis
|
||||
if (glms_vec3_norm2(t_prime_unorm) < FLT_EPSILON)
|
||||
{
|
||||
create_orthonormal_basis(geo_normal, &t_prime_unorm, &tangent); // Recycle variable
|
||||
}
|
||||
}
|
||||
vec3s t_prime = glms_vec3_normalize(t_prime_unorm);
|
||||
|
||||
// 3. Calculate Bitangent
|
||||
vec3s b_prime = glms_vec3_cross(geo_normal, t_prime);
|
||||
|
||||
// 4. Apply Tangent Handedness (w)
|
||||
// NOTE: Check if tangent W component is stored/passed correctly.
|
||||
// If not sure, assuming 1.0 is safer than calculating it from cross products of unnormalized vectors.
|
||||
float w = (glms_vec3_dot(glms_vec3_cross(geo_normal, tangent), b_prime) < 0.0f) ? -1.0f : 1.0f;
|
||||
b_prime = glms_vec3_scale(b_prime, w);
|
||||
|
||||
mat3s tbn = {t_prime.x, t_prime.y, t_prime.z, b_prime.x, b_prime.y, b_prime.z, geo_normal.x, geo_normal.y, geo_normal.z};
|
||||
|
||||
// 5. Transform and Re-normalize
|
||||
return glms_vec3_normalize(glms_mat3_mulv(tbn, normal));
|
||||
}
|
||||
|
||||
@@ -104,10 +120,10 @@ float pdf_blinn_phong_lobe(vec3s normal, vec3s wi, vec3s wo, float roughness)
|
||||
return pdf_spec;
|
||||
}
|
||||
|
||||
vec3s sample_cosine_weighted_hemisphere_z_angular(float angular, uint32_t index, uint32_t d1, uint32_t d2)
|
||||
vec3s sample_cosine_weighted_hemisphere_z_angular(float angular, uint32_t index, uint16_t d1, uint16_t d2, uint32_t scramble)
|
||||
{
|
||||
float r1 = sobol_sample(index, d1);
|
||||
float r2 = sobol_sample(index, d2);
|
||||
float r1 = sobol_sample_scrambled(index, d1, scramble);
|
||||
float r2 = sobol_sample_scrambled(index, d2, scramble);
|
||||
|
||||
float phi = 2.0f * PI * r1;
|
||||
|
||||
@@ -128,10 +144,10 @@ vec3s sample_cosine_weighted_hemisphere_z_angular(float angular, uint32_t index,
|
||||
|
||||
// Function to generate a direction with cosine weighting around (0, 0, 1)
|
||||
// This is the local coordinate sample.
|
||||
vec3s sample_cosine_weighted_hemisphere_z(uint32_t index, uint32_t d1, uint32_t d2)
|
||||
vec3s sample_cosine_weighted_hemisphere_z(uint32_t index, uint16_t d1, uint16_t d2, uint32_t scramble)
|
||||
{
|
||||
float r1 = sobol_sample(index, d1);
|
||||
float r2 = sobol_sample(index, d2);
|
||||
float r1 = sobol_sample_scrambled(index, d1, scramble);
|
||||
float r2 = sobol_sample_scrambled(index, d2, scramble);
|
||||
|
||||
float r = sqrtf(r1);
|
||||
float phi = 2.0f * PI * r2;
|
||||
@@ -155,20 +171,20 @@ void create_orthonormal_basis(vec3s direction, vec3s* u, vec3s* v)
|
||||
vec3s a;
|
||||
if (fabsf(direction.x) > 0.9f)
|
||||
{
|
||||
a = (vec3s){{0.0f, 1.0f, 0.0f}}; // Use y-axis
|
||||
a = (vec3s){0.0f, 1.0f, 0.0f}; // Use y-axis
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (vec3s){{1.0f, 0.0f, 0.0f}}; // Use x-axis
|
||||
a = (vec3s){1.0f, 0.0f, 0.0f}; // Use x-axis
|
||||
}
|
||||
|
||||
*u = glms_vec3_normalize(glms_vec3_cross(a, direction));
|
||||
*v = glms_vec3_normalize(glms_vec3_cross(direction, *u));
|
||||
}
|
||||
|
||||
vec3s random_cosine_direction_angular(vec3s direction, float angular, uint32_t index, uint32_t d1, uint32_t d2)
|
||||
vec3s random_cosine_direction_angular(vec3s direction, float angular, uint32_t index, uint32_t d1, uint32_t d2, uint32_t scramble)
|
||||
{
|
||||
vec3s local_dir = sample_cosine_weighted_hemisphere_z_angular(angular, index, d1, d2);
|
||||
vec3s local_dir = sample_cosine_weighted_hemisphere_z_angular(angular, index, d1, d2, scramble);
|
||||
|
||||
vec3s u, v;
|
||||
create_orthonormal_basis(direction, &u, &v);
|
||||
@@ -184,9 +200,9 @@ vec3s random_cosine_direction_angular(vec3s direction, float angular, uint32_t i
|
||||
|
||||
// Samples a direction from the hemisphere oriented along 'normal'
|
||||
// with a cosine-weighted distribution.
|
||||
vec3s random_cosine_direction(vec3s direction, uint32_t index, uint32_t d1, uint32_t d2)
|
||||
vec3s random_cosine_direction(vec3s direction, uint32_t index, uint32_t d1, uint32_t d2, uint32_t scramble)
|
||||
{
|
||||
vec3s local_dir = sample_cosine_weighted_hemisphere_z(index, d1, d2);
|
||||
vec3s local_dir = sample_cosine_weighted_hemisphere_z(index, d1, d2, scramble);
|
||||
|
||||
vec3s u, v;
|
||||
create_orthonormal_basis(direction, &u, &v);
|
||||
@@ -199,10 +215,10 @@ vec3s random_cosine_direction(vec3s direction, uint32_t index, uint32_t d1, uint
|
||||
return world_dir;
|
||||
}
|
||||
|
||||
vec3s random_uniform_cdf_direction(vec3s direction, uint32_t index, uint32_t d1, uint32_t d2)
|
||||
vec3s random_uniform_cdf_direction(vec3s direction, uint32_t index, uint16_t d1, uint16_t d2, uint32_t scramble)
|
||||
{
|
||||
float r1 = sobol_sample(index, d1);
|
||||
float r2 = sobol_sample(index, d2);
|
||||
float r1 = sobol_sample_scrambled(index, d1, scramble);
|
||||
float r2 = sobol_sample_scrambled(index, d2, scramble);
|
||||
|
||||
float phi = 2.0f * PI * r1;
|
||||
float cos_theta = 1.0f - r2 * 2.0f;
|
||||
@@ -223,10 +239,10 @@ vec3s random_uniform_cdf_direction(vec3s direction, uint32_t index, uint32_t d1,
|
||||
return world_dir;
|
||||
}
|
||||
|
||||
vec3s random_uniform_cdf_direction_angular(vec3s direction, uint32_t index, float angular, uint32_t d1, uint32_t d2)
|
||||
vec3s random_uniform_cdf_direction_angular(vec3s direction, uint32_t index, float angular, uint16_t d1, uint16_t d2, uint32_t scramble)
|
||||
{
|
||||
float r1 = sobol_sample(index, d1);
|
||||
float r2 = sobol_sample(index, d2);
|
||||
float r1 = sobol_sample_scrambled(index, d1, scramble);
|
||||
float r2 = sobol_sample_scrambled(index, d2, scramble);
|
||||
|
||||
float cos_alpha = cosf(angular);
|
||||
float cos_theta = 1.0f - r1 * (1.0f - cos_alpha);
|
||||
@@ -249,11 +265,10 @@ vec3s random_uniform_cdf_direction_angular(vec3s direction, uint32_t index, floa
|
||||
return world_dir;
|
||||
}
|
||||
|
||||
|
||||
// Must use this function to weight any nee light contribution before accumulate.
|
||||
vec3s weight_nee_light(vec3s bsdf, vec3s light, float pdf_bsdf, float pdf_sky)
|
||||
{
|
||||
light = glms_vec3_mul(bsdf, light);
|
||||
float weight = power_heuristic(pdf_sky, pdf_bsdf);
|
||||
return glms_vec3_scale(light, weight);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user