comparison tests/test_gltf.nim @ 1332:df3c075e5dea

did: formatting
author sam <sam@basx.dev>
date Thu, 22 Aug 2024 18:31:59 +0700
parents 3ba2c180e52c
children
comparison
equal deleted inserted replaced
1331:1abdd42f5cfe 1332:df3c075e5dea
11 11
12 type 12 type
13 ObjectData = object 13 ObjectData = object
14 transform: Mat4 14 transform: Mat4
15 materialId: int32 15 materialId: int32
16
16 Camera = object 17 Camera = object
17 view: Mat4 18 view: Mat4
18 normal: Mat4 19 normal: Mat4
19 projection: Mat4 20 projection: Mat4
21
20 Material = object 22 Material = object
21 color: Vec4f = vec4(1, 1, 1, 1) 23 color: Vec4f = vec4(1, 1, 1, 1)
22 # colorTexture: int32 = -1 24 # colorTexture: int32 = -1
23 metallic: float32 = 0 25 metallic: float32 = 0
24 roughness: float32 = 0 26 roughness: float32 = 0
25 # metallicRoughnessTexture: int32 = -1 27 # metallicRoughnessTexture: int32 = -1
26 # normalTexture: int32 = -1 28 # normalTexture: int32 = -1
27 # occlusionTexture: int32 = -1 29 # occlusionTexture: int32 = -1
28 emissive: Vec4f = vec4(0, 0, 0, 0) 30 emissive: Vec4f = vec4(0, 0, 0, 0) # emissiveTexture: int32 = -1
29 # emissiveTexture: int32 = -1 31
30 MainDescriptors = object 32 MainDescriptors = object
31 materials: array[50, GPUValue[Material, UniformBuffer]] 33 materials: array[50, GPUValue[Material, UniformBuffer]]
32 camera: GPUValue[Camera, UniformBufferMapped] 34 camera: GPUValue[Camera, UniformBufferMapped]
35
33 Shader = object 36 Shader = object
34 objectData {.PushConstant.}: ObjectData 37 objectData {.PushConstant.}: ObjectData
35 position {.VertexAttribute.}: Vec3f 38 position {.VertexAttribute.}: Vec3f
36 color {.VertexAttribute.}: Vec4f 39 color {.VertexAttribute.}: Vec4f
37 normal {.VertexAttribute.}: Vec3f 40 normal {.VertexAttribute.}: Vec3f
39 fragmentColor {.Pass.}: Vec4f 42 fragmentColor {.Pass.}: Vec4f
40 fragmentNormal {.Pass.}: Vec3f 43 fragmentNormal {.Pass.}: Vec3f
41 outColor {.ShaderOutput.}: Vec4f 44 outColor {.ShaderOutput.}: Vec4f
42 descriptors {.DescriptorSet: 0.}: MainDescriptors 45 descriptors {.DescriptorSet: 0.}: MainDescriptors
43 # code 46 # code
44 vertexCode: string = """ 47 vertexCode: string =
48 """
45 void main() { 49 void main() {
46 mat4 modelView = objectData.transform * camera.view; 50 mat4 modelView = objectData.transform * camera.view;
47 mat3 normalMat = mat3(transpose(inverse(objectData.transform))); 51 mat3 normalMat = mat3(transpose(inverse(objectData.transform)));
48 vec4 posTransformed = vec4(position, 1) * modelView; 52 vec4 posTransformed = vec4(position, 1) * modelView;
49 fragmentPosition = posTransformed.xyz / posTransformed.w; 53 fragmentPosition = posTransformed.xyz / posTransformed.w;
50 fragmentColor = color * materials[objectData.materialId].color; 54 fragmentColor = color * materials[objectData.materialId].color;
51 fragmentNormal = normal * normalMat; 55 fragmentNormal = normal * normalMat;
52 gl_Position = vec4(position, 1) * (modelView * camera.projection); 56 gl_Position = vec4(position, 1) * (modelView * camera.projection);
53 }""" 57 }"""
54 fragmentCode: string = """ 58 fragmentCode: string =
59 """
55 const vec3 lightPosition = vec3(7, 9, -12); 60 const vec3 lightPosition = vec3(7, 9, -12);
56 const float shininess = 40; 61 const float shininess = 40;
57 const vec3 ambientColor = vec3(0, 0, 0); 62 const vec3 ambientColor = vec3(0, 0, 0);
58 const vec3 lightColor = vec3(1, 1, 1); 63 const vec3 lightColor = vec3(1, 1, 1);
59 // const vec3 specColor = vec3(1, 1, 1); 64 // const vec3 specColor = vec3(1, 1, 1);
80 vec3 specColor = diffuseColor; 85 vec3 specColor = diffuseColor;
81 vec3 color = ambientColor + diffuseColor * lambertian * lightColor * lightPower / dist + specColor * specular * lightColor * lightPower / dist; 86 vec3 color = ambientColor + diffuseColor * lambertian * lightColor * lightPower / dist + specColor * specular * lightColor * lightPower / dist;
82 87
83 outColor = vec4(color, fragmentColor.a); 88 outColor = vec4(color, fragmentColor.a);
84 }""" 89 }"""
90
85 Mesh = object 91 Mesh = object
86 position: GPUArray[Vec3f, VertexBuffer] 92 position: GPUArray[Vec3f, VertexBuffer]
87 color: GPUArray[Vec4f, VertexBuffer] 93 color: GPUArray[Vec4f, VertexBuffer]
88 normal: GPUArray[Vec3f, VertexBuffer] 94 normal: GPUArray[Vec3f, VertexBuffer]
89 indices: GPUArray[uint32, IndexBuffer] 95 indices: GPUArray[uint32, IndexBuffer]
107 metallicRoughnessTexture: "metallicRoughnessTexture", 113 metallicRoughnessTexture: "metallicRoughnessTexture",
108 normalTexture: "normalTexture", 114 normalTexture: "normalTexture",
109 occlusionTexture: "occlusionTexture", 115 occlusionTexture: "occlusionTexture",
110 emissiveTexture: "emissiveTexture", 116 emissiveTexture: "emissiveTexture",
111 emissiveFactor: "emissive", 117 emissiveFactor: "emissive",
112 ) 118 ),
113 ) 119 )
114 var descriptors = asDescriptorSetData( 120 var descriptors = asDescriptorSetData(
115 MainDescriptors( 121 MainDescriptors(
116 camera: asGPUValue(Camera( 122 camera: asGPUValue(
117 view: Unit4, 123 Camera(view: Unit4, normal: Unit4, projection: Unit4), UniformBufferMapped
118 normal: Unit4, 124 )
119 projection: Unit4,
120 ), UniformBufferMapped)
121 ) 125 )
122 ) 126 )
123 for i in 0 ..< gltfData.materials.len: 127 for i in 0 ..< gltfData.materials.len:
124 descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer) 128 descriptors.data.materials[i] = asGPUValue(gltfData.materials[i], UniformBuffer)
125 for mesh in mitems(gltfData.meshes): 129 for mesh in mitems(gltfData.meshes):
126 for primitive in mitems(mesh): 130 for primitive in mitems(mesh):
127 primitive[0].color = asGPUArray(newSeqWith(primitive[0].position.data.len, vec4(1, 1, 1, 1)), VertexBuffer) 131 primitive[0].color = asGPUArray(
132 newSeqWith(primitive[0].position.data.len, vec4(1, 1, 1, 1)), VertexBuffer
133 )
128 renderdata.assignBuffers(primitive[0]) 134 renderdata.assignBuffers(primitive[0])
129 renderdata.assignBuffers(descriptors) 135 renderdata.assignBuffers(descriptors)
130 136
131 var pipeline = createPipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode=[]) 137 var pipeline =
138 createPipeline[Shader](renderPass = vulkan.swapchain.renderPass, cullMode = [])
132 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors) 139 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], descriptors)
133 140
134 renderdata.flushAllMemory() 141 renderdata.flushAllMemory()
135 142
136 proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4) = 143 proc drawNode(
144 commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4
145 ) =
137 let nodeTransform = gltfData.nodes[nodeId].transform * transform 146 let nodeTransform = gltfData.nodes[nodeId].transform * transform
138 if gltfData.nodes[nodeId].mesh >= 0: 147 if gltfData.nodes[nodeId].mesh >= 0:
139 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh].mitems: 148 for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh].mitems:
140 renderWithPushConstant( 149 renderWithPushConstant(
141 commandbuffer = commandbuffer, 150 commandbuffer = commandbuffer,
142 pipeline = pipeline, 151 pipeline = pipeline,
143 mesh = primitive[0], 152 mesh = primitive[0],
144 pushConstant = ObjectData(transform: nodeTransform, materialId: primitive[0].material) 153 pushConstant =
154 ObjectData(transform: nodeTransform, materialId: primitive[0].material),
145 ) 155 )
146 for childNode in gltfData.nodes[nodeId].children: 156 for childNode in gltfData.nodes[nodeId].children:
147 drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform) 157 drawNode(
158 commandbuffer = commandbuffer,
159 pipeline = pipeline,
160 nodeId = childNode,
161 transform = nodeTransform,
162 )
148 163
149 var camPos: Vec3f 164 var camPos: Vec3f
150 var camYaw: float32 165 var camYaw: float32
151 var camPitch: float32 166 var camPitch: float32
152 167
156 var lastT = getMonoTime() 171 var lastT = getMonoTime()
157 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time and updateInputs(): 172 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time and updateInputs():
158 let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32 173 let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32
159 lastT = getMonoTime() 174 lastT = getMonoTime()
160 175
161 camYaw += mouseMove().x.float32 / 1000'f32 176 camYaw += mouseMove().x.float32 / 1000'f32
162 camPitch += mouseMove().y.float32 / 1000'f32 177 camPitch += mouseMove().y.float32 / 1000'f32
163 var 178 var
164 forward = 0'f32 179 forward = 0'f32
165 sideward = 0'f32 180 sideward = 0'f32
166 if keyIsDown(W): forward += 2 181 if keyIsDown(W):
167 if keyIsDown(S): forward -= 2 182 forward += 2
168 if keyIsDown(A): sideward -= 2 183 if keyIsDown(S):
169 if keyIsDown(D): sideward += 2 184 forward -= 2
185 if keyIsDown(A):
186 sideward -= 2
187 if keyIsDown(D):
188 sideward += 2
170 189
171 let camDir = (rotate(camYaw, Y) * rotate(camPitch, X)) * Z 190 let camDir = (rotate(camYaw, Y) * rotate(camPitch, X)) * Z
172 let camDirSide = camDir.cross(-Y).normalized 191 let camDirSide = camDir.cross(-Y).normalized
173 camPos += camDir * forward * dt 192 camPos += camDir * forward * dt
174 camPos += camDirSide * sideward * dt 193 camPos += camDirSide * sideward * dt
175 194
176 let view = rotate(-camPitch, X) * rotate(-camYaw, Y) * translate(-camPos) 195 let view = rotate(-camPitch, X) * rotate(-camYaw, Y) * translate(-camPos)
177 descriptors.data.camera.data.view = view 196 descriptors.data.camera.data.view = view
178 descriptors.data.camera.data.normal = view 197 descriptors.data.camera.data.normal = view
179 descriptors.data.camera.data.projection = projection(PI / 2, aspect = getAspectRatio(), zNear = 0.01, zFar = 20) 198 descriptors.data.camera.data.projection =
199 projection(PI / 2, aspect = getAspectRatio(), zNear = 0.01, zFar = 20)
180 200
181 updateGPUBuffer(descriptors.data.camera) 201 updateGPUBuffer(descriptors.data.camera)
182 202
183 withNextFrame(framebuffer, commandbuffer): 203 withNextFrame(framebuffer, commandbuffer):
184 204 withRenderPass(
185 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): 205 vulkan.swapchain.renderPass,
186 206 framebuffer,
207 commandbuffer,
208 vulkan.swapchain.width,
209 vulkan.swapchain.height,
210 vec4(0, 0, 0, 0),
211 ):
187 withPipeline(commandbuffer, pipeline): 212 withPipeline(commandbuffer, pipeline):
188 bindDescriptorSet(commandbuffer, descriptors, 0, pipeline) 213 bindDescriptorSet(commandbuffer, descriptors, 0, pipeline)
189 for nodeId in gltfData.scenes[0]: 214 for nodeId in gltfData.scenes[0]:
190 drawNode( 215 drawNode(
191 commandbuffer = commandbuffer, 216 commandbuffer = commandbuffer,
192 pipeline = pipeline, 217 pipeline = pipeline,
193 nodeId = nodeId, 218 nodeId = nodeId,
194 transform = rotate(PI / 2, Z) 219 transform = rotate(PI / 2, Z),
195 ) 220 )
196 221
197 # cleanup 222 # cleanup
198 checkVkResult vkDeviceWaitIdle(vulkan.device) 223 checkVkResult vkDeviceWaitIdle(vulkan.device)
199 destroyPipeline(pipeline) 224 destroyPipeline(pipeline)
201 226
202 when isMainModule: 227 when isMainModule:
203 var time = 1000'f32 228 var time = 1000'f32
204 initVulkan() 229 initVulkan()
205 230
206 var renderpass = createDirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT) 231 var renderpass = createDirectPresentationRenderPass(
232 depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT
233 )
207 setupSwapchain(renderpass = renderpass) 234 setupSwapchain(renderpass = renderpass)
208 lockMouse(true) 235 lockMouse(true)
209 # showSystemCursor(false) 236 # showSystemCursor(false)
210 237
211 # tests a simple triangle with minimalistic shader and vertex format 238 # tests a simple triangle with minimalistic shader and vertex format