144 lines
3.9 KiB
GLSL
144 lines
3.9 KiB
GLSL
#version 430
|
|
|
|
layout(local_size_x = 1, local_size_y = 1) in; // size of local work group - 1 pixel
|
|
|
|
// gbuffer?
|
|
layout(rgba32f, binding = 2) readonly uniform image2D _g0;
|
|
layout(rgba32f, binding = 3) readonly uniform image2D _g1;
|
|
|
|
// final output
|
|
layout(rgba32f, binding = 0) uniform image2D img_output; // rgba32f defines internal format, image2d for random write to output texture
|
|
|
|
//uniform vec3 _skyColor = vec3(0.75,0.9,1.0);
|
|
uniform vec3 _skyColor = vec3(1.0,1.0,1.0);
|
|
|
|
// TODO: some of these depend on each other!! need be be in this order for now c:
|
|
#include func.glsl
|
|
#include constants.glsl
|
|
#include time.glsl
|
|
#include sphere.glsl
|
|
#include ray.glsl
|
|
#include intersect.glsl
|
|
#include random.glsl
|
|
#include camera.glsl
|
|
#include image.glsl
|
|
// scene.glsl includes scene trace function
|
|
#include scene.glsl
|
|
#include lighting.glsl
|
|
#include depth.glsl
|
|
|
|
vec3 shade(inout Ray ray, RayHit hit)
|
|
{
|
|
if (hit.distance < INF)
|
|
{
|
|
switch (hit.material)
|
|
{
|
|
case MAT_SKY: break;
|
|
case MAT_LAMBERT:
|
|
scatterLambert(ray, hit);
|
|
break;
|
|
case MAT_CHROME:
|
|
return scatterMetal(ray, hit);
|
|
break;
|
|
case MAT_GLOW:
|
|
return scatterGlow(ray, hit);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// sky color
|
|
return _skyColor;
|
|
//ray.distance = INF;
|
|
//return _skyColor * (1-getLinearDepth(ray.distance));
|
|
//return vec3(1.0,0.0,0.0);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
// base pixel colour for the image
|
|
//vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
|
|
vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
|
ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy);
|
|
ivec2 dims = imageSize(img_output);
|
|
|
|
vec2 uv = pixelUv(pixelCoords, dims);
|
|
|
|
vec4 g[2];
|
|
|
|
// load data from first pass
|
|
g[0] = imageLoad(_g0, ivec2(gl_GlobalInvocationID.xy));
|
|
float depth = g[0].w;
|
|
vec3 normal = g[0].xyz*2.0-1.0; // unpack normal packaged into texture
|
|
|
|
g[1] = imageLoad(_g1, ivec2(gl_GlobalInvocationID.xy));
|
|
vec3 albedo = g[1].xyz;
|
|
|
|
// create a ray from the uv
|
|
Ray ray = createCameraRay(uv);
|
|
RayHit firstHit;
|
|
firstHit.position = ray.origin+ray.direction*depth;
|
|
firstHit.distance = depth;
|
|
firstHit.normal = normal;
|
|
firstHit.albedo = albedo;
|
|
|
|
int bounces = BOUNCES;
|
|
//pixel.xyz = mix(pixel.xyz, _skyColor, sky);
|
|
|
|
// sample
|
|
int samples = 2;
|
|
//int reflections = 0;
|
|
//depth = 0;
|
|
float tracedDepth = 0;
|
|
for (int i = 0; i < samples; i++)
|
|
{
|
|
float sampleDepth = 0;
|
|
|
|
// trace the ray's path around the scene
|
|
for (int j = 0; j < bounces; j++)
|
|
{
|
|
RayHit hit = trace(ray);
|
|
|
|
//ray.distance = hit.material == MAT_CHROME
|
|
// ? ray.distance * hit.material
|
|
// : 0;
|
|
//int reflection = hit.material == MAT_CHROME ? 1 : 0;
|
|
//reflections |= (reflection << j);
|
|
|
|
sampleDepth = getLogarithmicDepth(ray.distance);
|
|
|
|
pixel.xyz += ray.energy * shade(ray, hit);
|
|
|
|
if (length(ray.energy) < 0.001) break;
|
|
}
|
|
|
|
//depth = max(getLogarithmicDepth(ray.distance
|
|
tracedDepth += sampleDepth / float(samples);
|
|
}
|
|
|
|
|
|
// apply gamma correction
|
|
float gamma = 2.0;
|
|
float scale = 1.0 / gamma;
|
|
pixel.xyz = sqrt(pixel.xyz * scale);
|
|
pixel.xyz /= 2.0;
|
|
//
|
|
// apply fog
|
|
//float fogDepth = (clamp(tracedDepth - depth, 0, 1) - 1.0) * 2.0;
|
|
//fogDepth *= depth * depth;
|
|
//fogDepth -= depth;
|
|
//fogDepth = depth * tracedDepth;
|
|
vec3 fogColor = _skyColor;
|
|
pixel.xyz = mix(pixel.xyz, fogColor, depth);
|
|
//pixel = clamp(pixel, 0, 1);
|
|
|
|
//tracedDepth = max(depth,
|
|
//tracedDepth -= 0.2;
|
|
//tracedDepth *= (5.0/4.0);
|
|
vec3 depthDebugColor = mix(vec3(depth), vec3(fogDepth), step(-uv.x, 0.0));
|
|
pixel.xyz = mix(pixel.xyz, depthDebugColor, 1);
|
|
|
|
// output to a specific pixel in the image
|
|
imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
|
|
}
|