This commit is contained in:
Jorijn van der Graaf 2025-06-10 22:47:47 +02:00
commit 6fe9c0f4c2
7 changed files with 262 additions and 13 deletions

View file

@ -40,3 +40,30 @@ void Camera::Update() {
projectionView = projection*view; projectionView = projection*view;
onUpdate.Invoke(); onUpdate.Invoke();
} }
Vector<float, 3> Camera::ToRay(uint32_t x, uint32_t y) {
// // Normalize the screen coordinates
// float mx = (2.0f * x) / sizeX - 1.0f;
// float my = 1.0f - (2.0f * y) / sizeY;
//
// // Construct Ray in Homogeneous Clip Space
// Vector<float, 3> rayOrigin = Vector<float, 3>(mx, my, 0.0f);
// Vector<float, 3> rayEnd = Vector<float, 3>(mx, my, 1.0f);
//
// // Transform Ray to View Space
// MatrixRowMajor<float, 4, 4, 1> invProjection = DirectX::XMMatrixInverse(NULL, projectionMatrix);
// Vector<float, 3> rayOriginView = DirectX::XMVector3TransformCoord(rayOrigin, invProjection);
// Vector<float, 3> rayEndView = DirectX::XMVector3TransformCoord(rayEnd, invProjection);
//
// // Transform Ray to World Space
// DirectX::XMMATRIX viewMatrix = GetViewMatrix(); // Assuming this returns the view matrix
// DirectX::XMMATRIX invView = DirectX::XMMatrixInverse(NULL, viewMatrix);
// Vector<float, 3> rayOriginWorld = DirectX::XMVector3TransformCoord(rayOriginView, invView);
// Vector<float, 3> rayEndWorld = DirectX::XMVector3TransformCoord(rayEndView, invView);
//
// // Compute Ray Direction
// DirectX::XMVECTOR rayDirWorld = DirectX::XMVector3Normalize(DirectX::XMVectorSubtract(rayEndWorld, rayOriginWorld));
//
// return rayDirWorld;
return Vector<float, 3>(0,0,0);
}

View file

@ -36,5 +36,7 @@ namespace Crafter {
Event<void> onUpdate; Event<void> onUpdate;
Camera(float fov, float aspectRatio, float near, float far); Camera(float fov, float aspectRatio, float near, float far);
void Update(); void Update();
Vector<float, 3> ToRay(uint32_t x, uint32_t y);
}; };
} }

View file

