oglc/shader/root/rt.glsl

148 lines
4.1 KiB
Plaintext
Raw Normal View History

2021-07-24 02:31:35 +02:00
#version 430
2021-08-03 00:32:47 +02:00
// TODO: do i actually need explicit location descriptors?
layout (location = 1) uniform vec4 _t;
2021-07-24 02:31:35 +02:00
2021-08-03 00:32:47 +02:00
layout (location = 2) uniform vec3 _w; // view space axes
layout (location = 3) uniform vec3 _u;
layout (location = 4) uniform vec3 _v;
2021-08-02 10:35:39 +02:00
2021-08-03 00:32:47 +02:00
layout (location = 5) uniform mat4 _cameraInverseProjection;
layout (location = 6) uniform vec3 _camh;
layout (location = 7) uniform vec3 _camv;
layout (location = 8) uniform vec3 _camll;
layout (location = 9) uniform vec3 _cpos;
layout (location = 10) uniform vec3 _tpos; // target
2021-07-30 03:06:59 +02:00
2021-08-03 00:32:47 +02:00
layout(local_size_x = 1, local_size_y = 1) in; // size of local work group - 1 pixel
layout(rgba32f, binding = 0) uniform image2D img_output; // rgba32f defines internal format, image2d for random write to output texture
2021-07-24 02:31:35 +02:00
2021-08-03 00:32:47 +02:00
const float INF = 30.0;
2021-07-24 02:31:35 +02:00
2021-07-30 00:39:04 +02:00
#include sphere.glsl
2021-07-24 02:31:35 +02:00
struct Ray
{
vec3 origin;
vec3 direction;
};
struct RayHit
{
vec3 position;
float distance;
vec3 normal;
2021-08-02 10:35:39 +02:00
vec3 albedo;
2021-07-24 02:31:35 +02:00
};
void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
{
vec3 d = ray.origin-sphere.center;
float p1 = -dot(ray.direction,d);
float p2sqr = p1*p1-dot(d,d)+sphere.radius*sphere.radius;
if (p2sqr < 0) return;
float p2 = sqrt(p2sqr);
float t = p1-p2 > 0 ? p1-p2 : p1+p2;
if (t > 0 && t < bestHit.distance)
{
bestHit.distance = t;
bestHit.position = ray.origin + t*ray.direction;
bestHit.normal = normalize(bestHit.position-sphere.center);
2021-08-02 10:35:39 +02:00
bestHit.albedo = sphere.albedo;
2021-07-24 02:31:35 +02:00
}
}
Ray createCameraRay(vec2 uv)
{
// transform -1..1 -> 0..1
2021-08-02 10:35:39 +02:00
uv = uv*0.5+0.5;
2021-07-24 02:31:35 +02:00
//uv.x=1-uv.x;
2021-08-03 00:32:47 +02:00
vec3 target = vec3(0,0,0);
2021-07-24 02:31:35 +02:00
// transform camera origin to world space
// TODO: c2w matrix!! for now we just assume the camera is at the origin
// float3 origin = mul(_CameraToWorld, float4(0.0,0.0,0.0,1.0)).xyz;
// TODO: offset from centre of the lens for depth of field
// float2 rd = _CameraLensRadius * randomInUnitDisk();
// float3 offset = _CameraU * rd.x + _CameraV * rd.y;
2021-08-02 10:35:39 +02:00
// invert perspective projection of view space position
//vec3 dir = mul(_cameraInverseProjection, float4(uv, 0.0, 1.0)).xyz;
// TODO: transform direction from camera to world space (move camera around!)
vec3 dir;
dir = uv.x*_camh + uv.y*_camv;
dir = _camll + uv.x*_camh + uv.y*_camv;
dir = normalize(dir);
2021-07-24 02:31:35 +02:00
float max_x = 5.0;
float max_y = 5.0;
Ray ray;
2021-08-03 00:32:47 +02:00
ray.origin = _cpos;
2021-08-02 10:35:39 +02:00
ray.direction = dir;
2021-07-24 02:31:35 +02:00
return ray;
2021-08-03 00:32:47 +02:00
};
2021-07-24 02:31:35 +02:00
void main()
{
// base pixel colour for the image
vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
// get index in global work group ie xy position
ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy);
// set up ray based on pixel position, project it forward with an orthographic projection
ivec2 dims = imageSize(img_output); // fetch image dimensions
vec2 uv;
uv.x = (float(pixel_coords.x * 2 - dims.x) / dims.x) * dims.x/dims.y; // account for aspect ratio
uv.y = (float(pixel_coords.y * 2 - dims.y) / dims.y);
Ray ray = createCameraRay(uv);
RayHit hit;
hit.position = vec3(0.0,0.0,0.0);
hit.distance = INF;
hit.normal = vec3(0.0,0.0,0.0);
2021-08-02 10:35:39 +02:00
hit.albedo = vec3(0.0,0.0,0.0);
2021-08-03 00:32:47 +02:00
vec3 spheresCenter = vec3(0.0,0.0,0.0);
2021-08-02 10:35:39 +02:00
2021-08-03 00:32:47 +02:00
float t = _t.x;
2021-08-02 10:35:39 +02:00
Sphere s1;
2021-08-03 00:32:47 +02:00
s1.center = spheresCenter+vec3(sin(t),0.0,cos(t))*2.5;
2021-08-02 10:35:39 +02:00
s1.radius = 2.0;
s1.albedo = vec3(1.0,0.0,0.0);
2021-08-03 00:32:47 +02:00
t+=3.1415/1.5;
2021-08-02 10:35:39 +02:00
Sphere s2;
2021-08-03 00:32:47 +02:00
s2.center = spheresCenter+vec3(sin(t),0.0,cos(t))*2.5;
2021-08-02 10:35:39 +02:00
s2.radius = 2.0;
2021-08-03 00:32:47 +02:00
s2.albedo = vec3(0.0,1.0,0.0);
2021-07-24 02:31:35 +02:00
2021-08-03 00:32:47 +02:00
t+=3.1415/1.5;
Sphere s3;
s3.center = spheresCenter+vec3(sin(t),0.0,cos(t))*2.5;
s3.radius = 2.0;
s3.albedo = vec3(0.0,0.0,1.0);
2021-07-24 02:31:35 +02:00
// ray-sphere intersection
2021-08-02 10:35:39 +02:00
intersectSphere(ray, hit, s1);
intersectSphere(ray, hit, s2);
2021-08-03 00:32:47 +02:00
intersectSphere(ray, hit, s3);
2021-07-24 02:31:35 +02:00
2021-08-02 10:35:39 +02:00
// TODO: write depth to texture
float depth = hit.distance/INF;
2021-07-30 03:06:59 +02:00
2021-08-02 10:35:39 +02:00
pixel = vec4(hit.albedo,1.0);
2021-07-30 03:06:59 +02:00
pixel *= (1.0-depth);
2021-07-24 02:31:35 +02:00
// output to a specific pixel in the image
imageStore(img_output, pixel_coords, pixel);
}