Made small ray tracer with a sphere to test fragment shading and uniform buffers

This commit is contained in:
Conál 2024-01-28 10:01:39 -05:00
parent a76cbb46c3
commit 4012425d35
5 changed files with 70 additions and 4 deletions

View File

@ -51,7 +51,7 @@ add_dependencies(pleascach shaders)
if(UNIX)
add_custom_command(
TARGET shaders POST_BUILD
COMMAND cp -r
COMMAND cmake -E copy_directory
"$<TARGET_PROPERTY:pleascach,SOURCE_DIR>/assets"
"$<TARGET_PROPERTY:pleascach,BINARY_DIR>/assets")
else()

View File

@ -186,7 +186,7 @@ Renderer::Renderer(Window& win) : win(win) {
std::vector<Shader> shaders = {
{ dev, "assets/shaders/basic.vert.spv", vk::ShaderStageFlagBits::eVertex },
{ dev, "assets/shaders/basic.frag.spv", vk::ShaderStageFlagBits::eFragment },
{ dev, "assets/shaders/trace.frag.spv", vk::ShaderStageFlagBits::eFragment },
};
std::vector<vk::DescriptorSetLayoutBinding> bindings = {
@ -265,11 +265,14 @@ void Renderer::draw() {
command_buffer->bind(*vertex_buffer);
command_buffer->bind(pipeline->layout, pipeline->desc_set);
const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(swapchain->extent.width) / static_cast<float>(swapchain->extent.height), 0.01f, 50.0f);
auto sz = win.getDimensions();
const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(sz.width) / static_cast<float>(sz.height), 0.01f, 50.0f);
uniform_buffer->upload(UniformData{
//.mvp = p * glm::rotate(glm::mat4(1.0), glm::radians(static_cast<float>(frame)), glm::vec3(1.0, 1.0, 1.0)),
.time = static_cast<float>(frame),
.time = static_cast<float>(frame) * 0.0167f,
.aspect_ratio = static_cast<float>(sz.width)/static_cast<float>(sz.height),
});

View File

@ -12,6 +12,7 @@
struct UniformData {
glm::mat4 mvp;
float time;
float aspect_ratio;
};
struct UniformBuffer {

62
assets/shaders/trace.frag Normal file
View File

@ -0,0 +1,62 @@
#version 460 core
layout (location = 0) in vec2 texCoord;
layout (location = 0) out vec4 FragColor;
layout (set = 0, binding = 0) uniform Matrices {
mat4 mpv;
float time;
float aspect_ratio;
};
/* 4-float alignment in memory*/
struct Ray {
vec3 orig;
float min;
vec3 dir;
float max;
};
vec3 ray_color(vec3 ray) {
float a = 0.5 * (ray.y+1.0);
return vec3(1.0-a) + a*vec3(0.5, 0.7, 1.0);
}
/* returns float of where you hit, or -1.0 */
float sphere(vec3 center, float r, Ray ray) {
vec3 p = ray.orig-center;
float a = dot(ray.dir, ray.dir);
float half_b = dot(p, ray.dir);
float c = dot(p, p) - r*r;
float discr = half_b*half_b - a*c;
if(discr < 0.0)
return -1.0;
return -half_b-sqrt(discr)/a;
}
void main() {
vec2 pixel = texCoord*2.0-1.0;
Ray ray;
ray.orig = vec3(0.0);
ray.min = 0.1;
ray.max = 10000.0;
float fov = radians(90);
ray.dir = normalize(vec3(pixel.x * aspect_ratio, pixel.y, tan(fov/2.0)));
vec3 sphere_center = vec3(0.0, 0.0, 1.0);
float d = sphere(sphere_center, 0.5, ray);
if(d < 0.0) {
FragColor = vec4(0.0);
return;
}
vec3 n = normalize(ray.dir*d-sphere_center);
FragColor = vec4((n+vec3(1.0)) / 2.0, 1.0);
}

Binary file not shown.