aboutsummaryrefslogtreecommitdiffstatsci
path: root/samples/Model
diff options
context:
space:
mode:
Diffstat (limited to 'samples/Model')
-rw-r--r--samples/Model/Model.csproj34
-rw-r--r--samples/Model/data/DamagedHelmet.binbin0 -> 558504 bytes
-rw-r--r--samples/Model/data/DamagedHelmet.gltf204
-rw-r--r--samples/Model/main.cs259
-rw-r--r--samples/Model/shaders/model.frag72
-rw-r--r--samples/Model/shaders/model.vert44
6 files changed, 613 insertions, 0 deletions
diff --git a/samples/Model/Model.csproj b/samples/Model/Model.csproj
new file mode 100644
index 0000000..df98d01
--- /dev/null
+++ b/samples/Model/Model.csproj
@@ -0,0 +1,34 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="$(RootDirectory)netfx.props" />
+ <PropertyGroup>
+ <OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
+ <OutputType>Exe</OutputType>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DefineConstants>TRACE;DEBUG;NETSTANDARD;NETSTANDARD2_0</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+
+ <ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
+ <Reference Include="System" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="glTF2Loader" Version="1.1.3-alpha" />
+ <PackageReference Include="Vulkan" Version="0.1.3" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\vke\CVKL.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <GLSLShader Include="shaders\**\*.frag;shaders\**\*.vert" />
+ <None Remove="shaders\**\*.frag;shaders\**\*.vert" />
+ </ItemGroup>
+
+ <Import Project="$(SolutionDir)spirv.targets" />
+</Project>
diff --git a/samples/Model/data/DamagedHelmet.bin b/samples/Model/data/DamagedHelmet.bin
new file mode 100644
index 0000000..662eacc
--- /dev/null
+++ b/samples/Model/data/DamagedHelmet.bin
Binary files differ
diff --git a/samples/Model/data/DamagedHelmet.gltf b/samples/Model/data/DamagedHelmet.gltf
new file mode 100644
index 0000000..c61145a
--- /dev/null
+++ b/samples/Model/data/DamagedHelmet.gltf
@@ -0,0 +1,204 @@
+{
+ "accessors" : [
+ {
+ "bufferView" : 0,
+ "componentType" : 5123,
+ "count" : 46356,
+ "max" : [
+ 14555
+ ],
+ "min" : [
+ 0
+ ],
+ "type" : "SCALAR"
+ },
+ {
+ "bufferView" : 1,
+ "componentType" : 5126,
+ "count" : 14556,
+ "max" : [
+ 0.9424954056739807,
+ 0.8128451108932495,
+ 0.900973916053772
+ ],
+ "min" : [
+ -0.9474585652351379,
+ -1.18715500831604,
+ -0.9009949564933777
+ ],
+ "type" : "VEC3"
+ },
+ {
+ "bufferView" : 2,
+ "componentType" : 5126,
+ "count" : 14556,
+ "max" : [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "min" : [
+ -1.0,
+ -1.0,
+ -1.0
+ ],
+ "type" : "VEC3"
+ },
+ {
+ "bufferView" : 3,
+ "componentType" : 5126,
+ "count" : 14556,
+ "max" : [
+ 0.9999759793281555,
+ 1.998665988445282
+ ],
+ "min" : [
+ 0.002448640065267682,
+ 1.0005531199858524
+ ],
+ "type" : "VEC2"
+ }
+ ],
+ "asset" : {
+ "generator" : "Khronos Blender glTF 2.0 exporter",
+ "version" : "2.0"
+ },
+ "bufferViews" : [
+ {
+ "buffer" : 0,
+ "byteLength" : 92712,
+ "byteOffset" : 0,
+ "target" : 34963
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 174672,
+ "byteOffset" : 92712,
+ "target" : 34962
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 174672,
+ "byteOffset" : 267384,
+ "target" : 34962
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 116448,
+ "byteOffset" : 442056,
+ "target" : 34962
+ }
+ ],
+ "buffers" : [
+ {
+ "byteLength" : 558504,
+ "uri" : "DamagedHelmet.bin"
+ }
+ ],
+ "images" : [
+ {
+ "uri" : "Default_albedo.jpg"
+ },
+ {
+ "uri" : "Default_metalRoughness.jpg"
+ },
+ {
+ "uri" : "Default_emissive.jpg"
+ },
+ {
+ "uri" : "Default_AO.jpg"
+ },
+ {
+ "uri" : "Default_normal.jpg"
+ }
+ ],
+ "materials" : [
+ {
+ "emissiveFactor" : [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "emissiveTexture" : {
+ "index" : 2
+ },
+ "name" : "Material_MR",
+ "normalTexture" : {
+ "index" : 4
+ },
+ "occlusionTexture" : {
+ "index" : 3
+ },
+ "pbrMetallicRoughness" : {
+ "baseColorTexture" : {
+ "index" : 0
+ },
+ "metallicRoughnessTexture" : {
+ "index" : 1
+ }
+ }
+ }
+ ],
+ "meshes" : [
+ {
+ "name" : "mesh_helmet_LP_13930damagedHelmet",
+ "primitives" : [
+ {
+ "attributes" : {
+ "NORMAL" : 2,
+ "POSITION" : 1,
+ "TEXCOORD_0" : 3
+ },
+ "indices" : 0,
+ "material" : 0
+ }
+ ]
+ }
+ ],
+ "nodes" : [
+ {
+ "mesh" : 0,
+ "name" : "node_damagedHelmet_-6514",
+ "rotation" : [
+ 0.7071068286895752,
+ 0.0,
+ -0.0,
+ 0.7071068286895752
+ ]
+ }
+ ],
+ "samplers" : [
+ {}
+ ],
+ "scene" : 0,
+ "scenes" : [
+ {
+ "name" : "Scene",
+ "nodes" : [
+ 0
+ ]
+ }
+ ],
+ "textures" : [
+ {
+ "sampler" : 0,
+ "source" : 0
+ },
+ {
+ "sampler" : 0,
+ "source" : 1
+ },
+ {
+ "sampler" : 0,
+ "source" : 2
+ },
+ {
+ "sampler" : 0,
+ "source" : 3
+ },
+ {
+ "sampler" : 0,
+ "source" : 4
+ }
+ ]
+}
diff --git a/samples/Model/main.cs b/samples/Model/main.cs
new file mode 100644
index 0000000..95a6e90
--- /dev/null
+++ b/samples/Model/main.cs
@@ -0,0 +1,259 @@
+using System.Collections.Generic;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using CVKL;
+using VK;
+
+namespace ModelSample {
+ class Program : VkWindow {
+ static void Main (string[] args) {
+
+ Instance.VALIDATION = true;
+ //Instance.DEBUG_UTILS = true;
+ //Instance.RENDER_DOC_CAPTURE = true;
+
+ using (Program vke = new Program ()) {
+ vke.Run ();
+ }
+ }
+
+ struct Matrices {
+ public Matrix4x4 projection;
+ public Matrix4x4 view;
+ public Matrix4x4 model;
+ //public Vector4 lightPos;
+ }
+
+ public struct PushConstants {
+ public Matrix4x4 matrix;
+ }
+
+ Matrices matrices;
+
+ HostBuffer uboMats;
+
+ DescriptorPool descriptorPool;
+ DescriptorSet dsMatrices, dsTextures;
+ DescriptorSetLayout descLayoutMatrix;
+ DescriptorSetLayout descLayoutTextures;
+
+ Framebuffer[] frameBuffers;
+
+ GraphicPipeline pipeline;
+
+ VkSampleCountFlags NUM_SAMPLES = VkSampleCountFlags.SampleCount1;
+
+ float rotSpeed = 0.01f, zoomSpeed = 0.01f;
+ float rotX, rotY, rotZ = 0f, zoom = 2f;
+
+ SimpleModel helmet;
+ DebugReport dbgReport;
+
+ Program () : base () {
+ //dbgReport = new DebugReport (instance);
+
+ descriptorPool = new DescriptorPool (dev, 2,
+ new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer),
+ new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 3));
+
+ descLayoutMatrix = new DescriptorSetLayout (dev,
+ new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer));
+
+ descLayoutTextures = new DescriptorSetLayout (dev,
+ new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
+ );
+
+
+ VkPushConstantRange pushConstantRange = new VkPushConstantRange {
+ stageFlags = VkShaderStageFlags.Vertex,
+ size = (uint)Marshal.SizeOf<PushConstants>(),
+ offset = 0
+ };
+
+ GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, NUM_SAMPLES);
+ cfg.rasterizationState.cullMode = VkCullModeFlags.Back;
+ if (NUM_SAMPLES != VkSampleCountFlags.SampleCount1) {
+ cfg.multisampleState.sampleShadingEnable = true;
+ cfg.multisampleState.minSampleShading = 0.5f;
+ }
+
+ cfg.Layout = new PipelineLayout (dev, pushConstantRange, descLayoutMatrix, descLayoutTextures);
+ cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat (), cfg.Samples);
+ cfg.AddVertexBinding<Model.Vertex> (0);
+ cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat);
+
+ cfg.AddShader (VkShaderStageFlags.Vertex, "shaders/model.vert.spv");
+ cfg.AddShader (VkShaderStageFlags.Fragment, "shaders/model.frag.spv");
+
+ pipeline = new GraphicPipeline (cfg);
+
+ helmet = new SimpleModel (presentQueue, "data/models/DamagedHelmet/glTF/DamagedHelmet.gltf");
+ //helmet = new SimpleModel (presentQueue, "data/models/Hubble.glb");
+
+ //helmet = new SimpleModel (presentQueue, "/mnt/devel/vulkan/Lugdunum/resources/models/Box.gltf");
+
+ dsMatrices = descriptorPool.Allocate (descLayoutMatrix);
+ dsTextures = descriptorPool.Allocate (descLayoutTextures);
+
+ uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, matrices);
+ //matrices.lightPos = new Vector4 (0.0f, 0.0f, -2.0f, 1.0f);
+
+ DescriptorSetWrites uboUpdate = new DescriptorSetWrites (dsMatrices, descLayoutMatrix);
+ uboUpdate.Write (dev, uboMats.Descriptor);
+
+ DescriptorSetWrites texturesUpdate = new DescriptorSetWrites (dsTextures, descLayoutTextures);
+ texturesUpdate.Write (dev,
+ helmet.textures[0].Descriptor,
+ helmet.textures[1].Descriptor,
+ helmet.textures[2].Descriptor);
+
+ uboMats.Map ();//permanent map
+ }
+
+ public override void UpdateView () {
+ matrices.projection = Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (45f),
+ (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f) * Camera.VKProjectionCorrection;
+ matrices.view =
+ Matrix4x4.CreateFromAxisAngle (Vector3.UnitZ, rotZ) *
+ Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) *
+ Matrix4x4.CreateFromAxisAngle (Vector3.UnitX, rotX) *
+ Matrix4x4.CreateTranslation (0, 0, -3f * zoom);
+ matrices.model = Matrix4x4.Identity;
+ uboMats.Update (matrices, (uint)Marshal.SizeOf<Matrices> ());
+ updateViewRequested = false;
+ }
+
+ protected override void onMouseMove (double xPos, double yPos) {
+ double diffX = lastMouseX - xPos;
+ double diffY = lastMouseY - yPos;
+ if (MouseButton[0]) {
+ rotY -= rotSpeed * (float)diffX;
+ rotX += rotSpeed * (float)diffY;
+ } else if (MouseButton[1]) {
+ zoom += zoomSpeed * (float)diffY;
+ }
+ updateViewRequested = true;
+ }
+ void buildCommandBuffers () {
+ cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
+ cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+
+ for (int i = 0; i < swapChain.ImageCount; ++i) {
+ Framebuffer fb = frameBuffers[i];
+ cmds[i].Start ();
+
+ pipeline.RenderPass.Begin (cmds[i], fb);
+
+ cmds[i].SetViewport (swapChain.Width, swapChain.Height);
+ cmds[i].SetScissor (swapChain.Width, swapChain.Height);
+
+ cmds[i].BindDescriptorSet (pipeline.Layout, dsMatrices);
+ cmds[i].BindDescriptorSet (pipeline.Layout, dsTextures, 1);
+
+ PushConstants pc = new PushConstants { matrix = Matrix4x4.Identity };
+ cmds[i].PushConstant (pipeline.Layout, VkShaderStageFlags.Vertex, pc, (uint)Marshal.SizeOf<Matrix4x4> ());
+
+ cmds[i].BindPipeline (pipeline);
+
+ helmet.DrawAll (cmds[i], pipeline.Layout);
+
+ pipeline.RenderPass.End (cmds[i]);
+
+ cmds[i].End ();
+ }
+ }
+
+ protected override void OnResize () {
+
+ if (frameBuffers != null)
+ for (int i = 0; i < swapChain.ImageCount; ++i)
+ frameBuffers[i]?.Dispose ();
+ frameBuffers = new Framebuffer[swapChain.ImageCount];
+
+ for (int i = 0; i < swapChain.ImageCount; ++i)
+ frameBuffers[i] = new Framebuffer (pipeline.RenderPass, swapChain.Width, swapChain.Height,
+ (pipeline.Samples == VkSampleCountFlags.SampleCount1) ? new Image[] {
+ swapChain.images[i],
+ null
+ } : new Image[] {
+ null,
+ null,
+ swapChain.images[i]
+ });
+
+ buildCommandBuffers ();
+ }
+
+ class SimpleModel : Model {
+ public GPUBuffer vbo;
+ public GPUBuffer ibo;
+ public Image[] textures;
+
+ public SimpleModel (Queue transferQ, string path) {
+ dev = transferQ.Dev;
+
+ using (CommandPool cmdPool = new CommandPool (dev, transferQ.index)) {
+ using (CVKL.glTFLoader ctx = new CVKL.glTFLoader (path, transferQ, cmdPool)) {
+ ulong vertexCount, indexCount;
+
+ ctx.GetVertexCount (out vertexCount, out indexCount, out IndexBufferType);
+
+ ulong vertSize = vertexCount * (ulong)Marshal.SizeOf<Vertex> ();
+ ulong idxSize = indexCount * (IndexBufferType == VkIndexType.Uint16 ? 2ul : 4ul);
+ ulong size = vertSize + idxSize;
+
+ vbo = new GPUBuffer (dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.TransferDst, vertSize);
+ ibo = new GPUBuffer (dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.TransferDst, idxSize);
+
+ vbo.SetName ("vbo gltf");
+ ibo.SetName ("ibo gltf");
+
+ Meshes = new List<Mesh> (ctx.LoadMeshes<Vertex> (IndexBufferType, vbo, 0, ibo, 0));
+ Scenes = new List<Scene> (ctx.LoadScenes (out defaultSceneIndex));
+
+ textures = ctx.LoadImages ();
+ }
+ }
+ }
+ /// <summary> bind vertex and index buffers </summary>
+ public virtual void Bind (CommandBuffer cmd) {
+ cmd.BindVertexBuffer (vbo);
+ cmd.BindIndexBuffer (ibo, IndexBufferType);
+ }
+ public void DrawAll (CommandBuffer cmd, PipelineLayout pipelineLayout) {
+ //helmet.Meshes
+ cmd.BindVertexBuffer (vbo);
+ cmd.BindIndexBuffer (ibo, IndexBufferType);
+ cmd.DrawIndexed ((uint)Meshes[0].Primitives[0].indexCount);
+ //foreach (Scene sc in Scenes) {
+ // foreach (Node node in sc.Root.Children)
+ // RenderNode (cmd, pipelineLayout, node, sc.Root.localMatrix, shadowPass);
+ //}
+ }
+ }
+
+ protected override void Dispose (bool disposing) {
+ if (disposing) {
+ if (!isDisposed) {
+ helmet.vbo.Dispose ();
+ helmet.ibo.Dispose ();
+ foreach (var t in helmet.textures)
+ t.Dispose ();
+
+ pipeline.Dispose ();
+ descLayoutMatrix.Dispose ();
+ descLayoutTextures.Dispose ();
+ for (int i = 0; i < swapChain.ImageCount; i++)
+ frameBuffers[i]?.Dispose ();
+ descriptorPool.Dispose ();
+ uboMats.Dispose ();
+ dbgReport?.Dispose ();
+ }
+ }
+
+ base.Dispose (disposing);
+ }
+ }
+}
diff --git a/samples/Model/shaders/model.frag b/samples/Model/shaders/model.frag
new file mode 100644
index 0000000..351f156
--- /dev/null
+++ b/samples/Model/shaders/model.frag
@@ -0,0 +1,72 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (set = 1, binding = 0) uniform sampler2D samplerColor;
+layout (set = 1, binding = 1) uniform sampler2D samplerNormal;
+layout (set = 1, binding = 2) uniform sampler2D samplerOcclusion;
+
+layout (location = 0) in vec2 inUV;
+layout (location = 1) in vec3 inN;
+layout (location = 2) in vec3 inV;//ViewDir
+
+layout (location = 0) out vec4 outFragColor;
+
+vec3 light = vec3(1.0,.0,1.0);
+
+// http://www.thetenthplanet.de/archives/1180
+mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)
+{
+ // get edge vectors of the pixel triangle
+ vec3 dp1 = dFdx( p );
+ vec3 dp2 = dFdy( p );
+ vec2 duv1 = dFdx( uv );
+ vec2 duv2 = dFdy( uv );
+
+ // solve the linear system
+ vec3 dp2perp = cross( dp2, N );
+ vec3 dp1perp = cross( N, dp1 );
+ vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
+ vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
+
+ // construct a scale-invariant frame
+ float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
+ return mat3( T * invmax, B * invmax, N );
+}
+
+vec3 perturb_normal( vec3 N, vec3 V, vec2 texcoord )
+{
+ // assume N, the interpolated vertex normal and
+ // V, the view vector (vertex to eye)
+ vec3 map = texture(samplerNormal, texcoord).xyz;
+ map = map * 255./127. - 128./127.;
+ mat3 TBN = cotangent_frame(N, -V, texcoord);
+ return normalize(TBN * map);
+}
+
+
+
+void main()
+{
+ vec4 diff = texture(samplerColor, inUV);
+
+ vec3 n = normalize(inN);
+ vec3 l = normalize(light);
+ vec3 pn = perturb_normal(n, inV, inUV);
+
+ float lambert = max(0.0, dot(pn, l));
+
+ //diff.rgb *= lambert * texture(samplerOcclusion, inUV).rgb;
+ vec3 spec = vec3(0);
+ vec3 amb = vec3(0.1);
+ if (lambert >= 0.0) {
+ vec3 rd = reflect(l, pn);
+ float s = dot(rd, normalize(inV));
+ spec = vec3(0.9,0.9,0.9)* //light.specular.xyz * material.specular.xyz *
+ pow(max(0.0, s), 0.5); //0.5 = mat shininess
+ }
+ //outFragColor = vec4(1.0); //
+ //outFragColor = vec4(diff.rgb , 1.0); //
+ outFragColor = vec4(diff.rgb + amb + spec , diff.a); //
+} \ No newline at end of file
diff --git a/samples/Model/shaders/model.vert b/samples/Model/shaders/model.vert
new file mode 100644
index 0000000..d63c794
--- /dev/null
+++ b/samples/Model/shaders/model.vert
@@ -0,0 +1,44 @@
+#version 450
+
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+layout (location = 0) in vec3 inPos;
+layout (location = 1) in vec3 inNormal;
+layout (location = 2) in vec2 inUV;
+
+layout (binding = 0) uniform UBO
+{
+ mat4 projectionMatrix;
+ mat4 viewMatrix;
+ mat4 modelMatrix;
+} ubo;
+
+layout (location = 0) out vec2 outUV;
+layout (location = 1) out vec3 outN;
+layout (location = 2) out vec3 outV;//ViewDir
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+layout(push_constant) uniform PushConsts {
+ mat4 model;
+} pc;
+
+void main()
+{
+ outUV = inUV;
+
+ mat4 mod = ubo.modelMatrix;// * pc.model;
+ vec4 pos = mod * vec4(inPos.xyz, 1.0);
+
+ //outN = normalize(transpose(inverse(mat3(mod))) * inNormal);
+ outN = normalize(mat3(mod)* inNormal);
+
+ mat4 viewInv = inverse(ubo.viewMatrix);
+ outV = -(ubo.viewMatrix * pos).xyz;//normalize(vec3(viewInv * vec4(0.0, 0.0, 0.0, 1.0) - pos));
+
+ gl_Position = ubo.projectionMatrix * ubo.viewMatrix * pos;
+}