From 7777a2a52697f4712a7a90ba31454275451fad9a Mon Sep 17 00:00:00 2001 From: saschawillems Date: Mon, 28 Mar 2016 00:18:10 +0200 Subject: [PATCH] Ray tracer reflections (wip) --- data/shaders/raytracing/raytracing.comp | 101 +++++++++++++------- data/shaders/raytracing/raytracing.comp.spv | Bin 11352 -> 13260 bytes 2 files changed, 67 insertions(+), 34 deletions(-) diff --git a/data/shaders/raytracing/raytracing.comp b/data/shaders/raytracing/raytracing.comp index c66eda29..e6e9bb67 100644 --- a/data/shaders/raytracing/raytracing.comp +++ b/data/shaders/raytracing/raytracing.comp @@ -13,6 +13,8 @@ layout (binding = 0, rgba8) uniform image2D resultImage; #define PLANEID 1 #define SPHERECOUNT 3 #define SHADOW 0.5 +#define RAYBOUNCES 1 +#define REFLECTIONSTRENGTH 0.25 struct Camera { vec3 pos; @@ -29,6 +31,11 @@ layout (binding = 1) uniform UBO mat4 rotMat; } ubo; +void reflectRay(inout vec3 rayD, in vec3 mormal) +{ + rayD = rayD + 2.0 * -dot(mormal, rayD) * mormal; +} + // Lighting calculations float lightDiffuse(vec3 normal, vec3 lightDir) @@ -102,7 +109,7 @@ int intersect(in vec3 rayO, in vec3 rayD, out float resT) for (int i = 0; i < SPHERECOUNT; i++) { float tSphere = sphereIntersect(rayO, rayD, spheres[i]); - if (tSphere > 0.0) + if (tSphere > EPSILON) { id = spheres[i].id; resT = tSphere; @@ -111,7 +118,7 @@ int intersect(in vec3 rayO, in vec3 rayD, out float resT) } float tplane = planeIntersect(rayO, rayD); - if ((tplane > 0.0) && (tplane < resT)) + if ((tplane > EPSILON) && (tplane < resT)) { id = PLANEID; resT = tplane; @@ -138,6 +145,53 @@ vec3 fog(in float t, in vec3 color) return mix(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0)); } +vec3 renderScene(inout vec3 rayO, inout vec3 rayD, inout int id) +{ + vec3 color = vec3(0.0); + float t = 0.0; + + // Get intersected object ID + int objectID = intersect(rayO, rayD, t); + + vec3 pos = rayO + t * rayD; + vec3 lightVec = normalize(ubo.lightPos - pos); + vec3 normal; + + if (objectID == PLANEID) + { + normal = planeNormal(pos); + float diffuse = clamp(dot(normal, lightVec), 0.0, 1.0); + color = vec3(1.0, 1.0, 1.0) * diffuse; + } + else + { + for (int i = 0; i < SPHERECOUNT; i++) + { + if (objectID == spheres[i].id) + { + normal = sphereNormal(pos, spheres[i]); + float diffuse = lightDiffuse(normal, lightVec); + float specular = lightSpecular(normal, lightVec); + color = diffuse * spheres[i].material.diffuse + specular * spheres[i].material.specular; + } + } + } + + id = objectID; + + // Shadows + color *= calcShadow(pos, lightVec, objectID); + + // Fog + color = fog(t, color); + + // Reflect ray for next render pass + reflectRay(rayD, normal); + rayO = pos; + + return color; +} + void main() { // Scene setup @@ -160,47 +214,26 @@ void main() spheres[2].material.diffuse = vec3(0.0, 1.0, 0.0); spheres[2].material.specular = vec3(1.0, 1.0, 1.0); - ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy); ivec2 dim = imageSize(resultImage); - vec2 uv = vec2(gl_GlobalInvocationID.xy)/dim; + vec2 uv = vec2(gl_GlobalInvocationID.xy) / dim; vec3 rayO = ubo.camera.pos; vec3 rayD = normalize(vec3((-1.0 + 2.0 * uv) * vec2(ubo.aspectRatio, 1.0), -1.0)); - // Get intersected object ID - float t; - int objectID = intersect(rayO, rayD, t); + // Basic color path + int id = 0; + vec3 finalColor = renderScene(rayO, rayD, id); - vec3 color = vec3(0.0); - - vec3 pos = rayO + t * rayD; - vec3 lightVec = normalize(ubo.lightPos - pos); - - if (objectID == PLANEID) + bool reflections = true; + // Reflection + if (reflections) { - vec3 normal = planeNormal(pos); - float diffuse = clamp(dot(normal, lightVec), 0.0, 1.0); - color = vec3(1.0, 1.0, 1.0) * diffuse; - } - else - { - for (int i = 0; i < SPHERECOUNT; i++) + for (int i = 0; i < RAYBOUNCES; i++) { - if (objectID == spheres[i].id) - { - vec3 normal = sphereNormal(pos, spheres[i]); - float diffuse = lightDiffuse(normal, lightVec); - float specular = lightSpecular(normal, lightVec); - color = diffuse * spheres[i].material.diffuse + specular * spheres[i].material.specular; - } + vec3 reflectionColor = renderScene(rayO, rayD, id); + finalColor = (1.0 - REFLECTIONSTRENGTH) * finalColor + REFLECTIONSTRENGTH * mix(reflectionColor, finalColor, 1.0 - REFLECTIONSTRENGTH); } } - - // Shadows - color *= calcShadow(pos, lightVec, objectID); - - // Fog - color = fog(t, color); - imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(color, 0.0)); + imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(finalColor, 0.0)); } \ No newline at end of file diff --git a/data/shaders/raytracing/raytracing.comp.spv b/data/shaders/raytracing/raytracing.comp.spv index 91cb7a55405dfd3129df567caf5132f6bba0f2fe..3bcb26515cd9197f6fa9b9d5458210d88b1e4749 100644 GIT binary patch literal 13260 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