+ | Transparency Material

This commit is contained in:
TheRedShip
2025-01-16 00:12:31 +01:00
parent a892d5e7e6
commit 787833ac84
12 changed files with 6203 additions and 6118 deletions

View File

@ -86,6 +86,7 @@ struct Ray
struct hitInfo
{
float t;
float last_t;
vec3 normal;
vec3 position;
int obj_index;
@ -141,6 +142,7 @@ hitInfo traceRay(Ray ray)
if (intersect(ray, obj, temp_hit) && temp_hit.t > 0.0f && temp_hit.t < hit.t + 0.0001)
{
hit.t = temp_hit.t;
hit.last_t = temp_hit.last_t;
hit.obj_index = i;
hit.position = temp_hit.position;
hit.normal = temp_hit.normal;

View File

@ -7,9 +7,17 @@ bool intersectSphere(Ray ray, GPUObject obj, out hitInfo hit)
float h = b * b - c;
float t = -b - sqrt(h);
t = mix(t, -b + sqrt(h), step(t, 0.0));
float last_t = -b + sqrt(h);
if (t > last_t)
{
float temp = t;
t = last_t;
last_t = temp;
}
hit.t = t;
hit.last_t = last_t;
hit.position = ray.origin + ray.direction * t;
hit.normal = normalize(hit.position - obj.position);

View File

@ -64,32 +64,29 @@ vec3 sampleQuadLight(vec3 position, GPUObject obj, GPUMaterial mat, inout uint r
vec3 normal = normalize(crossQuad);
float cos_theta = max(0.0, dot(normal, -light_dir));
return mat.emission * mat.color * cos_theta / (pdf * light_dist * light_dist);
return mat.emission * mat.color / (light_dist);
}
vec3 sampleLights(vec3 position, inout uint rng_state)
{
vec3 light = vec3(0.0);
int emissive_count = 0;
for (int i = 0; i < u_objectsNum; i++)
if (materials[objects[i].mat_index].emission > 0.0)
emissive_count++;
{
GPUObject obj = objects[i];
GPUMaterial mat = materials[obj.mat_index];
if (mat.emission > 0.0)
{
vec3 light_dir = normalize(obj.position - position);
float light_dist = length(obj.position - position);
int target_light = int(floor(randomValue(rng_state) * float(emissive_count)));
Ray shadow_ray = Ray(position + light_dir * 0.01, light_dir);
hitInfo shadow_hit = traceRay(shadow_ray);
GPUObject obj = objects[target_light];
GPUMaterial mat = materials[obj.mat_index];
vec3 light_dir = normalize(obj.position - position);
float light_dist = length(obj.position - position);
Ray shadow_ray = Ray(position + light_dir * 0.01, light_dir);
hitInfo shadow_hit = traceRay(shadow_ray);
if (shadow_hit.obj_index == target_light)
light += mat.emission * mat.color / (light_dist);
if (shadow_hit.obj_index == i)
light += mat.emission * mat.color / (light_dist);
}
}
return (light);
}
@ -98,25 +95,21 @@ vec3 sampleLights(vec3 position, inout uint rng_state)
// {
// vec3 light = vec3(0.0);
// int emissive_count = 0;
// for (int i = 0; i < u_objectsNum; i++)
// if (materials[objects[i].mat_index].emission > 0.0)
// emissive_count++;
// {
// GPUObject obj = objects[i];
// GPUMaterial mat = materials[obj.mat_index];
// if (emissive_count == 0)
// return (vec3(0.));
// int target_light = int(floor(randomValue(rng_state) * float(emissive_count)));
// GPUObject obj = objects[target_light];
// GPUMaterial mat = materials[obj.mat_index];
// if (mat.emission == 0.0)
// continue ;
// if (obj.type == 0)
// light = sampleSphereLight(position, obj, mat, rng_state);
// else if (obj.type == 2)
// light = sampleQuadLight(position, obj, mat, rng_state);
// }
// if (obj.type == 0)
// light = sampleSphereLight(position, obj, mat, rng_state);
// else if (obj.type == 2)
// light = sampleQuadLight(position, obj, mat, rng_state);
// return (light);
// }

View File

@ -32,6 +32,72 @@ Ray dieletricRay(hitInfo hit, Ray ray, GPUMaterial mat)
return (ray);
}
void swap(inout float a, inout float b)
{
float temp = a;
a = b;
b = temp;
}
float fresnel(vec3 incident, vec3 normal, float eta)
{
float cosi = clamp(dot(incident, normal), -1.0, 1.0);
float etai = 1.0, etat = eta;
if (cosi > 0.0) swap(etai, etat);
float sint = etai / etat * sqrt(max(0.0, 1.0 - cosi * cosi));
if (sint >= 1.0) {
return 1.0; // Total internal reflection
}
float cost = sqrt(max(0.0, 1.0 - sint * sint));
cosi = abs(cosi);
float Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost));
float Rp = ((etai * cosi) - (etat * cost)) / ((etai * cosi) + (etat * cost));
return (Rs * Rs + Rp * Rp) * 0.5;
}
Ray transparencyRay(hitInfo hit, Ray ray, GPUMaterial mat, inout uint rng_state)
{
Ray newRay;
float eta = mat.refraction;
vec3 refractedDir = refract(ray.direction, hit.normal, 1.0 / eta);
float kr = fresnel(ray.direction, hit.normal, eta);
float randVal = randomValue(rng_state);
if (randVal < mat.metallic || length(refractedDir) == 0.0)
{
newRay.origin = hit.position + hit.normal * 1e-4;
newRay.direction = reflect(ray.direction, hit.normal);
}
else
{
newRay.origin = hit.position - hit.normal * 1e-4;
newRay.direction = refractedDir;
}
return newRay;
}
// Ray transparencyRay(hitInfo hit, Ray ray, GPUMaterial mat, inout uint rng_state)
// {
// vec3 specular_origin = hit.position + hit.normal * 0.001;
// vec3 specular_dir = mix(normalize(reflect(ray.direction, hit.normal)), lambertRay(hit, ray, mat, rng_state).direction, mat.roughness);
// vec3 transparency_origin = ray.origin + ray.direction * hit.last_t + ray.direction * 0.001;
// vec3 transparency_dir = ray.direction;
// Ray specular_ray = Ray(specular_origin, specular_dir);
// Ray transparency_ray = Ray(transparency_origin, transparency_dir);
// bool is_transparent = (mat.metallic >= randomValue(rng_state));
// if (is_transparent)
// return (transparency_ray);
// return (specular_ray);
// }
Ray newRay(hitInfo hit, Ray ray, inout uint rng_state)
{
@ -45,5 +111,7 @@ Ray newRay(hitInfo hit, Ray ray, inout uint rng_state)
return (lambertRay(hit, ray, mat, rng_state));
else if (mat.type == 1)
return (dieletricRay(hit, ray, mat));
else if (mat.type == 2)
return (transparencyRay(hit, ray, mat, rng_state));
return (ray);
}