@ -0,0 +1,75 @@
/*
Crafter®.Graphics
Copyright (C) 2025 Catcrafts®
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
module;
#include <cstdint>
#include <vulkan/vulkan.h>
#include <cstring>
#include <iostream>
#include <cmath>
#include "VulkanInitializers.hpp"
export module Crafter.Graphics:VoxelShader;
import :Mesh;
import :Camera;
import :VulkanPipeline;
import :DescriptorSet;
import Crafter.Math;
namespace Crafter {
export struct VoxelShaderData {
MatrixRowMajor<float, 4, 4, 1> mvp;
uint32_t sizeX;
uint32_t sizeY;
uint32_t sizeZ;
};
export template <typename VoxelType>
class VoxelShader {
public:
MatrixRowMajor<float, 4, 4, 1> transform;
Camera* camera;
Buffer<VoxelType> grid;
Buffer<VoxelShaderData> data;
std::uint32_t threadCount;
EventListener<void> cameraUpdate;
VoxelShader(uint32_t sizeX, uint32_t sizeY, uint sizeZ, Camera* camera) : threadCount((sizeX*sizeY*sizeZ)/16), data(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), grid(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeX*sizeY*sizeZ) ,camera(camera), cameraUpdate(
&camera->onUpdate, [this](){
Update();
}
) {
transform = MatrixRowMajor<float, 4, 4, 1>::Identity();
data.value->sizeX = sizeX;
data.value->sizeY = sizeY;
data.value->sizeZ = sizeZ;
}
void WriteDescriptors(VkDescriptorSet set) {
VkWriteDescriptorSet write[2] = {
vks::initializers::writeDescriptorSet(set, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &data.descriptor),
vks::initializers::writeDescriptorSet(set, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, &grid.descriptor),
};
vkUpdateDescriptorSets(VulkanDevice::device, 2, &write[0], 0, nullptr);
}
void Update() {
data.value->mvp = camera->projectionView*transform;
}
};
}

View file

@ -31,6 +31,7 @@ export import :VulkanPipeline;
export import :VulkanShader; export import :VulkanShader;
export import :Camera; export import :Camera;
export import :VulkanBuffer; export import :VulkanBuffer;
export import :VoxelShader;
export import :Mesh; export import :Mesh;
export import :MeshShader; export import :MeshShader;
export import :VulkanTexture; export import :VulkanTexture;

View file

@ -0,0 +1,144 @@
/*
* Crafter®.Graphics
* Copyright (C) 2025 Catcrafts®
* Catcrafts.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#version 450
#extension GL_EXT_mesh_shader : require
layout (binding = 0) uniform UBO
{
mat4 modelProjectionView;
uint sizeX;
uint sizeY;
uint sizeZ;
} ubo;
struct VoxelType
{
uint type;
};
layout (binding = 1) buffer VOXELS
{
VoxelType voxel[];
} voxels;
/*
layout (location = 0) out PerVertexData
{
vec4 color;
} outVert[];
*/
shared uint writeCounter;
layout(local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
layout(triangles, max_vertices = 128, max_primitives = 192) out;
void main()
{
//if (gl_LocalInvocationIndex == 0) {
//writeCounter = 0;
//}
//barrier();
//uint type = voxels.voxel[gl_GlobalInvocationID.x].type;
//if(type != 0) {
uint old = atomicAdd(writeCounter, 1);
uint z = gl_GlobalInvocationID.x / (ubo.sizeX * ubo.sizeY);
uint y = (gl_GlobalInvocationID.x % (ubo.sizeX * ubo.sizeY)) / ubo.sizeX;
uint x = gl_GlobalInvocationID.x % ubo.sizeX;
float zF = float(z);
float yF = float(y);
float xF = float(x);
uint oldVertexOffset = old*8;
gl_MeshVerticesEXT[oldVertexOffset + 0].gl_Position = vec4(xF - 0.5, yF - 0.5, zF - 0.5, 1.0); // Vertex 0
gl_MeshVerticesEXT[oldVertexOffset + 1].gl_Position = vec4(xF + 0.5, yF - 0.5, zF - 0.5, 1.0); // Vertex 1
gl_MeshVerticesEXT[oldVertexOffset + 2].gl_Position = vec4(xF + 0.5, yF + 0.5, zF - 0.5, 1.0); // Vertex 2
gl_MeshVerticesEXT[oldVertexOffset + 3].gl_Position = vec4(xF - 0.5, yF + 0.5, zF - 0.5, 1.0); // Vertex 3
gl_MeshVerticesEXT[oldVertexOffset + 4].gl_Position = vec4(xF - 0.5, yF - 0.5, zF + 0.5, 1.0); // Vertex 4
gl_MeshVerticesEXT[oldVertexOffset + 5].gl_Position = vec4(xF + 0.5, yF - 0.5, zF + 0.5, 1.0); // Vertex 5
gl_MeshVerticesEXT[oldVertexOffset + 6].gl_Position = vec4(xF + 0.5, yF + 0.5, zF + 0.5, 1.0); // Vertex 6
gl_MeshVerticesEXT[oldVertexOffset + 7].gl_Position = vec4(xF - 0.5, yF + 0.5, zF + 0.5, 1.0); // Vertex 7
uint oldPrimOffset = old*12;
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 0] = uvec3(oldVertexOffset + 0, oldVertexOffset + 1, oldVertexOffset + 2);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 1] = uvec3(oldVertexOffset + 2, oldVertexOffset + 3, oldVertexOffset + 0);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 2] = uvec3(oldVertexOffset + 4, oldVertexOffset + 6, oldVertexOffset + 5);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 3] = uvec3(oldVertexOffset + 6, oldVertexOffset + 4, oldVertexOffset + 7);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 4] = uvec3(oldVertexOffset + 0, oldVertexOffset + 5, oldVertexOffset + 1);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 5] = uvec3(oldVertexOffset + 0, oldVertexOffset + 4, oldVertexOffset + 5);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 6] = uvec3(oldVertexOffset + 3, oldVertexOffset + 2, oldVertexOffset + 6);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 7] = uvec3(oldVertexOffset + 6, oldVertexOffset + 7, oldVertexOffset + 3);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 8] = uvec3(oldVertexOffset + 0, oldVertexOffset + 3, oldVertexOffset + 7);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 9] = uvec3(oldVertexOffset + 7, oldVertexOffset + 4, oldVertexOffset + 0);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 10] = uvec3(oldVertexOffset + 1, oldVertexOffset + 2, oldVertexOffset + 6);
gl_PrimitiveTriangleIndicesEXT[oldPrimOffset + 11] = uvec3(oldVertexOffset + 6, oldVertexOffset + 5, oldVertexOffset + 1);
//}
//barrier();
//SetMeshOutputsEXT(writeCounter*8, writeCounter*12);
SetMeshOutputsEXT(128, 192);
}
/**
int z = gl_GlobalInvocationID.x / (ubo.sizeX * ubo.sizeY);
int y = (gl_GlobalInvocationID.x % (ubo.sizeX * ubo.sizeY)) / ubo.sizeX;
int x = gl_GlobalInvocationID.x % ubo.sizeX;
// Top (y+1) if within bounds
if (y < ubo.sizeY - 1 && vertex.pos[gl_GlobalInvocationID.x + ubo.sizeX]) {
}
// Bottom (y-1) if within bounds
if (y > 0 && vertex.pos[gl_GlobalInvocationID.x - ubo.sizeX]) {
}
// Left (x-1) if within bounds
if (x > 0 && vertex.pos[gl_GlobalInvocationID.x - 1]) {
}
// Right (x+1) if within bounds
if (x < ubo.sizeX - 1 && vertex.pos[gl_GlobalInvocationID.x + 1]) {
}
// Front (z+1) if within bounds
if (z < ubo.sizeZ - 1 && vertex.pos[gl_GlobalInvocationID.x + ubo.sizeX * ubo.sizeY]) {
}
// Back (z-1) if within bounds
if (z > 0 && vertex.pos[gl_GlobalInvocationID.x - ubo.sizeX * ubo.sizeY]) {
}
**/

