+ | Better random

This commit is contained in:
TheRedShip
2025-01-04 18:14:24 +01:00
parent 05387337cf
commit 8f256e5c35
8 changed files with 83 additions and 28 deletions

View File

@ -20,7 +20,7 @@ typedef struct s_Material
glm::vec3 color; glm::vec3 color;
float emission; float emission;
float roughness; float roughness;
float specular; float metallic;
} Material; } Material;
class Object class Object

View File

@ -22,7 +22,7 @@ struct GPUObject
alignas(16) glm::vec3 color; alignas(16) glm::vec3 color;
float emission; float emission;
float roughness; float roughness;
float specular; float metallic;
float radius; // sphere float radius; // sphere
alignas(16) glm::vec3 normal; // plane alignas(16) glm::vec3 normal; // plane

View File

@ -1,12 +1,12 @@
MAT 255 255 255 0.0 0.0 0.0 MAT 255 255 255 0.0 0.0 0.0
MAT 255 255 255 5.0 0.0 0.0 MAT 255 255 255 3.0 0.0 0.0
MAT 255 100 100 0.0 0.0 0.0 MAT 255 100 100 0.0 0.0 0.0
MAT 100 100 255 0.0 0.0 0.0 MAT 100 100 255 0.0 0.0 0.0
MAT 100 255 100 0.0 0.0 0.0 MAT 100 255 100 0.0 0.5 0.0
MAT 255 255 255 0.0 0.98 0.0 MAT 255 255 255 0.0 1.0 0.0
sp 0 -1 0 1 5 sp 0 -1 0 1 5

21
scenes/roughness.rt Normal file
View File

@ -0,0 +1,21 @@
MAT 255 255 255 5.0 0.0 0.0 // white light 0
MAT 255 50 50 0.0 0.0 0.0 // red 1
MAT 50 50 50 0.0 0.0 0.0 // gray 2
MAT 50 255 50 0.0 0.0 0.0 // green 3
MAT 255 255 255 0.0 0.0 0.0 // white 4
// walls of a long width box
pl 0 0 -3 0 0 1 4 // back wall
pl 0 0 3 0 0 -1 4 // front wall
pl 4 0 0 -1 0 0 3 // right wall
pl -4 0 0 1 0 0 1 // left wall
pl 0 3 0 0 -1 0 2 // ceiling
pl 0 -3 0 0 1 0 4 // floor
// light quad
qu -1 2.9 -1 2 0 0 0 0 2 0

View File

@ -10,7 +10,7 @@ struct GPUObject {
vec3 color; // 12 + 4 vec3 color; // 12 + 4
float emission; // 4 float emission; // 4
float roughness; // 4 float roughness; // 4
float specular; // 4 float metallic; // 4
float radius; // 4 float radius; // 4
vec3 normal; // 12 + 4 vec3 normal; // 12 + 4
@ -73,24 +73,27 @@ hitInfo traceRay(Ray ray)
return (hit); return (hit);
} }
Ray newRay(hitInfo hit, Ray ray, vec2 uv) Ray newRay(hitInfo hit, Ray ray, inout uint rng_state)
{ {
GPUObject obj;
Ray new_ray; Ray new_ray;
vec3 in_unit_sphere; // vec3 in_unit_sphere;
in_unit_sphere = normalize(randomVec3(uv, u_time)); obj = objects[hit.obj_index];
in_unit_sphere *= sign(dot(in_unit_sphere, hit.normal));
vec3 diffuse_dir = normalize(hit.normal + in_unit_sphere); // in_unit_sphere = normalize(randomVec3(uv, u_time));
// in_unit_sphere *= sign(dot(in_unit_sphere, hit.normal));
vec3 diffuse_dir = normalize(randomHemisphereDirection(hit.normal, rng_state));
vec3 specular_dir = reflect(ray.direction, hit.normal); vec3 specular_dir = reflect(ray.direction, hit.normal);
new_ray.origin = hit.position + hit.normal * 0.001; new_ray.origin = hit.position + hit.normal * 0.001;
new_ray.direction = mix(diffuse_dir, specular_dir, objects[hit.obj_index].roughness); new_ray.direction = mix(diffuse_dir, specular_dir, obj.roughness);
return (new_ray); return (new_ray);
} }
vec3 pathtrace(Ray ray, vec2 uv) vec3 pathtrace(Ray ray, inout uint rng_state)
{ {
vec3 color = vec3(1.0); vec3 color = vec3(1.0);
vec3 light = vec3(0.0); vec3 light = vec3(0.0);
@ -109,13 +112,12 @@ vec3 pathtrace(Ray ray, vec2 uv)
GPUObject obj = objects[hit.obj_index]; GPUObject obj = objects[hit.obj_index];
color *= obj.color; color *= obj.color;
if (obj.emission > 0.0)
{
light += obj.emission * obj.color;
break;
}
ray = newRay(hit, ray, uv); light += obj.emission * obj.color;
if (obj.emission > 0.0)
break;
ray = newRay(hit, ray, rng_state);
} }
return (color * light); return (color * light);
} }
@ -129,6 +131,9 @@ void main()
vec2 uv = (vec2(pixel_coords) / u_resolution) * 2.0 - 1.0;; vec2 uv = (vec2(pixel_coords) / u_resolution) * 2.0 - 1.0;;
uv.x *= u_resolution.x / u_resolution.y; uv.x *= u_resolution.x / u_resolution.y;
uint rng_state = uint(u_resolution.x) * uint(pixel_coords.y) + pixel_coords.x;
rng_state = rng_state + u_frameCount * 719393;
float fov = 90.0; float fov = 90.0;
float focal_length = 1.0 / tan(radians(fov) / 2.0); float focal_length = 1.0 / tan(radians(fov) / 2.0);
vec3 view_space_ray = normalize(vec3(uv.x, uv.y, -focal_length)); vec3 view_space_ray = normalize(vec3(uv.x, uv.y, -focal_length));
@ -136,8 +141,8 @@ void main()
vec3 ray_direction = normalize((inverse(u_viewMatrix) * vec4(view_space_ray, 0.0)).xyz); vec3 ray_direction = normalize((inverse(u_viewMatrix) * vec4(view_space_ray, 0.0)).xyz);
Ray ray = Ray(u_cameraPosition, ray_direction); Ray ray = Ray(u_cameraPosition, ray_direction);
vec3 color = pathtrace(ray, uv); vec3 color = pathtrace(ray, rng_state);
color = vec3(sqrt(color.x), sqrt(color.y), sqrt(color.z)); // color = vec3(sqrt(color.x), sqrt(color.y), sqrt(color.z));
float blend = 1.0 / float(u_frameCount + 1); float blend = 1.0 / float(u_frameCount + 1);
vec4 accum = imageLoad(accumulation_image, pixel_coords); vec4 accum = imageLoad(accumulation_image, pixel_coords);

