Ray tracing shadows

This commit is contained in:
saschawillems 2016-03-27 23:45:41 +02:00
parent d71a7e7d9a
commit a666ca7d3c
3 changed files with 45 additions and 24 deletions

View file

@ -8,9 +8,11 @@
layout (local_size_x =16, local_size_y = 16) in; layout (local_size_x =16, local_size_y = 16) in;
layout (binding = 0, rgba8) uniform image2D resultImage; layout (binding = 0, rgba8) uniform image2D resultImage;
#define EPSILON 0.0001
#define MAXLEN 1000.0 #define MAXLEN 1000.0
#define PLANEID 1 #define PLANEID 1
#define SPHERECOUNT 3 #define SPHERECOUNT 3
#define SHADOW 0.5
struct Camera { struct Camera {
vec3 pos; vec3 pos;
@ -97,13 +99,6 @@ int intersect(in vec3 rayO, in vec3 rayD, out float resT)
int id = -1; int id = -1;
resT = MAXLEN; resT = MAXLEN;
float tplane = planeIntersect(rayO, rayD);
if ((tplane > 0.0) && (tplane < resT))
{
id = PLANEID;
resT = tplane;
}
for (int i = 0; i < SPHERECOUNT; i++) for (int i = 0; i < SPHERECOUNT; i++)
{ {
float tSphere = sphereIntersect(rayO, rayD, spheres[i]); float tSphere = sphereIntersect(rayO, rayD, spheres[i]);
@ -115,17 +110,38 @@ int intersect(in vec3 rayO, in vec3 rayD, out float resT)
} }
} }
float tplane = planeIntersect(rayO, rayD);
if ((tplane > 0.0) && (tplane < resT))
{
id = PLANEID;
resT = tplane;
}
return id; return id;
} }
float calcShadow(in vec3 rayO, in vec3 rayD, in int id)
{
for (int i = 0; i < SPHERECOUNT; i++)
{
float tSphere = sphereIntersect(rayO, rayD, spheres[i]);
if (tSphere > EPSILON)
{
return SHADOW;
}
}
return 1.0;
}
vec3 fog(in float t, in vec3 color) vec3 fog(in float t, in vec3 color)
{ {
return mix(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/10.0, 0.0, 1.0)); return mix(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0));
} }
void main() void main()
{ {
// Scene setup // Scene setup
// todo : from ubo
spheres[0].id = 2; spheres[0].id = 2;
spheres[0].pos = vec3(-2.25, 1.0, 0.0); spheres[0].pos = vec3(-2.25, 1.0, 0.0);
spheres[0].r = 1.0; spheres[0].r = 1.0;
@ -133,15 +149,15 @@ void main()
spheres[0].material.specular = vec3(1.0, 1.0, 1.0); spheres[0].material.specular = vec3(1.0, 1.0, 1.0);
spheres[1].id = 3; spheres[1].id = 3;
spheres[1].pos = vec3(2.25, 1.0, 0.0); spheres[1].pos = vec3(0.0, 2.5, 0.0);
spheres[1].r = 1.0; spheres[1].r = 1.0;
spheres[1].material.diffuse = vec3(0.0, 1.0, 0.0); spheres[1].material.diffuse = vec3(0.0, 0.0, 1.0);
spheres[1].material.specular = vec3(1.0, 1.0, 1.0); spheres[1].material.specular = vec3(1.0, 1.0, 1.0);
spheres[2].id = 4; spheres[2].id = 4;
spheres[2].pos = vec3(0.0, 1.0, 0.0); spheres[2].pos = vec3(2.25, 1.0, 0.0);
spheres[2].r = 1.0; spheres[2].r = 1.0;
spheres[2].material.diffuse = vec3(0.0, 0.0, 1.0); spheres[2].material.diffuse = vec3(0.0, 1.0, 0.0);
spheres[2].material.specular = vec3(1.0, 1.0, 1.0); spheres[2].material.specular = vec3(1.0, 1.0, 1.0);
ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy); ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy);
@ -157,11 +173,12 @@ void main()
vec3 color = vec3(0.0); vec3 color = vec3(0.0);
vec3 pos = rayO + t * rayD;
vec3 lightVec = normalize(ubo.lightPos - pos);
if (objectID == PLANEID) if (objectID == PLANEID)
{ {
vec3 pos = rayO + t * rayD;
vec3 normal = planeNormal(pos); vec3 normal = planeNormal(pos);
vec3 lightVec = normalize(ubo.lightPos - pos);
float diffuse = clamp(dot(normal, lightVec), 0.0, 1.0); float diffuse = clamp(dot(normal, lightVec), 0.0, 1.0);
color = vec3(1.0, 1.0, 1.0) * diffuse; color = vec3(1.0, 1.0, 1.0) * diffuse;
} }
@ -171,8 +188,6 @@ void main()
{ {
if (objectID == spheres[i].id) if (objectID == spheres[i].id)
{ {
vec3 pos = rayO + t * rayD;
vec3 lightVec = normalize(ubo.lightPos - pos);
vec3 normal = sphereNormal(pos, spheres[i]); vec3 normal = sphereNormal(pos, spheres[i]);
float diffuse = lightDiffuse(normal, lightVec); float diffuse = lightDiffuse(normal, lightVec);
float specular = lightSpecular(normal, lightVec); float specular = lightSpecular(normal, lightVec);
@ -181,6 +196,10 @@ void main()
} }
} }
// Shadows
color *= calcShadow(pos, lightVec, objectID);
// Fog
color = fog(t, color); color = fog(t, color);
imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(color, 0.0)); imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(color, 0.0));