View file

@ -31,8 +31,8 @@ import Crafter.Event;
import Crafter.Math; import Crafter.Math;
using namespace Crafter; using namespace Crafter;
typedef VulkanShader<"MeshShaderHeightmapRGBA.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 2, {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}}}> MeshVulkanShader; typedef VulkanShader<"MeshShaderMixedVoxelGrid.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 2, {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}}}> MeshVulkanShader;
typedef VulkanShader<"FragmentShaderVertexColor.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader; typedef VulkanShader<"FragmentShaderSolidWhite.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader;
typedef VulkanPipeline<MeshVulkanShader, FragmentShader> Pipeline; typedef VulkanPipeline<MeshVulkanShader, FragmentShader> Pipeline;
int main() { int main() {
@ -44,21 +44,16 @@ int main() {
WindowWaylandVulkan window("Crafter.Graphics", 1280, 720); WindowWaylandVulkan window("Crafter.Graphics", 1280, 720);
Camera camera(1.57079633, 1280.0f / 720.0f, 0.01, 512); Camera camera(1.57079633, 1280.0f / 720.0f, 0.01, 512);
camera.view = MatrixRowMajor<float, 4, 4, 1>::Translation(0, 2, -10); camera.view = MatrixRowMajor<float, 4, 4, 1>::Translation(0, 0, 10);
camera.Update(); camera.Update();
VkCommandBuffer cmd = window.StartInit(); VkCommandBuffer cmd = window.StartInit();
DescriptorSet<MeshVulkanShader, FragmentShader> descriptors; DescriptorSet<MeshVulkanShader, FragmentShader> descriptors;
HeightmapShader<HeightRGBA> meshShader(4, 2, 1, &camera); VoxelShader<uint> meshShader(1, 4, 4, &camera);
for(uint32_t i = 0; i < 1*1*4*64; i++) { for(uint32_t i = 0; i < 16; i++) {
meshShader.heights.value[i].height = -0.5; meshShader.grid.value[i] = 1;
meshShader.heights.value[i].r = 255;
meshShader.heights.value[i].g = 255;
meshShader.heights.value[i].b = 255;
meshShader.heights.value[i].a = 255;
} }
meshShader.WriteDescriptors(descriptors.set[0]); meshShader.WriteDescriptors(descriptors.set[0]);
meshShader.Update(); meshShader.Update();

View file

@ -6,7 +6,7 @@
"standard": "c++26", "standard": "c++26",
"source_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics-UiElement", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-WindowWaylandVulkan", "VulkanBuffer", "VulkanTools", "Crafter.Graphics-Camera"], "source_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics-UiElement", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-WindowWaylandVulkan", "VulkanBuffer", "VulkanTools", "Crafter.Graphics-Camera"],
"c_files": ["wayland-xdg-decoration-unstable-v1-client-protocol", "xdg-shell-protocol", "shm"], "c_files": ["wayland-xdg-decoration-unstable-v1-client-protocol", "xdg-shell-protocol", "shm"],
"module_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics", "Crafter.Graphics-UiElement", "Crafter.Graphics-Types", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-VulkanPipeline", "Crafter.Graphics-VulkanShader", "Crafter.Graphics-WindowWaylandVulkan", "Crafter.Graphics-Camera", "Crafter.Graphics-VulkanBuffer", "Crafter.Graphics-Mesh", "Crafter.Graphics-MeshShader", "Crafter.Graphics-HeightmapShader", "Crafter.Graphics-VulkanTexture", "Crafter.Graphics-TextureShader", "Crafter.Graphics-DescriptorSet"], "module_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics", "Crafter.Graphics-UiElement", "Crafter.Graphics-Types", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-VulkanPipeline", "Crafter.Graphics-VulkanShader", "Crafter.Graphics-WindowWaylandVulkan", "Crafter.Graphics-Camera", "Crafter.Graphics-VulkanBuffer", "Crafter.Graphics-Mesh", "Crafter.Graphics-MeshShader", "Crafter.Graphics-HeightmapShader","Crafter.Graphics-VoxelShader", "Crafter.Graphics-VulkanTexture", "Crafter.Graphics-TextureShader", "Crafter.Graphics-DescriptorSet"],
"build_dir": "build", "build_dir": "build",
"output_dir": "bin", "output_dir": "bin",
"type":"library", "type":"library",
@ -33,6 +33,11 @@
"type":13, "type":13,
"entrypoint":"main" "entrypoint":"main"
}, },
{
"path":"MeshShaderMixedVoxelGrid.glsl",
"type":13,
"entrypoint":"main"
},
{ {
"path":"FragmentShaderSolidWhite.glsl", "path":"FragmentShaderSolidWhite.glsl",
"type":4, "type":4,