View File

@ -42,3 +42,32 @@ vec3 randomVec3(vec2 uv, float time)
{ {
return (vec3((random(uv, time) - 0.5) * 2, (random(uv, time) - 0.5) * 2, (random(uv, time) - 0.5) * 2)); return (vec3((random(uv, time) - 0.5) * 2, (random(uv, time) - 0.5) * 2, (random(uv, time) - 0.5) * 2));
} }
float randomValue(inout uint rng_state)
{
rng_state = rng_state * 747796405 + 2891336453;
uint result = ((rng_state >> ((rng_state >> 28) + 4)) ^ rng_state) * 277803737;
result = (result >> 22) ^ result;
return (result / 4294967295.0);
}
float randomValueNormalDistribution(inout uint rng_state)
{
float theta = 2.0 * 3.14159265359 * randomValue(rng_state);
float rho = sqrt(-2.0 * log(randomValue(rng_state)));
return (rho * cos(theta));
}
vec3 randomDirection(inout uint rng_state)
{
float x = randomValueNormalDistribution(rng_state);
float y = randomValueNormalDistribution(rng_state);
float z = randomValueNormalDistribution(rng_state);
return normalize(vec3(x, y, z));
}
vec3 randomHemisphereDirection(vec3 normal, inout uint rng_state)
{
vec3 direction = randomDirection(rng_state);
return (direction * sign(dot(normal, direction)));
}

View File

@ -76,7 +76,7 @@ void Scene::updateGPUData()
gpu_obj.color = mat->color; gpu_obj.color = mat->color;
gpu_obj.emission = mat->emission; gpu_obj.emission = mat->emission;
gpu_obj.roughness = mat->roughness; gpu_obj.roughness = mat->roughness;
gpu_obj.specular = mat->specular; gpu_obj.metallic = mat->metallic;
gpu_obj.type = static_cast<int>(obj->getType()); gpu_obj.type = static_cast<int>(obj->getType());

View File

@ -38,10 +38,10 @@ void SceneParser::parseMaterial(std::stringstream &line)
float r,g,b; float r,g,b;
float emission; float emission;
float roughness; float roughness;
float specular; float metallic;
Material *mat; Material *mat;
if (!(line >> r >> g >> b >> emission >> roughness >> specular)) if (!(line >> r >> g >> b >> emission >> roughness >> metallic))
throw std::runtime_error("Material: Missing material properties"); throw std::runtime_error("Material: Missing material properties");
mat = new Material; mat = new Material;
@ -49,7 +49,7 @@ void SceneParser::parseMaterial(std::stringstream &line)
mat->color = glm::vec3(r / 255.0f, g / 255.0f, b / 255.0f); mat->color = glm::vec3(r / 255.0f, g / 255.0f, b / 255.0f);
mat->emission = emission; mat->emission = emission;
mat->roughness = roughness; mat->roughness = roughness;
mat->specular = specular; mat->metallic = metallic;
_scene->addMaterial(mat); _scene->addMaterial(mat);
} }