diff --git a/shader/include/constants.glsl b/shader/include/constants.glsl index 104b27f..ece0918 100644 --- a/shader/include/constants.glsl +++ b/shader/include/constants.glsl @@ -1,9 +1,10 @@ -const float INF = 30.0; +const float INF = 20.0; const float PI = 3.14159; const float E = 2.71828; -const int BOUNCES = 5; +const int BOUNCES = 4; // materials const int MAT_SKY = -1; const int MAT_LAMBERT = 0; const int MAT_CHROME = 1; +const int MAT_GLOW = 2; diff --git a/shader/include/depth.glsl b/shader/include/depth.glsl index 34fc7f2..e524b43 100644 --- a/shader/include/depth.glsl +++ b/shader/include/depth.glsl @@ -7,10 +7,13 @@ float getLogarithmicDepth(float distance) { // n roughly correlates to steepness of log curve // TODO: what does this mean in mathematical terms?? - float n = 4; + float n = 2; float f = INF; float z = distance; // logarithmic depth - return max(0,log(z*pow(E,n)/f)/n); + float d = log(z*pow(E,n)/f)/n; + //d = d < 0 ? 1 : d; + return d; + //return max(0,d); } diff --git a/shader/include/intersect.glsl b/shader/include/intersect.glsl index 403e743..5b00e78 100644 --- a/shader/include/intersect.glsl +++ b/shader/include/intersect.glsl @@ -21,6 +21,29 @@ void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere) } } +void intersectInsideOutSphere(Ray ray, inout RayHit bestHit, Sphere sphere) +{ + vec3 c = sphere.cr.xyz; + float r = sphere.cr.w; + + vec3 d = ray.origin-c; + float p1 = -dot(ray.direction,d); + float p2sqr = p1*p1-dot(d,d)+r*r; + + 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-c); + bestHit.albedo = sphere.albedo; + bestHit.material = sphere.material; + } +} + void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal) { float denom = dot(normal, ray.direction); @@ -33,7 +56,7 @@ void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal) bestHit.distance = t; bestHit.position = ray.origin + t*ray.direction; bestHit.normal = normal; - bestHit.albedo = vec3(1.0,.4,.4); + bestHit.albedo = vec3(1.0,.8,.7); bestHit.material = MAT_LAMBERT; } } diff --git a/shader/include/lighting.glsl b/shader/include/lighting.glsl index 5456b56..b9168d6 100644 --- a/shader/include/lighting.glsl +++ b/shader/include/lighting.glsl @@ -35,18 +35,30 @@ vec3 sampleHemisphere(vec3 normal) vec3 scatterMetal(inout Ray ray, RayHit hit) { + //float d = length(ray.origin - hit.position); ray.origin = hit.position + hit.normal*0.001; ray.direction = reflect(ray.direction,hit.normal); - ray.energy *= 0.5; + ray.energy *= 0.95; return vec3(0.0); } vec3 scatterLambert(inout Ray ray, RayHit hit) { + //float d = length(ray.origin - hit.position); ray.origin = hit.position + hit.normal*0.001; ray.direction = sampleHemisphere(hit.normal); - ray.energy *= hit.albedo * sdot(hit.normal, ray.direction); + ray.energy = hit.albedo * sdot(hit.normal, ray.direction); + //ray.distance += d; return vec3(0.0); } + +vec3 scatterGlow(inout Ray ray, RayHit hit) +{ + ray.origin = hit.position + hit.normal*0.001; + //ray.direction = reflect(ray.direction,hit.normal); + ray.energy = hit.albedo * 2.0; + + return vec3(hit.albedo); +} diff --git a/shader/include/scene.glsl b/shader/include/scene.glsl index c9a20ec..610c8ac 100644 --- a/shader/include/scene.glsl +++ b/shader/include/scene.glsl @@ -11,7 +11,19 @@ RayHit trace(inout Ray ray) intersectSphere(ray, hit, _spheres[i]); } - ray.distance += hit.distance * float(hit.distance < INF); + Sphere s; + s.cr = vec4(0.0,0.0,0.0,INF*2.0); + s.material = MAT_GLOW; + s.albedo = vec3(1.0,1.0,1.0); + intersectInsideOutSphere(ray, hit, s); + + //ray.distance += hit.material == MAT_CHROME + // ? hit.distance * length(ray.energy) * float(hit.distance < INF) + // : hit.distance * float(hit.distance < INF); + //ray.distance += hit.distance * float(hit.distance < INF); + ray.distance += hit.distance; + //ray.distance = clamp(ray.distance, 0, INF); + //ray.distance += hit.distance * length(ray.energy); return hit; } diff --git a/shader/root/rt.glsl b/shader/root/rt.glsl index c081533..8849765 100644 --- a/shader/root/rt.glsl +++ b/shader/root/rt.glsl @@ -9,7 +9,8 @@ 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.68,0.85,0.9); +//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 @@ -39,16 +40,23 @@ vec3 shade(inout Ray ray, RayHit hit) 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); @@ -74,12 +82,14 @@ void main() firstHit.normal = normal; firstHit.albedo = albedo; - int sky = depth >= INF ? 1 : 0; - int bounces = (1-sky) * BOUNCES; - pixel.xyz = mix(pixel.xyz, _skyColor, sky); + 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; @@ -89,17 +99,44 @@ void main() { RayHit hit = trace(ray); - depth = getLogarithmicDepth(ray.distance); + //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 += sampleDepth / float(samples); + //depth = max(getLogarithmicDepth(ray.distance + tracedDepth += sampleDepth / float(samples); } - pixel.xyz = mix(pixel.xyz, vec3(1.0), depth); + + // 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); diff --git a/shader/root/rtpre.glsl b/shader/root/rtpre.glsl index 047b644..fb7f2ec 100644 --- a/shader/root/rtpre.glsl +++ b/shader/root/rtpre.glsl @@ -44,6 +44,6 @@ void main() imageStore(g0_output, pixelCoords, pixel); pixel.xyz = hit.albedo; - pixel.w = 0; + pixel.w = hit.material; imageStore(g1_output, pixelCoords, pixel); }