View file

@ -54,7 +54,7 @@ public:
float aspectRatio; float aspectRatio;
glm::vec4 fogColor = glm::vec4(0.025f, 0.025f, 0.025f, 0.0f); glm::vec4 fogColor = glm::vec4(0.025f, 0.025f, 0.025f, 0.0f);
struct { struct {
glm::vec3 pos = glm::vec3(0.0f, 1.0f, 4.0f); glm::vec3 pos = glm::vec3(0.0f, 1.5f, 4.0f);
glm::vec3 lookat = glm::vec3(0.0f, 0.5f, 0.0f); glm::vec3 lookat = glm::vec3(0.0f, 0.5f, 0.0f);
float fov = 10.0f; float fov = 10.0f;
} camera; } camera;
@ -84,6 +84,7 @@ public:
title = "Vulkan Example - Compute shader ray tracing"; title = "Vulkan Example - Compute shader ray tracing";
uboCompute.aspectRatio = (float)width / (float)height; uboCompute.aspectRatio = (float)width / (float)height;
paused = true; paused = true;
timerSpeed *= 0.5f;
} }
~VulkanExample() ~VulkanExample()
@ -656,9 +657,10 @@ public:
void updateUniformBuffers() void updateUniformBuffers()
{ {
uboCompute.lightPos.x = 0.0f; uboCompute.lightPos.x = 0.0f + sin(glm::radians(timer * 360.0f)) * 2.0f;
uboCompute.lightPos.y = 1.0f; uboCompute.lightPos.y = 5.0f;
uboCompute.lightPos.z = 1.5f; uboCompute.lightPos.z = 1.0f;
uboCompute.lightPos.z = 0.0f + cos(glm::radians(timer * 360.0f)) * 2.0f;
uint8_t *pData; uint8_t *pData;
vkTools::checkResult(vkMapMemory(device, uniformDataCompute.memory, 0, sizeof(uboCompute), 0, (void **)&pData)); vkTools::checkResult(vkMapMemory(device, uniformDataCompute.memory, 0, sizeof(uboCompute), 0, (void **)&pData));
memcpy(pData, &uboCompute, sizeof(uboCompute)); memcpy(pData, &uboCompute, sizeof(uboCompute));