diff --git a/README.md b/README.md index 72a9cf0..49a3dbb 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ graph TD - [x] Camera - [ ] Lighting - [x] Colors - - [ ] Basic Lighting + - [x] Basic Lighting - [ ] Materials - [ ] Lighting maps - [ ] Light casters diff --git a/data_type/modules/data_type.ixx b/data_type/modules/data_type.ixx index 5b4948e..01dd98a 100644 --- a/data_type/modules/data_type.ixx +++ b/data_type/modules/data_type.ixx @@ -66,6 +66,7 @@ export namespace sopho struct FragmentReflection { std::uint32_t sampler_count{}; + std::uint32_t uniform_count{}; }; } // namespace sopho diff --git a/glsl_reflector/modules/glsl_reflector.ixx b/glsl_reflector/modules/glsl_reflector.ixx index 5d5f5ab..07fc893 100644 --- a/glsl_reflector/modules/glsl_reflector.ixx +++ b/glsl_reflector/modules/glsl_reflector.ixx @@ -67,6 +67,7 @@ namespace sopho } program.buildReflection(); auto count = program.getNumPipeInputs(); + std::map pipes{}; for (auto i = 0; i < count; i++) { const auto& var = program.getPipeInput(i); @@ -77,10 +78,15 @@ namespace sopho std::string name = var.name.c_str(); auto vector = type->getVectorSize(); std::cout << name << vector << std::endl; - result.inputs.emplace_back(VertexInfo{.location = var.layoutLocation(), - .name = var.name, - .basic_type = to_basic_type(type->getBasicType()), - .vector_size = type->getVectorSize()}); + pipes.emplace(var.layoutLocation(), + VertexInfo{.location = var.layoutLocation(), + .name = var.name, + .basic_type = to_basic_type(type->getBasicType()), + .vector_size = type->getVectorSize()}); + } + for (const auto& vertex_info : pipes) + { + result.inputs.emplace_back(vertex_info.second); } count = program.getNumUniformVariables(); for (auto i = 0; i < count; i++) @@ -133,6 +139,10 @@ namespace sopho { result.sampler_count++; } + else + { + result.uniform_count++; + } } return result; } diff --git a/main.cpp b/main.cpp index ce687e3..a64146d 100644 --- a/main.cpp +++ b/main.cpp @@ -36,7 +36,9 @@ import logos; struct VertexType { - float x{}, y{}, z{}, u{}, v{}; + float x{}, y{}, z{}; + float nx{}, ny{}, nz{}; + float u{}, v{}; }; /** @@ -97,30 +99,44 @@ class UserApp : public sopho::App int win_w = 0, win_h = 0; + // see: https://wiki.libsdl.org/SDL3/SDL_CreateGPUShader for uniform layout std::string vertex_source = R"WSQ(#version 460 layout (location = 0) in vec3 a_position; -layout (location = 1) in vec2 a_uv; -layout (location = 0) out vec2 v_uv; +layout (location = 1) in vec3 a_normal; +layout (location = 2) in vec2 a_uv; +layout (location = 0) out vec3 v_normal; +layout (location = 1) out vec3 v_pos; +layout (location = 2) out vec2 v_uv; layout(std140, set = 1, binding = 0) uniform Camera { + mat4 uModel; mat4 uView; + mat4 uProjection; }; void main() { - gl_Position = uView * vec4(a_position, 1.0f); - v_uv = a_uv; + gl_Position = uProjection * uView * uModel * vec4(a_position, 1.0f); + v_normal = normalize(mat3(transpose(inverse(uModel))) * a_normal); + v_pos = vec3(uModel * vec4(a_position, 1.0)); + v_uv = a_uv; })WSQ"; std::string fragment_source = R"WSQ(#version 460 -layout (location = 0) in vec2 v_uv; +layout (location = 0) in vec3 v_normal; +layout (location = 1) in vec3 v_pos; +layout (location = 2) in vec2 v_uv; layout (location = 0) out vec4 FragColor; +layout(std140, set = 3, binding = 0) uniform Params { + vec3 lightPos; + vec3 viewPos; +}; layout(set = 2, binding = 0) uniform sampler2D uTexture; void main() @@ -128,12 +144,22 @@ void main() FragColor = texture(uTexture, v_uv); if (FragColor.a <= 0.001) discard; + vec3 lightDir = normalize(lightPos - v_pos); + float diff = max(dot(v_normal, lightDir), 0.0); + float specularStrength = 0.5; + vec3 viewDir = normalize(viewPos - v_pos); + vec3 reflectDir = reflect(-lightDir, v_normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); + float specular = specularStrength * spec; + FragColor.rgb *= 0.1 + diff + specular; })WSQ"; std::string fragment_source2 = R"WSQ(#version 460 -layout (location = 0) in vec2 v_uv; +layout (location = 0) in vec3 v_normal; +layout (location = 1) in vec3 v_pos; +layout (location = 2) in vec2 v_uv; layout (location = 0) out vec4 FragColor; void main() @@ -186,17 +212,66 @@ void main() } std::vector vertices{ - {0.5, 0.5, 0.5, 0., 0.}, {-0.5, 0.5, 0.5, 1., 0.}, {0.5, -0.5, 0.5, 0., 1.}, {-0.5, -0.5, 0.5, 1., 1.}, - {0.5, 0.5, -0.5, 1., 1.}, {-0.5, 0.5, -0.5, 0., 1.}, {0.5, -0.5, -0.5, 1., 0.}, {-0.5, -0.5, -0.5, 0., 0.}, + // +Z (front) 2 triangles + {.x = 0.5f, .y = 0.5f, .z = 0.5f, .nx = 0, .ny = 0, .nz = 1, .u = 0, .v = 0}, + {.x = -0.5f, .y = 0.5f, .z = 0.5f, .nx = 0, .ny = 0, .nz = 1, .u = 1, .v = 0}, + {.x = 0.5f, .y = -0.5f, .z = 0.5f, .nx = 0, .ny = 0, .nz = 1, .u = 0, .v = 1}, + {.x = -0.5f, .y = 0.5f, .z = 0.5f, .nx = 0, .ny = 0, .nz = 1, .u = 1, .v = 0}, + {.x = -0.5f, .y = -0.5f, .z = 0.5f, .nx = 0, .ny = 0, .nz = 1, .u = 1, .v = 1}, + {.x = 0.5f, .y = -0.5f, .z = 0.5f, .nx = 0, .ny = 0, .nz = 1, .u = 0, .v = 1}, + + // -Z (back) + {.x = -0.5f, .y = 0.5f, .z = -0.5f, .nx = 0, .ny = 0, .nz = -1, .u = 0, .v = 0}, + {.x = 0.5f, .y = 0.5f, .z = -0.5f, .nx = 0, .ny = 0, .nz = -1, .u = 1, .v = 0}, + {.x = -0.5f, .y = -0.5f, .z = -0.5f, .nx = 0, .ny = 0, .nz = -1, .u = 0, .v = 1}, + {.x = 0.5f, .y = 0.5f, .z = -0.5f, .nx = 0, .ny = 0, .nz = -1, .u = 1, .v = 0}, + {.x = 0.5f, .y = -0.5f, .z = -0.5f, .nx = 0, .ny = 0, .nz = -1, .u = 1, .v = 1}, + {.x = -0.5f, .y = -0.5f, .z = -0.5f, .nx = 0, .ny = 0, .nz = -1, .u = 0, .v = 1}, + + // +X (right) + {.x = 0.5f, .y = 0.5f, .z = -0.5f, .nx = 1, .ny = 0, .nz = 0, .u = 0, .v = 0}, + {.x = 0.5f, .y = 0.5f, .z = 0.5f, .nx = 1, .ny = 0, .nz = 0, .u = 1, .v = 0}, + {.x = 0.5f, .y = -0.5f, .z = -0.5f, .nx = 1, .ny = 0, .nz = 0, .u = 0, .v = 1}, + {.x = 0.5f, .y = 0.5f, .z = 0.5f, .nx = 1, .ny = 0, .nz = 0, .u = 1, .v = 0}, + {.x = 0.5f, .y = -0.5f, .z = 0.5f, .nx = 1, .ny = 0, .nz = 0, .u = 1, .v = 1}, + {.x = 0.5f, .y = -0.5f, .z = -0.5f, .nx = 1, .ny = 0, .nz = 0, .u = 0, .v = 1}, + + // -X (left) + {.x = -0.5f, .y = 0.5f, .z = 0.5f, .nx = -1, .ny = 0, .nz = 0, .u = 0, .v = 0}, + {.x = -0.5f, .y = 0.5f, .z = -0.5f, .nx = -1, .ny = 0, .nz = 0, .u = 1, .v = 0}, + {.x = -0.5f, .y = -0.5f, .z = 0.5f, .nx = -1, .ny = 0, .nz = 0, .u = 0, .v = 1}, + {.x = -0.5f, .y = 0.5f, .z = -0.5f, .nx = -1, .ny = 0, .nz = 0, .u = 1, .v = 0}, + {.x = -0.5f, .y = -0.5f, .z = -0.5f, .nx = -1, .ny = 0, .nz = 0, .u = 1, .v = 1}, + {.x = -0.5f, .y = -0.5f, .z = 0.5f, .nx = -1, .ny = 0, .nz = 0, .u = 0, .v = 1}, + + // +Y (top) + {.x = 0.5f, .y = 0.5f, .z = -0.5f, .nx = 0, .ny = 1, .nz = 0, .u = 0, .v = 0}, + {.x = -0.5f, .y = 0.5f, .z = -0.5f, .nx = 0, .ny = 1, .nz = 0, .u = 1, .v = 0}, + {.x = 0.5f, .y = 0.5f, .z = 0.5f, .nx = 0, .ny = 1, .nz = 0, .u = 0, .v = 1}, + {.x = -0.5f, .y = 0.5f, .z = -0.5f, .nx = 0, .ny = 1, .nz = 0, .u = 1, .v = 0}, + {.x = -0.5f, .y = 0.5f, .z = 0.5f, .nx = 0, .ny = 1, .nz = 0, .u = 1, .v = 1}, + {.x = 0.5f, .y = 0.5f, .z = 0.5f, .nx = 0, .ny = 1, .nz = 0, .u = 0, .v = 1}, + + // -Y (bottom) + {.x = 0.5f, .y = -0.5f, .z = 0.5f, .nx = 0, .ny = -1, .nz = 0, .u = 0, .v = 0}, + {.x = -0.5f, .y = -0.5f, .z = 0.5f, .nx = 0, .ny = -1, .nz = 0, .u = 1, .v = 0}, + {.x = 0.5f, .y = -0.5f, .z = -0.5f, .nx = 0, .ny = -1, .nz = 0, .u = 0, .v = 1}, + {.x = -0.5f, .y = -0.5f, .z = 0.5f, .nx = 0, .ny = -1, .nz = 0, .u = 1, .v = 0}, + {.x = -0.5f, .y = -0.5f, .z = -0.5f, .nx = 0, .ny = -1, .nz = 0, .u = 1, .v = 1}, + {.x = 0.5f, .y = -0.5f, .z = -0.5f, .nx = 0, .ny = -1, .nz = 0, .u = 0, .v = 1}, }; - std::vector indices{0, 1, 2, 1, 2, 3, 0, 1, 4, 1, 4, 5, 0, 2, 4, 2, 4, 6, - 2, 3, 6, 3, 6, 7, 1, 3, 5, 3, 5, 7, 4, 5, 6, 5, 6, 7}; + std::vector indices{}; + + for (int i = 0; i < 36; ++i) + { + indices.push_back(i); + } // 3. Create vertex buffer. auto render_data = sopho::RenderData::Builder{} .set_vertex_layout(pw_result.value().vertex_layout()) - .set_vertex_count(8) + .set_vertex_count(36) .set_index_count(36) .set_vertices(std::span(vertices)) .set_indices(std::span(indices)) @@ -581,18 +656,31 @@ void main() SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(command_buffer_raii.raw(), &colorTargetInfo, 1, &depthStencilTargetInfo); - - for (int i = 0; i < m_renderables.size(); i++) - { - auto renderable = m_renderables[i]; - auto camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * - sopho::rotation_x(-pitch) * sopho::rotation_y(yaw) * - sopho::translate(0 - location(0), 0.5 * i - location(1), -i - 5 - location(2)); - renderable->draw(sopho::RenderContext{.render_pass = renderPass, - .command_buffer = command_buffer_raii.raw(), - .camera_mat = camera_mat, - .texture_wrapper = i == 0 ? m_texture_wrapper : nullptr}); - } + auto renderable = m_renderables[0]; + std::array, 3> camera_mat{}; + // Model + camera_mat[0] = sopho::translate(0.0f, -4.f, -5.0f) * sopho::rotation_y(1.6) * sopho::scale(10); + // View + camera_mat[1] = sopho::rotation_x(-pitch) * sopho::rotation_y(yaw) * + sopho::translate(-location(0), -location(1), -location(2)); + // Projection` + camera_mat[2] = sopho::perspective(1, static_cast(width) / height, 0.1, 50); + renderable->draw( + sopho::RenderContext{.render_pass = renderPass, + .command_buffer = command_buffer_raii.raw(), + .camera_mat = camera_mat, + .pos = std::array{sopho::Mat{0.0f, 2.f, -6.0f}, location.resize<1, 4>()}, + .texture_wrapper = m_texture_wrapper}); + renderable = m_renderables[1]; + // Model + camera_mat[0] = sopho::translate(0.0f, 2.f, -6.0f); + // View + camera_mat[1] = sopho::rotation_x(-pitch) * sopho::rotation_y(yaw) * + sopho::translate(-location(0), -location(1), -location(2)); + // Projection + camera_mat[2] = sopho::perspective(1, static_cast(width) / height, 0.1, 50); + renderable->draw(sopho::RenderContext{ + .render_pass = renderPass, .command_buffer = command_buffer_raii.raw(), .camera_mat = camera_mat}); SDL_EndGPURenderPass(renderPass); diff --git a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx index 42ea672..145414e 100644 --- a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx @@ -3,6 +3,7 @@ // module; #include +#include #include #include export module sdl_wrapper:renderable; @@ -16,7 +17,8 @@ namespace sopho { SDL_GPURenderPass* render_pass{}; SDL_GPUCommandBuffer* command_buffer{}; - Mat camera_mat{}; + std::array, 3> camera_mat{}; + std::array, 2> pos{}; std::shared_ptr texture_wrapper{}; }; diff --git a/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp b/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp index b34b393..52a270f 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp @@ -236,7 +236,8 @@ namespace sopho std::vector code = spv_result_to_bytes(result); auto reflect_result = reflect_fragment(source); - auto shader_result = m_gpu->create_shader(code, SDL_GPU_SHADERSTAGE_FRAGMENT, 0, reflect_result.sampler_count); + auto shader_result = m_gpu->create_shader(code, SDL_GPU_SHADERSTAGE_FRAGMENT, reflect_result.uniform_count, + reflect_result.sampler_count); if (!shader_result) { diff --git a/sdl_wrapper/src/sdl_wrapper.renderable.cpp b/sdl_wrapper/src/sdl_wrapper.renderable.cpp index de3a1fb..93a7bec 100644 --- a/sdl_wrapper/src/sdl_wrapper.renderable.cpp +++ b/sdl_wrapper/src/sdl_wrapper.renderable.cpp @@ -3,6 +3,7 @@ // module; #include +#include #include #include module sdl_wrapper; @@ -21,7 +22,9 @@ namespace sopho } SDL_BindGPUGraphicsPipeline(render_contex.render_pass, procedural()->raw()); SDL_PushGPUVertexUniformData(render_contex.command_buffer, 0, render_contex.camera_mat.data(), - sizeof(Mat)); + sizeof(Mat) * 3); + SDL_PushGPUFragmentUniformData(render_contex.command_buffer, 0, render_contex.pos.data(), + sizeof(std::array, 2>)); SDL_BindGPUVertexBuffers(render_contex.render_pass, 0, data()->get_vertex_buffer_binding().data(), data()->get_vertex_buffer_binding().size());