Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Cat Flynn | 202ec0673f |
|
@ -1,9 +1,10 @@
|
||||||
const float INF = 45.0;
|
const float INF = 20.0;
|
||||||
const float PI = 3.14159;
|
const float PI = 3.14159;
|
||||||
const float E = 2.71828;
|
const float E = 2.71828;
|
||||||
const int BOUNCES = 5;
|
const int BOUNCES = 4;
|
||||||
|
|
||||||
// materials
|
// materials
|
||||||
const int MAT_SKY = -1;
|
const int MAT_SKY = -1;
|
||||||
const int MAT_LAMBERT = 0;
|
const int MAT_LAMBERT = 0;
|
||||||
const int MAT_CHROME = 1;
|
const int MAT_CHROME = 1;
|
||||||
|
const int MAT_GLOW = 2;
|
||||||
|
|
|
@ -12,5 +12,8 @@ float getLogarithmicDepth(float distance)
|
||||||
float z = distance;
|
float z = distance;
|
||||||
|
|
||||||
// logarithmic depth
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal)
|
||||||
{
|
{
|
||||||
float denom = dot(normal, ray.direction);
|
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.distance = t;
|
||||||
bestHit.position = ray.origin + t*ray.direction;
|
bestHit.position = ray.origin + t*ray.direction;
|
||||||
bestHit.normal = normal;
|
bestHit.normal = normal;
|
||||||
bestHit.albedo = vec3(1.0,.4,.4);
|
bestHit.albedo = vec3(1.0,.8,.7);
|
||||||
bestHit.material = MAT_LAMBERT;
|
bestHit.material = MAT_LAMBERT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,18 +35,30 @@ vec3 sampleHemisphere(vec3 normal)
|
||||||
|
|
||||||
vec3 scatterMetal(inout Ray ray, RayHit hit)
|
vec3 scatterMetal(inout Ray ray, RayHit hit)
|
||||||
{
|
{
|
||||||
|
//float d = length(ray.origin - hit.position);
|
||||||
ray.origin = hit.position + hit.normal*0.001;
|
ray.origin = hit.position + hit.normal*0.001;
|
||||||
ray.direction = reflect(ray.direction,hit.normal);
|
ray.direction = reflect(ray.direction,hit.normal);
|
||||||
ray.energy *= 0.5;
|
ray.energy *= 0.95;
|
||||||
|
|
||||||
return vec3(0.0);
|
return vec3(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 scatterLambert(inout Ray ray, RayHit hit)
|
vec3 scatterLambert(inout Ray ray, RayHit hit)
|
||||||
{
|
{
|
||||||
|
//float d = length(ray.origin - hit.position);
|
||||||
ray.origin = hit.position + hit.normal*0.001;
|
ray.origin = hit.position + hit.normal*0.001;
|
||||||
ray.direction = sampleHemisphere(hit.normal);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -11,35 +11,19 @@ RayHit trace(inout Ray ray)
|
||||||
intersectSphere(ray, hit, _spheres[i]);
|
intersectSphere(ray, hit, _spheres[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sphereCount = 10;
|
|
||||||
for (int i = 0; i < sphereCount; i++)
|
|
||||||
{
|
|
||||||
Sphere s;
|
Sphere s;
|
||||||
float a = i/float(sphereCount)*2.0*PI;
|
s.cr = vec4(0.0,0.0,0.0,INF*2.0);
|
||||||
float d = 17.0 + cos((1.3+a)*3.0) * 3.0;
|
s.material = MAT_GLOW;
|
||||||
float r = 4.0 + sin(a*3.0)*2.0;
|
s.albedo = vec3(1.0,1.0,1.0);
|
||||||
s.cr = vec4(sin(a)*d,2.0*r+cos(a*5.0),cos(a)*d, r);
|
intersectInsideOutSphere(ray, hit, s);
|
||||||
s.albedo = vec3(.2);
|
|
||||||
s.material = i % 3 == 0 ? MAT_CHROME : MAT_LAMBERT;
|
|
||||||
|
|
||||||
intersectSphere(ray, hit, s);
|
//ray.distance += hit.material == MAT_CHROME
|
||||||
}
|
// ? hit.distance * length(ray.energy) * float(hit.distance < INF)
|
||||||
|
// : hit.distance * float(hit.distance < INF);
|
||||||
sphereCount = 3;
|
//ray.distance += hit.distance * float(hit.distance < INF);
|
||||||
for (int i = 0; i < sphereCount; i++)
|
ray.distance += hit.distance;
|
||||||
{
|
//ray.distance = clamp(ray.distance, 0, INF);
|
||||||
Sphere s;
|
//ray.distance += hit.distance * length(ray.energy);
|
||||||
float a = i/float(sphereCount)*2.0*PI;
|
|
||||||
float d = 5.0 + cos((5.34+a)*5.0) * 3.0;
|
|
||||||
float r = 3.0 + sin(a*2.0)*1.5;
|
|
||||||
s.cr = vec4(sin(a)*d,4.0*r+cos(a*5.0),cos(a)*d, r);
|
|
||||||
s.albedo = vec3(.2);
|
|
||||||
s.material = i % 3 == 0 ? MAT_CHROME : MAT_LAMBERT;
|
|
||||||
|
|
||||||
intersectSphere(ray, hit, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
ray.distance += hit.distance * float(hit.distance < INF);
|
|
||||||
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,9 @@ vec4 denoise(sampler2D tex, vec2 uv, float sigma, float kSigma, float threshold)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float sigma = 2.5;
|
float sigma = 2.2;
|
||||||
float kSigma = 7.0;
|
float kSigma = 10.0;
|
||||||
float threshold = 0.3;
|
float threshold = 0.2;
|
||||||
|
|
||||||
FragColor = denoise(ourTexture, TexCoord, sigma, kSigma, threshold);
|
FragColor = denoise(ourTexture, TexCoord, sigma, kSigma, threshold);
|
||||||
//FragColor = texture(ourTexture, TexCoord);
|
//FragColor = texture(ourTexture, TexCoord);
|
||||||
|
|
|
@ -9,7 +9,8 @@ layout(rgba32f, binding = 3) readonly uniform image2D _g1;
|
||||||
// final output
|
// final output
|
||||||
layout(rgba32f, binding = 0) uniform image2D img_output; // rgba32f defines internal format, image2d for random write to output texture
|
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:
|
// TODO: some of these depend on each other!! need be be in this order for now c:
|
||||||
#include func.glsl
|
#include func.glsl
|
||||||
|
@ -39,16 +40,23 @@ vec3 shade(inout Ray ray, RayHit hit)
|
||||||
case MAT_CHROME:
|
case MAT_CHROME:
|
||||||
return scatterMetal(ray, hit);
|
return scatterMetal(ray, hit);
|
||||||
break;
|
break;
|
||||||
|
case MAT_GLOW:
|
||||||
|
return scatterGlow(ray, hit);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sky color
|
// sky color
|
||||||
return _skyColor;
|
return _skyColor;
|
||||||
|
//ray.distance = INF;
|
||||||
|
//return _skyColor * (1-getLinearDepth(ray.distance));
|
||||||
|
//return vec3(1.0,0.0,0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// base pixel colour for the image
|
// 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);
|
vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy);
|
ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
@ -74,12 +82,14 @@ void main()
|
||||||
firstHit.normal = normal;
|
firstHit.normal = normal;
|
||||||
firstHit.albedo = albedo;
|
firstHit.albedo = albedo;
|
||||||
|
|
||||||
int sky = depth >= INF ? 1 : 0;
|
int bounces = BOUNCES;
|
||||||
int bounces = (1-sky) * BOUNCES;
|
//pixel.xyz = mix(pixel.xyz, _skyColor, sky);
|
||||||
pixel.xyz = mix(pixel.xyz, _skyColor, sky);
|
|
||||||
|
|
||||||
// sample
|
// sample
|
||||||
int samples = 2;
|
int samples = 2;
|
||||||
|
//int reflections = 0;
|
||||||
|
//depth = 0;
|
||||||
|
float tracedDepth = 0;
|
||||||
for (int i = 0; i < samples; i++)
|
for (int i = 0; i < samples; i++)
|
||||||
{
|
{
|
||||||
float sampleDepth = 0;
|
float sampleDepth = 0;
|
||||||
|
@ -89,24 +99,44 @@ void main()
|
||||||
{
|
{
|
||||||
RayHit hit = trace(ray);
|
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);
|
pixel.xyz += ray.energy * shade(ray, hit);
|
||||||
|
|
||||||
if (length(ray.energy) < 0.001) break;
|
if (length(ray.energy) < 0.001) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
depth += sampleDepth / float(samples);
|
//depth = max(getLogarithmicDepth(ray.distance
|
||||||
|
tracedDepth += sampleDepth / float(samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// include the first sample we took
|
// apply gamma correction
|
||||||
samples++;
|
float gamma = 2.0;
|
||||||
// gamma correction
|
float scale = 1.0 / gamma;
|
||||||
float scale = 1.0 / samples;
|
pixel.xyz = sqrt(pixel.xyz * scale);
|
||||||
pixel.xyz = sqrt(scale * pixel.xyz);
|
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);
|
||||||
|
|
||||||
pixel.xyz = mix(pixel.xyz, vec3(1.0), depth);
|
//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
|
// output to a specific pixel in the image
|
||||||
imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
|
imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
|
||||||
|
|
|
@ -44,6 +44,6 @@ void main()
|
||||||
imageStore(g0_output, pixelCoords, pixel);
|
imageStore(g0_output, pixelCoords, pixel);
|
||||||
|
|
||||||
pixel.xyz = hit.albedo;
|
pixel.xyz = hit.albedo;
|
||||||
pixel.w = 0;
|
pixel.w = hit.material;
|
||||||
imageStore(g1_output, pixelCoords, pixel);
|
imageStore(g1_output, pixelCoords, pixel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ void updateUniforms(GLuint shaderProgram, float t)
|
||||||
updateCameraUniforms(shaderProgram, aspect, t);
|
updateCameraUniforms(shaderProgram, aspect, t);
|
||||||
|
|
||||||
// make and update spheres
|
// make and update spheres
|
||||||
const int sphereCount = 25;
|
const int sphereCount = 41;
|
||||||
struct Sphere spheres[sphereCount];
|
struct Sphere spheres[sphereCount];
|
||||||
makeSpheres(spheres, sphereCount, t);
|
makeSpheres(spheres, sphereCount, t);
|
||||||
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
updateSphereUniforms(shaderProgram, spheres, sphereCount);
|
||||||
|
|
15
src/sphere.c
15
src/sphere.c
|
@ -2,6 +2,17 @@
|
||||||
|
|
||||||
void makeSpheres(struct Sphere *spheres, int count, float t)
|
void makeSpheres(struct Sphere *spheres, int count, float t)
|
||||||
{
|
{
|
||||||
|
vec3 albedos[] =
|
||||||
|
{
|
||||||
|
{0.0,0.0,1.0},
|
||||||
|
{0.0,1.0,0.0},
|
||||||
|
{0.0,1.0,1.0},
|
||||||
|
{1.0,0.0,0.0},
|
||||||
|
{1.0,0.0,1.0},
|
||||||
|
{1.0,1.0,0.0},
|
||||||
|
{1.0,1.0,1.0}
|
||||||
|
};
|
||||||
|
|
||||||
vec3 sc = {0.0,0.0,1.0};
|
vec3 sc = {0.0,0.0,1.0};
|
||||||
|
|
||||||
int sphereIdx = 0;
|
int sphereIdx = 0;
|
||||||
|
@ -19,13 +30,13 @@ void makeSpheres(struct Sphere *spheres, int count, float t)
|
||||||
int rainbowSpheres = count - middleSpheres;
|
int rainbowSpheres = count - middleSpheres;
|
||||||
// distance from center
|
// distance from center
|
||||||
float d = 6.0;
|
float d = 6.0;
|
||||||
radius = 0.7;
|
radius = 0.5;
|
||||||
float x;
|
float x;
|
||||||
for (int i = 0; i < rainbowSpheres; i++)
|
for (int i = 0; i < rainbowSpheres; i++)
|
||||||
{
|
{
|
||||||
x = 2.0*CGLM_PI * (float)i/(float)rainbowSpheres;
|
x = 2.0*CGLM_PI * (float)i/(float)rainbowSpheres;
|
||||||
sc[0] = sin(x)*d;
|
sc[0] = sin(x)*d;
|
||||||
sc[1] = radius*sin(x*3.0-5.0*sin(t));
|
sc[1] = sin(x*3.0-5.0*sin(t));
|
||||||
sc[2] = cos(x)*d;
|
sc[2] = cos(x)*d;
|
||||||
|
|
||||||
float ic = i/(float)rainbowSpheres*CGLM_PI*2.0;
|
float ic = i/(float)rainbowSpheres*CGLM_PI*2.0;
|
||||||
|
|
Loading…
Reference in New Issue