From 298f635675772f87f672eabdd2d1602563ad4272 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Tue, 31 Dec 2019 18:44:15 +0100 Subject: [PATCH] wip --- samples/Model/main.cs | 12 +- samples/deferred/shaders/GBuffPbr.frag | 75 +--- samples/deferred/shaders/GBuffPbrCommon.inc | 56 +++ .../deferred/shaders/GBuffPbrTexArray.frag | 74 +--- samples/deferred/shaders/compose.frag | 77 +--- .../shaders/compose_with_shadows.frag | 75 +--- samples/deferred/shaders/tone_mapping.frag | 46 +-- samples/pbr/EnvironmentPipeline.cs | 354 ------------------ samples/pbr/main.cs | 14 +- samples/pbr/shaders/filtercube.vert | 20 - samples/pbr/shaders/genbrdflut.frag | 90 ----- samples/pbr/shaders/genbrdflut.vert | 9 - samples/pbr/shaders/irradiancecube.frag | 37 -- samples/pbr/shaders/pbr_khr.frag | 158 ++------ samples/pbr/shaders/prefilterenvmap.frag | 105 ------ samples/pbr/shaders/skybox.frag | 60 --- samples/pbr/shaders/skybox.vert | 27 -- samples/voxels/Program.cs | 10 + samples/voxels/SimpleModel.cs | 11 + samples/voxels/VkCrowWindow.cs | 204 ++++++++++ samples/voxels/Voxelization.cs | 11 + samples/voxels/shaders/constants.inc | 10 + samples/voxels/shaders/voxel_visu.frag | 26 ++ samples/voxels/shaders/voxel_visu.vert | 34 ++ samples/voxels/shaders/voxelizer.frag | 26 ++ samples/voxels/shaders/voxelizer.vert | 34 ++ samples/voxels/voxels.csproj | 8 + vke.net.sln | 24 +- vke/shaders/preamble.inc | 3 + vke/src/base/CommandBuffer.cs | 4 + vke/src/base/RenderPass.cs | 9 +- vke/src/model/ObjMesh.cs | 6 +- 32 files changed, 519 insertions(+), 1190 deletions(-) create mode 100644 samples/deferred/shaders/GBuffPbrCommon.inc delete mode 100644 samples/pbr/EnvironmentPipeline.cs delete mode 100644 samples/pbr/shaders/filtercube.vert delete mode 100644 samples/pbr/shaders/genbrdflut.frag delete mode 100644 samples/pbr/shaders/genbrdflut.vert delete mode 100644 samples/pbr/shaders/irradiancecube.frag delete mode 100644 samples/pbr/shaders/prefilterenvmap.frag delete mode 100644 samples/pbr/shaders/skybox.frag delete mode 100644 samples/pbr/shaders/skybox.vert create mode 100644 samples/voxels/Program.cs create mode 100644 samples/voxels/SimpleModel.cs create mode 100644 samples/voxels/VkCrowWindow.cs create mode 100644 samples/voxels/Voxelization.cs create mode 100644 samples/voxels/shaders/constants.inc create mode 100644 samples/voxels/shaders/voxel_visu.frag create mode 100644 samples/voxels/shaders/voxel_visu.vert create mode 100644 samples/voxels/shaders/voxelizer.frag create mode 100644 samples/voxels/shaders/voxelizer.vert create mode 100644 samples/voxels/voxels.csproj create mode 100644 vke/shaders/preamble.inc diff --git a/samples/Model/main.cs b/samples/Model/main.cs index 05bae06..d4ce864 100644 --- a/samples/Model/main.cs +++ b/samples/Model/main.cs @@ -214,16 +214,18 @@ namespace ModelSample public override void RenderNode (CommandBuffer cmd, PipelineLayout pipelineLayout, Node node, Matrix4x4 currentTransform, bool shadowPass = false) { throw new System.NotImplementedException (); } + protected override void Dispose (bool disposing) + { + foreach (var t in textures) + t.Dispose (); + base.Dispose (disposing); + } } protected override void Dispose (bool disposing) { if (disposing) { if (!isDisposed) { - helmet.vbo.Dispose (); - helmet.ibo.Dispose (); - foreach (var t in helmet.textures) - t.Dispose (); - + helmet.Dispose (); pipeline.Dispose (); descLayoutMatrix.Dispose (); descLayoutTextures.Dispose (); diff --git a/samples/deferred/shaders/GBuffPbr.frag b/samples/deferred/shaders/GBuffPbr.frag index c6e1160..9e30cab 100644 --- a/samples/deferred/shaders/GBuffPbr.frag +++ b/samples/deferred/shaders/GBuffPbr.frag @@ -4,10 +4,6 @@ #define MANUAL_SRGB 0 -layout (constant_id = 0) const float NEAR_PLANE = 0.1f; -layout (constant_id = 1) const float FAR_PLANE = 256.0f; -layout (constant_id = 2) const int MAT_COUNT = 1; - struct Material { vec4 baseColorFactor; vec4 emissiveFactor; @@ -22,29 +18,9 @@ struct Material { float alphaMaskCutoff; int pad0; }; -const float M_PI = 3.141592653589793; -const float c_MinRoughness = 0.04; - -const float PBR_WORKFLOW_METALLIC_ROUGHNESS = 1.0; -const float PBR_WORKFLOW_SPECULAR_GLOSINESS = 2.0f; - -const uint MAP_COLOR = 0x1; -const uint MAP_NORMAL = 0x2; -const uint MAP_AO = 0x4; -const uint MAP_METAL = 0x8; -const uint MAP_ROUGHNESS = 0x10; -const uint MAP_METALROUGHNESS = 0x20; -const uint MAP_EMISSIVE = 0x40; - -layout (location = 0) in vec3 inWorldPos; -layout (location = 1) in vec3 inNormal; -layout (location = 2) in vec2 inUV0; -layout (location = 3) in vec2 inUV1; - -layout (set = 0, binding = 5) uniform UBOMaterials { - Material materials[MAT_COUNT]; -}; +#include "GBuffPbrCommon.inc" +#include "tonemap.inc" // Material bindings layout (set = 2, binding = 0) uniform sampler2D colorMap; @@ -53,33 +29,6 @@ layout (set = 2, binding = 2) uniform sampler2D normalMap; layout (set = 2, binding = 3) uniform sampler2D aoMap; layout (set = 2, binding = 4) uniform sampler2D emissiveMap; - -layout (push_constant) uniform PushCsts { - layout(offset = 64) - int materialIdx; -}; - - -layout (location = 0) out vec4 outColorRough; -layout (location = 1) out vec4 outEmitMetal; -layout (location = 2) out vec4 outN_AO; -layout (location = 3) out vec4 outPos; - -vec4 SRGBtoLINEAR(vec4 srgbIn) -{ - #ifdef MANUAL_SRGB - #ifdef SRGB_FAST_APPROXIMATION - vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); - #else //SRGB_FAST_APPROXIMATION - vec3 bLess = step(vec3(0.04045),srgbIn.xyz); - vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); - #endif //SRGB_FAST_APPROXIMATION - return vec4(linOut,srgbIn.w);; - #else //MANUAL_SRGB - return srgbIn; - #endif //MANUAL_SRGB -} - // Find the normal for this fragment, pulling either from a predefined normal map // or from the interpolated mesh normal and tangent attributes. vec3 getNormal() @@ -106,26 +55,6 @@ vec3 getNormal() return normalize(TBN * tangentNormal); } -// Gets metallic factor from specular glossiness workflow inputs -float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { - float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); - float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); - if (perceivedSpecular < c_MinRoughness) { - return 0.0; - } - float a = c_MinRoughness; - float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; - float c = c_MinRoughness - perceivedSpecular; - float D = max(b * b - 4.0 * a * c, 0.0); - return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); -} - -float linearDepth(float depth) -{ - float z = depth * 2.0f - 1.0f; - return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); -} - void main() { float perceptualRoughness; diff --git a/samples/deferred/shaders/GBuffPbrCommon.inc b/samples/deferred/shaders/GBuffPbrCommon.inc new file mode 100644 index 0000000..4146fa5 --- /dev/null +++ b/samples/deferred/shaders/GBuffPbrCommon.inc @@ -0,0 +1,56 @@ +layout (constant_id = 0) const float NEAR_PLANE = 0.1f; +layout (constant_id = 1) const float FAR_PLANE = 256.0f; +layout (constant_id = 2) const int MAT_COUNT = 1; + +const float M_PI = 3.141592653589793; +const float c_MinRoughness = 0.04; + +const float PBR_WORKFLOW_METALLIC_ROUGHNESS = 1.0; +const float PBR_WORKFLOW_SPECULAR_GLOSINESS = 2.0f; + +const uint MAP_COLOR = 0x1; +const uint MAP_NORMAL = 0x2; +const uint MAP_AO = 0x4; +const uint MAP_METAL = 0x8; +const uint MAP_ROUGHNESS = 0x10; +const uint MAP_METALROUGHNESS = 0x20; +const uint MAP_EMISSIVE = 0x40; + +layout (location = 0) in vec3 inWorldPos; +layout (location = 1) in vec3 inNormal; +layout (location = 2) in vec2 inUV0; +layout (location = 3) in vec2 inUV1; + +layout (set = 0, binding = 5) uniform UBOMaterials { + Material materials[MAT_COUNT]; +}; + +layout (push_constant) uniform PushCsts { + layout(offset = 64) + int materialIdx; +}; + +layout (location = 0) out vec4 outColorRough; +layout (location = 1) out vec4 outEmitMetal; +layout (location = 2) out vec4 outN_AO; +layout (location = 3) out vec4 outPos; + +// Gets metallic factor from specular glossiness workflow inputs +float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { + float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); + float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); + if (perceivedSpecular < c_MinRoughness) { + return 0.0; + } + float a = c_MinRoughness; + float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; + float c = c_MinRoughness - perceivedSpecular; + float D = max(b * b - 4.0 * a * c, 0.0); + return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); +} + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); +} \ No newline at end of file diff --git a/samples/deferred/shaders/GBuffPbrTexArray.frag b/samples/deferred/shaders/GBuffPbrTexArray.frag index 3d666d0..cddf49f 100644 --- a/samples/deferred/shaders/GBuffPbrTexArray.frag +++ b/samples/deferred/shaders/GBuffPbrTexArray.frag @@ -4,10 +4,6 @@ #define MANUAL_SRGB 0 -layout (constant_id = 0) const float NEAR_PLANE = 0.1f; -layout (constant_id = 1) const float FAR_PLANE = 256.0f; -layout (constant_id = 2) const int MAT_COUNT = 1; - struct Material { vec4 baseColorFactor; vec4 emissiveFactor; @@ -29,55 +25,11 @@ struct Material { float alphaMask; float alphaMaskCutoff; }; -const float M_PI = 3.141592653589793; -const float c_MinRoughness = 0.04; - -const float PBR_WORKFLOW_METALLIC_ROUGHNESS = 1.0; -const float PBR_WORKFLOW_SPECULAR_GLOSINESS = 2.0f; - -const uint MAP_COLOR = 0x1; -const uint MAP_NORMAL = 0x2; -const uint MAP_AO = 0x4; -const uint MAP_METAL = 0x8; -const uint MAP_ROUGHNESS = 0x10; -const uint MAP_METALROUGHNESS = 0x20; -const uint MAP_EMISSIVE = 0x40; - -layout (location = 0) in vec3 inWorldPos; -layout (location = 1) in vec3 inNormal; -layout (location = 2) in vec2 inUV0; -layout (location = 3) in vec2 inUV1; - -layout (set = 0, binding = 5) uniform UBOMaterials { - Material materials[MAT_COUNT]; -}; -layout (set = 0, binding = 7) uniform sampler2DArray texArray; - -layout (push_constant) uniform PushCsts { - layout(offset = 64) - int materialIdx; -}; - -layout (location = 0) out vec4 outColorRough; -layout (location = 1) out vec4 outEmitMetal; -layout (location = 2) out vec4 outN_AO; -layout (location = 3) out vec4 outPos; +#include "GBuffPbrCommon.inc" +#include "tonemap.inc" -vec4 SRGBtoLINEAR(vec4 srgbIn) -{ - #ifdef MANUAL_SRGB - #ifdef SRGB_FAST_APPROXIMATION - vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); - #else //SRGB_FAST_APPROXIMATION - vec3 bLess = step(vec3(0.04045),srgbIn.xyz); - vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); - #endif //SRGB_FAST_APPROXIMATION - return vec4(linOut,srgbIn.w);; - #else //MANUAL_SRGB - return srgbIn; - #endif //MANUAL_SRGB -} +layout (set = 0, binding = 7) uniform sampler2DArray texArray; // Find the normal for this fragment, pulling either from a predefined normal map // or from the interpolated mesh normal and tangent attributes. @@ -105,26 +57,6 @@ vec3 getNormal() return normalize(TBN * tangentNormal); } -// Gets metallic factor from specular glossiness workflow inputs -float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { - float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); - float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); - if (perceivedSpecular < c_MinRoughness) { - return 0.0; - } - float a = c_MinRoughness; - float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; - float c = c_MinRoughness - perceivedSpecular; - float D = max(b * b - 4.0 * a * c, 0.0); - return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); -} - -float linearDepth(float depth) -{ - float z = depth * 2.0f - 1.0f; - return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); -} - void main() { float perceptualRoughness; diff --git a/samples/deferred/shaders/compose.frag b/samples/deferred/shaders/compose.frag index 81312bd..e6ab256 100644 --- a/samples/deferred/shaders/compose.frag +++ b/samples/deferred/shaders/compose.frag @@ -1,6 +1,4 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable +#include "preamble.inc" layout (set = 0, binding = 0) uniform UBO { mat4 projection; @@ -41,24 +39,7 @@ layout (location = 0) in vec2 inUV; layout (location = 0) out vec4 outColor; -// Encapsulate the various inputs used by the various functions in the shading equation -// We store values in this struct to simplify the integration of alternative implementations -// of the shading terms, outlined in the Readme.MD Appendix. -struct PBRInfo -{ - float NdotL; // cos angle between normal and light direction - float NdotV; // cos angle between normal and view direction - float NdotH; // cos angle between normal and half vector - float LdotH; // cos angle between light direction and half vector - float VdotH; // cos angle between view direction and half vector - float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) - float metalness; // metallic value at the surface - vec3 reflectance0; // full reflectance color (normal incidence angle) - vec3 reflectance90; // reflectance color at grazing angle - float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) - vec3 diffuseColor; // color contribution from diffuse lighting - vec3 specularColor; // color contribution from specular lighting -}; +#include "pbr.inc" // Calculation of the lighting contribution from an optional Image Based Light source. // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1]. @@ -83,60 +64,6 @@ vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection) return diffuse + specular; } -// Basic Lambertian diffuse -// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog -// See also [1], Equation 1 -vec3 diffuse(PBRInfo pbrInputs) -{ - return pbrInputs.diffuseColor / M_PI; -} - -// The following equation models the Fresnel reflectance term of the spec equation (aka F()) -// Implementation of fresnel from [4], Equation 15 -vec3 specularReflection(PBRInfo pbrInputs) -{ - return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); -} - -// This calculates the specular geometric attenuation (aka G()), -// where rougher material will reflect less light back to the viewer. -// This implementation is based on [1] Equation 4, and we adopt their modifications to -// alphaRoughness as input as originally proposed in [2]. -float geometricOcclusion(PBRInfo pbrInputs) -{ - float NdotL = pbrInputs.NdotL; - float NdotV = pbrInputs.NdotV; - float r = pbrInputs.alphaRoughness; - - float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); - float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); - return attenuationL * attenuationV; -} - -// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) -// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz -// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. -float microfacetDistribution(PBRInfo pbrInputs) -{ - float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; - float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; - return roughnessSq / (M_PI * f * f); -} - -// Gets metallic factor from specular glossiness workflow inputs -float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { - float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); - float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); - if (perceivedSpecular < c_MinRoughness) { - return 0.0; - } - float a = c_MinRoughness; - float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; - float c = c_MinRoughness - perceivedSpecular; - float D = max(b * b - 4.0 * a * c, 0.0); - return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); -} - void main() { if (subpassLoad(samplerPos, gl_SampleID).a == 1.0f) diff --git a/samples/deferred/shaders/compose_with_shadows.frag b/samples/deferred/shaders/compose_with_shadows.frag index 4247393..68fc8bf 100644 --- a/samples/deferred/shaders/compose_with_shadows.frag +++ b/samples/deferred/shaders/compose_with_shadows.frag @@ -41,24 +41,7 @@ layout (location = 0) in vec2 inUV; layout (location = 0) out vec4 outColor; -// Encapsulate the various inputs used by the various functions in the shading equation -// We store values in this struct to simplify the integration of alternative implementations -// of the shading terms, outlined in the Readme.MD Appendix. -struct PBRInfo -{ - float NdotL; // cos angle between normal and light direction - float NdotV; // cos angle between normal and view direction - float NdotH; // cos angle between normal and half vector - float LdotH; // cos angle between light direction and half vector - float VdotH; // cos angle between view direction and half vector - float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) - float metalness; // metallic value at the surface - vec3 reflectance0; // full reflectance color (normal incidence angle) - vec3 reflectance90; // reflectance color at grazing angle - float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) - vec3 diffuseColor; // color contribution from diffuse lighting - vec3 specularColor; // color contribution from specular lighting -}; +#include "pbr.inc" // Calculation of the lighting contribution from an optional Image Based Light source. // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1]. @@ -68,8 +51,8 @@ vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection) float lod = (pbrInputs.perceptualRoughness * ubo.prefilteredCubeMipLevels); // retrieve a scale and bias to F0. See [1], Figure 3 vec3 brdf = (texture(samplerBRDFLUT, vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb; + vec3 diffuseLight = texture(samplerIrradiance, reflection).rgb; - vec3 specularLight = textureLod(prefilteredMap, reflection, lod).rgb; vec3 diffuse = diffuseLight * pbrInputs.diffuseColor; @@ -83,60 +66,6 @@ vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection) return diffuse + specular; } -// Basic Lambertian diffuse -// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog -// See also [1], Equation 1 -vec3 diffuse(PBRInfo pbrInputs) -{ - return pbrInputs.diffuseColor / M_PI; -} - -// The following equation models the Fresnel reflectance term of the spec equation (aka F()) -// Implementation of fresnel from [4], Equation 15 -vec3 specularReflection(PBRInfo pbrInputs) -{ - return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); -} - -// This calculates the specular geometric attenuation (aka G()), -// where rougher material will reflect less light back to the viewer. -// This implementation is based on [1] Equation 4, and we adopt their modifications to -// alphaRoughness as input as originally proposed in [2]. -float geometricOcclusion(PBRInfo pbrInputs) -{ - float NdotL = pbrInputs.NdotL; - float NdotV = pbrInputs.NdotV; - float r = pbrInputs.alphaRoughness; - - float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); - float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); - return attenuationL * attenuationV; -} - -// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) -// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz -// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. -float microfacetDistribution(PBRInfo pbrInputs) -{ - float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; - float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; - return roughnessSq / (M_PI * f * f); -} - -// Gets metallic factor from specular glossiness workflow inputs -float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { - float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); - float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); - if (perceivedSpecular < c_MinRoughness) { - return 0.0; - } - float a = c_MinRoughness; - float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; - float c = c_MinRoughness - perceivedSpecular; - float D = max(b * b - 4.0 * a * c, 0.0); - return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); -} - float textureProj(vec4 P, float layer, vec2 offset) { float shadow = 1.0; diff --git a/samples/deferred/shaders/tone_mapping.frag b/samples/deferred/shaders/tone_mapping.frag index 6a1a8d4..138bea8 100644 --- a/samples/deferred/shaders/tone_mapping.frag +++ b/samples/deferred/shaders/tone_mapping.frag @@ -1,62 +1,30 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable +#include "preamble.inc" layout(push_constant) uniform PushConsts { float exposure; float gamma; float debug; -} pc; +}; + +#include "tonemap.inc" layout (set = 0, binding = 0) uniform sampler2D samplerHDR; layout (set = 0, binding = 1) uniform sampler2D bloom; layout (location = 0) in vec2 inUV; layout (location = 0) out vec4 outColor; - -vec3 Uncharted2Tonemap(vec3 color) -{ - const float A = 0.15; - const float B = 0.50; - const float C = 0.10; - const float D = 0.20; - const float E = 0.02; - const float F = 0.30; - const float W = 11.2; - return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; -} - -vec3 tonemap(vec3 color) -{ - vec3 outcol = Uncharted2Tonemap(color.rgb * pc.exposure); - outcol = outcol * (1.0f / Uncharted2Tonemap(vec3(11.2f))); - return pow(outcol, vec3(1.0f / pc.gamma)); -} - -vec3 SRGBtoLINEAR(vec3 srgbIn) -{ - #ifdef MANUAL_SRGB - #ifdef SRGB_FAST_APPROXIMATION - return pow(srgbIn.xyz,vec3(2.2)); - #else //SRGB_FAST_APPROXIMATION - vec3 bLess = step(vec3(0.04045),srgbIn.xyz); - return linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); - #endif //SRGB_FAST_APPROXIMATION - #else //MANUAL_SRGB - return srgbIn; - #endif //MANUAL_SRGB -} void main() { - if (pc.debug < 0.0f) { + if (debug < 0.0f) { //vec4 hdrColor = texelFetch (samplerHDR, ivec2(inUV), gl_SampleID); vec4 hdrColor = texture (samplerHDR, inUV); //vec4 c = texture (bloom, inUV); //float lum = (0.299*c.r + 0.587*c.g + 0.114*c.b); //if (lum>1.0) // hdrColor.rgb += c.rgb * 0.05; - outColor = vec4(SRGBtoLINEAR(tonemap(hdrColor.rgb)), hdrColor.a); + //outColor = SRGBtoLINEAR(tonemap(hdrColor, exposure, gamma)); + outColor = tonemap(hdrColor, exposure, gamma); }else outColor = texture (bloom, inUV); diff --git a/samples/pbr/EnvironmentPipeline.cs b/samples/pbr/EnvironmentPipeline.cs deleted file mode 100644 index c4f883c..0000000 --- a/samples/pbr/EnvironmentPipeline.cs +++ /dev/null @@ -1,354 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Numerics; -using System.Runtime.InteropServices; -using Vulkan; - -namespace vke { - class EnvironmentCube : GraphicPipeline { - - GPUBuffer vboSkybox; - - public Image cubemap { get; private set; } - public Image lutBrdf { get; private set; } - public Image irradianceCube { get; private set; } - public Image prefilterCube { get; set; } - - public Image debugImg; - public int debugMip = -1; - public int debugFace = 0; - - public EnvironmentCube (DescriptorSet dsSkybox, PipelineLayout plLayout, Queue staggingQ, RenderPass renderPass, PipelineCache pipelineCache = null) - : base (renderPass, pipelineCache, "EnvCube pipeline") { - - using (CommandPool cmdPool = new CommandPool (staggingQ.Dev, staggingQ.index)) { - - vboSkybox = new GPUBuffer (staggingQ, cmdPool, VkBufferUsageFlags.VertexBuffer, box_vertices); - - cubemap = KTX.KTX.Load (staggingQ, cmdPool, cubemapPathes[2], - VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal, true); - cubemap.CreateView (VkImageViewType.Cube, VkImageAspectFlags.Color, 6); - cubemap.CreateSampler (VkSamplerAddressMode.ClampToEdge); - cubemap.SetName ("skybox Texture"); - cubemap.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - - GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, renderPass.Samples, false); - cfg.RenderPass = renderPass; - cfg.Layout = plLayout; - cfg.AddVertexBinding (0, 3 * sizeof (float)); - cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat); - cfg.AddShader (VkShaderStageFlags.Vertex, "#pbr.skybox.vert.spv"); - cfg.AddShader (VkShaderStageFlags.Fragment, "#pbr.skybox.frag.spv"); - cfg.multisampleState.rasterizationSamples = Samples; - - layout = cfg.Layout; - - init (cfg); - - generateBRDFLUT (staggingQ, cmdPool); - generateCubemaps (staggingQ, cmdPool); - } - - } - - //public void WriteDesc (VkDescriptorBufferInfo matrixDesc) { - // DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descLayoutMain); - // uboUpdate.Write (Dev, dsSkybox, matrixDesc, cubemap.Descriptor); - //} - - public void RecordDraw (CommandBuffer cmd) { - Bind (cmd); - cmd.BindVertexBuffer (vboSkybox); - cmd.Draw (36); - } - - #region skybox - public List cubemapPathes = new List() { - Utils.DataDirectory + "textures/papermill.ktx", - Utils.DataDirectory + "textures/cubemap_yokohama_bc3_unorm.ktx", - Utils.DataDirectory + "textures/gcanyon_cube.ktx", - Utils.DataDirectory + "textures/pisa_cube.ktx", - Utils.DataDirectory + "textures/uffizi_cube.ktx", - }; - static float[] box_vertices = { - 1.0f, 1.0f,-1.0f, // +X side - 1.0f, 1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f,-1.0f,-1.0f, - 1.0f, 1.0f,-1.0f, - - -1.0f,-1.0f,-1.0f, // +X side - -1.0f,-1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f,-1.0f, - -1.0f,-1.0f,-1.0f, - - -1.0f, 1.0f,-1.0f, // +Y side - -1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f, 1.0f,-1.0f, - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f,-1.0f, - - -1.0f,-1.0f,-1.0f, // -Y side - 1.0f,-1.0f,-1.0f, - 1.0f,-1.0f, 1.0f, - -1.0f,-1.0f,-1.0f, - 1.0f,-1.0f, 1.0f, - -1.0f,-1.0f, 1.0f, - - -1.0f, 1.0f, 1.0f, // +Z side - -1.0f,-1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - -1.0f,-1.0f, 1.0f, - 1.0f,-1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - - -1.0f,-1.0f,-1.0f, // -Z side - 1.0f, 1.0f,-1.0f, - 1.0f,-1.0f,-1.0f, - -1.0f,-1.0f,-1.0f, - -1.0f, 1.0f,-1.0f, - 1.0f, 1.0f,-1.0f, - - }; - #endregion - - void generateBRDFLUT (Queue staggingQ, CommandPool cmdPool) { - const VkFormat format = VkFormat.R16g16Sfloat; - const int dim = 512; - - lutBrdf = new Image (Dev, format, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled, - VkMemoryPropertyFlags.DeviceLocal, dim, dim); - lutBrdf.SetName ("lutBrdf"); - - lutBrdf.CreateView (); - lutBrdf.CreateSampler (VkSamplerAddressMode.ClampToEdge); - - GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false); - - cfg.Layout = new PipelineLayout (Dev, new DescriptorSetLayout (Dev)); - cfg.RenderPass = new RenderPass (Dev); - cfg.RenderPass.AddAttachment (format, VkImageLayout.ShaderReadOnlyOptimal); - cfg.RenderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0, 0, 0) }); - cfg.RenderPass.AddSubpass (new SubPass (VkImageLayout.ColorAttachmentOptimal)); - cfg.AddShader (VkShaderStageFlags.Vertex, "#pbr.genbrdflut.vert.spv"); - cfg.AddShader (VkShaderStageFlags.Fragment, "#pbr.genbrdflut.frag.spv"); - - using (GraphicPipeline pl = new GraphicPipeline (cfg)) { - using (FrameBuffer fb = new FrameBuffer (cfg.RenderPass, dim, dim, lutBrdf)) { - CommandBuffer cmd = cmdPool.AllocateCommandBuffer (); - cmd.Start (VkCommandBufferUsageFlags.OneTimeSubmit); - pl.RenderPass.Begin (cmd, fb); - cmd.SetViewport (dim, dim); - cmd.SetScissor (dim, dim); - pl.Bind (cmd); - cmd.Draw (3, 1, 0, 0); - pl.RenderPass.End (cmd); - cmd.End (); - - staggingQ.Submit (cmd); - staggingQ.WaitIdle (); - - cmd.Free (); - } - } - lutBrdf.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - } - - public enum CBTarget { IRRADIANCE = 0, PREFILTEREDENV = 1 }; - - public Image generateCubeMap (Queue staggingQ, CommandPool cmdPool, CBTarget target) { - const float deltaPhi = (2.0f * (float)Math.PI) / 180.0f; - const float deltaTheta = (0.5f * (float)Math.PI) / 64.0f; - - VkFormat format = VkFormat.R32g32b32a32Sfloat; - uint dim = 64; - - if (target == CBTarget.PREFILTEREDENV) { - format = VkFormat.R16g16b16a16Sfloat; - dim = 512; - } - - uint numMips = (uint)Math.Floor (Math.Log (dim, 2)) + 1; - - Image imgFbOffscreen = new Image (Dev, format, VkImageUsageFlags.TransferSrc | VkImageUsageFlags.ColorAttachment, - VkMemoryPropertyFlags.DeviceLocal, dim, dim); - imgFbOffscreen.SetName ("offscreenfb"); - imgFbOffscreen.CreateView (); - - Image cmap = new Image (Dev, format, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled, - VkMemoryPropertyFlags.DeviceLocal, dim, dim, VkImageType.Image2D, VkSampleCountFlags.SampleCount1, VkImageTiling.Optimal, - numMips, 6, 1, VkImageCreateFlags.CubeCompatible); - if (target == CBTarget.PREFILTEREDENV) - cmap.SetName ("prefilterenvmap"); - else - cmap.SetName ("irradianceCube"); - cmap.CreateView (VkImageViewType.Cube, VkImageAspectFlags.Color, 6); - cmap.CreateSampler (VkSamplerAddressMode.ClampToEdge); - - DescriptorPool dsPool = new DescriptorPool (Dev, 2, new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler)); - - DescriptorSetLayout dsLayout = new DescriptorSetLayout (Dev, - new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)); - - - GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false); - - cfg.Layout = new PipelineLayout (Dev, dsLayout); - cfg.Layout.AddPushConstants ( - new VkPushConstantRange (VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, (uint)Marshal.SizeOf () + 8)); - - cfg.RenderPass = new RenderPass (Dev); - cfg.RenderPass.AddAttachment (format, VkImageLayout.ColorAttachmentOptimal); - cfg.RenderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0, 0, 0) }); - cfg.RenderPass.AddSubpass (new SubPass (VkImageLayout.ColorAttachmentOptimal)); - - cfg.AddVertexBinding (0, 3 * sizeof (float)); - cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat); - - cfg.AddShader (VkShaderStageFlags.Vertex, "#pbr.filtercube.vert.spv"); - if (target == CBTarget.PREFILTEREDENV) - cfg.AddShader (VkShaderStageFlags.Fragment, "#pbr.prefilterenvmap.frag.spv"); - else - cfg.AddShader (VkShaderStageFlags.Fragment, "#pbr.irradiancecube.frag.spv"); - - Matrix4x4[] matrices = { - // POSITIVE_X - Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(90)), - // NEGATIVE_X - Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(-90)), - // POSITIVE_Y - Matrix4x4.CreateRotationX(Utils.DegreesToRadians(-90)), - // NEGATIVE_Y - Matrix4x4.CreateRotationX(Utils.DegreesToRadians(90)), - // POSITIVE_Z - Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)), - // NEGATIVE_Z - Matrix4x4.CreateRotationZ(Utils.DegreesToRadians(180)) - }; - - VkImageSubresourceRange subRes = new VkImageSubresourceRange (VkImageAspectFlags.Color, 0, numMips, 0, 6); - - using (GraphicPipeline pl = new GraphicPipeline (cfg)) { - DescriptorSet dset = dsPool.Allocate (dsLayout); - DescriptorSetWrites dsUpdate = new DescriptorSetWrites (dsLayout); - dsUpdate.Write (Dev, dset, cubemap.Descriptor); - - using (FrameBuffer fb = new FrameBuffer (pl.RenderPass, dim, dim, imgFbOffscreen)) { - CommandBuffer cmd = cmdPool.AllocateCommandBuffer (); - cmd.Start (VkCommandBufferUsageFlags.OneTimeSubmit); - - cmap.SetLayout (cmd, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, subRes); - - float roughness = 0; - - cmd.SetScissor (dim, dim); - cmd.SetViewport ((float)(dim), (float)dim); - - for (int m = 0; m < numMips; m++) { - roughness = (float)m / ((float)numMips - 1f); - - for (int f = 0; f < 6; f++) { - pl.RenderPass.Begin (cmd, fb); - - pl.Bind (cmd); - - float viewPortSize = (float)Math.Pow (0.5, m) * dim; - cmd.SetViewport (viewPortSize, viewPortSize); - cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, - matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (90), 1f, 0.1f, 512f)); - if (target == CBTarget.IRRADIANCE) { - cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaPhi, (uint)Marshal.SizeOf ()); - cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf () + 4); - } else { - cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, roughness, (uint)Marshal.SizeOf ()); - cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 32u, (uint)Marshal.SizeOf () + 4); - } - - cmd.BindDescriptorSet (pl.Layout, dset); - cmd.BindVertexBuffer (vboSkybox); - cmd.Draw (36); - - pl.RenderPass.End (cmd); - - imgFbOffscreen.SetLayout (cmd, VkImageAspectFlags.Color, - VkImageLayout.ColorAttachmentOptimal, VkImageLayout.TransferSrcOptimal); - - VkImageCopy region = new VkImageCopy (); - region.srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, 1); - region.dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, 1, (uint)m, (uint)f); - region.extent = new VkExtent3D { width = (uint)viewPortSize, height = (uint)viewPortSize, depth = 1 }; - - Vk.vkCmdCopyImage (cmd.Handle, - imgFbOffscreen.Handle, VkImageLayout.TransferSrcOptimal, - cmap.Handle, VkImageLayout.TransferDstOptimal, - 1, region.Pin ()); - region.Unpin (); - - //debug img - if (target == CBTarget.PREFILTEREDENV && m == debugMip && f == debugFace) { - debugImg?.Dispose (); - debugImg = new Image (Dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst, VkMemoryPropertyFlags.DeviceLocal, - (uint)viewPortSize, (uint)viewPortSize); - debugImg.CreateView (); - debugImg.CreateSampler (); - region.dstSubresource.baseArrayLayer = 0; - region.dstSubresource.mipLevel = 0; - debugImg.SetLayout (cmd, VkImageAspectFlags.Color, - VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal); - Vk.vkCmdCopyImage (cmd.Handle, - imgFbOffscreen.Handle, VkImageLayout.TransferSrcOptimal, - debugImg.Handle, VkImageLayout.TransferDstOptimal, - 1, region.Pin ()); - debugImg.SetLayout (cmd, VkImageAspectFlags.Color, - VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal); - region.Unpin (); - } - - imgFbOffscreen.SetLayout (cmd, VkImageAspectFlags.Color, - VkImageLayout.TransferSrcOptimal, VkImageLayout.ColorAttachmentOptimal); - - } - } - - cmap.SetLayout (cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, subRes); - - cmd.End (); - - staggingQ.Submit (cmd); - staggingQ.WaitIdle (); - - cmd.Free (); - } - } - cmap.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - - dsLayout.Dispose (); - imgFbOffscreen.Dispose (); - dsPool.Dispose (); - - return cmap; - } - - void generateCubemaps (Queue staggingQ, CommandPool cmdPool) { - irradianceCube = generateCubeMap (staggingQ, cmdPool, CBTarget.IRRADIANCE); - prefilterCube = generateCubeMap (staggingQ, cmdPool, CBTarget.PREFILTEREDENV); - } - - protected override void Dispose (bool disposing) { - vboSkybox.Dispose (); - cubemap.Dispose (); - lutBrdf.Dispose (); - irradianceCube.Dispose (); - prefilterCube.Dispose (); - - debugImg?.Dispose (); - - base.Dispose (disposing); - } - } - -} diff --git a/samples/pbr/main.cs b/samples/pbr/main.cs index abb69ae..94d4185 100644 --- a/samples/pbr/main.cs +++ b/samples/pbr/main.cs @@ -20,6 +20,8 @@ namespace pbrSample { Instance.VALIDATION = true; Instance.RENDER_DOC_CAPTURE = false; #endif + SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm; + using (Program vke = new Program ()) { vke.Run (); } @@ -32,7 +34,7 @@ namespace pbrSample { enabled_features.samplerAnisotropy = available_features.samplerAnisotropy; } - VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1; + VkSampleCountFlags samples = VkSampleCountFlags.SampleCount4; FrameBuffers frameBuffers; PBRPipeline pbrPipeline; @@ -362,14 +364,20 @@ namespace pbrSample { lightPos -= Vector4.UnitY; else camera.Move (0, -1, 0); - break; + break; + case Key.S: + if (modifiers.HasFlag (Modifier.Shift)) + pbrPipeline.matrices.scaleIBLAmbient -= 0.1f; + else + pbrPipeline.matrices.scaleIBLAmbient += 0.1f; + break; case Key.F2: if (modifiers.HasFlag (Modifier.Shift)) pbrPipeline.matrices.exposure -= 0.3f; else pbrPipeline.matrices.exposure += 0.3f; break; - case Key.F3: + case Key.F3: if (modifiers.HasFlag (Modifier.Shift)) pbrPipeline.matrices.gamma -= 0.1f; else diff --git a/samples/pbr/shaders/filtercube.vert b/samples/pbr/shaders/filtercube.vert deleted file mode 100644 index 34adf73..0000000 --- a/samples/pbr/shaders/filtercube.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 450 - -layout (location = 0) in vec3 inPos; - -layout(push_constant) uniform PushConsts { - layout (offset = 0) mat4 mvp; -} pushConsts; - -layout (location = 0) out vec3 outUVW; - -out gl_PerVertex { - vec4 gl_Position; -}; - -void main() -{ - outUVW = inPos; - //outUVW.y = -outUVW.y; - gl_Position = pushConsts.mvp * vec4(inPos.xyz, 1.0); -} diff --git a/samples/pbr/shaders/genbrdflut.frag b/samples/pbr/shaders/genbrdflut.frag deleted file mode 100644 index b6290dd..0000000 --- a/samples/pbr/shaders/genbrdflut.frag +++ /dev/null @@ -1,90 +0,0 @@ -#version 450 - -layout (location = 0) in vec2 inUV; -layout (location = 0) out vec4 outColor; -layout (constant_id = 0) const uint NUM_SAMPLES = 1024u; - -const float PI = 3.1415926536; - -// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ -float random(vec2 co) -{ - float a = 12.9898; - float b = 78.233; - float c = 43758.5453; - float dt= dot(co.xy ,vec2(a,b)); - float sn= mod(dt,3.14); - return fract(sin(sn) * c); -} - -vec2 hammersley2d(uint i, uint N) -{ - // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html - uint bits = (i << 16u) | (i >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - float rdi = float(bits) * 2.3283064365386963e-10; - return vec2(float(i) /float(N), rdi); -} - -// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf -vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) -{ - // Maps a 2D point to a hemisphere with spread based on roughness - float alpha = roughness * roughness; - float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; - float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); - float sinTheta = sqrt(1.0 - cosTheta * cosTheta); - vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); - - // Tangent space - vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); - vec3 tangentX = normalize(cross(up, normal)); - vec3 tangentY = normalize(cross(normal, tangentX)); - - // Convert to world Space - return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); -} - -// Geometric Shadowing function -float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) -{ - float k = (roughness * roughness) / 2.0; - float GL = dotNL / (dotNL * (1.0 - k) + k); - float GV = dotNV / (dotNV * (1.0 - k) + k); - return GL * GV; -} - -vec2 BRDF(float NoV, float roughness) -{ - // Normal always points along z-axis for the 2D lookup - const vec3 N = vec3(0.0, 0.0, 1.0); - vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV); - - vec2 LUT = vec2(0.0); - for(uint i = 0u; i < NUM_SAMPLES; i++) { - vec2 Xi = hammersley2d(i, NUM_SAMPLES); - vec3 H = importanceSample_GGX(Xi, roughness, N); - vec3 L = 2.0 * dot(V, H) * H - V; - - float dotNL = max(dot(N, L), 0.0); - float dotNV = max(dot(N, V), 0.0); - float dotVH = max(dot(V, H), 0.0); - float dotNH = max(dot(H, N), 0.0); - - if (dotNL > 0.0) { - float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); - float G_Vis = (G * dotVH) / (dotNH * dotNV); - float Fc = pow(1.0 - dotVH, 5.0); - LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis); - } - } - return LUT / float(NUM_SAMPLES); -} - -void main() -{ - outColor = vec4(BRDF(inUV.s, 1.0-inUV.t), 0.0, 1.0); -} \ No newline at end of file diff --git a/samples/pbr/shaders/genbrdflut.vert b/samples/pbr/shaders/genbrdflut.vert deleted file mode 100644 index f3dd233..0000000 --- a/samples/pbr/shaders/genbrdflut.vert +++ /dev/null @@ -1,9 +0,0 @@ -#version 450 - -layout (location = 0) out vec2 outUV; - -void main() -{ - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(outUV * 2.0f - 1.0f, 0.0f, 1.0f); -} \ No newline at end of file diff --git a/samples/pbr/shaders/irradiancecube.frag b/samples/pbr/shaders/irradiancecube.frag deleted file mode 100644 index 340d679..0000000 --- a/samples/pbr/shaders/irradiancecube.frag +++ /dev/null @@ -1,37 +0,0 @@ -// Generates an irradiance cube from an environment map using convolution - -#version 450 - -layout (location = 0) in vec3 inPos; -layout (location = 0) out vec4 outColor; -layout (binding = 0) uniform samplerCube samplerEnv; - -layout(push_constant) uniform PushConsts { - layout (offset = 64) float deltaPhi; - layout (offset = 68) float deltaTheta; -} consts; - -#define PI 3.1415926535897932384626433832795 - -void main() -{ - vec3 N = normalize(inPos); - vec3 up = vec3(0.0, 1.0, 0.0); - vec3 right = normalize(cross(up, N)); - up = cross(N, right); - - const float TWO_PI = PI * 2.0; - const float HALF_PI = PI * 0.5; - - vec3 color = vec3(0.0); - uint sampleCount = 0u; - for (float phi = 0.0; phi < TWO_PI; phi += consts.deltaPhi) { - for (float theta = 0.0; theta < HALF_PI; theta += consts.deltaTheta) { - vec3 tempVec = cos(phi) * right + sin(phi) * up; - vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec; - color += texture(samplerEnv, sampleVector).rgb * cos(theta) * sin(theta); - sampleCount++; - } - } - outColor = vec4(PI * color / float(sampleCount), 1.0);//texture(samplerEnv, inPos).rgba; -} diff --git a/samples/pbr/shaders/pbr_khr.frag b/samples/pbr/shaders/pbr_khr.frag index 6992f26..6b13393 100644 --- a/samples/pbr/shaders/pbr_khr.frag +++ b/samples/pbr/shaders/pbr_khr.frag @@ -2,12 +2,12 @@ // See https://github.com/KhronosGroup/glTF-WebGL-PBR // Supports both metallic roughness and specular glossiness inputs -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable +#include "preamble.inc" #define MANUAL_SRGB 0 +#include "tonemap.inc" + struct Material { vec4 baseColorFactor; vec4 emissiveFactor; @@ -23,6 +23,12 @@ struct Material { int pad0; }; +const float M_PI = 3.141592653589793; +const float c_MinRoughness = 0.04; + +const float PBR_WORKFLOW_METALLIC_ROUGHNESS = 1.0; +const float PBR_WORKFLOW_SPECULAR_GLOSINESS = 2.0f; + const uint MAP_COLOR = 0x1; const uint MAP_NORMAL = 0x2; const uint MAP_AO = 0x4; @@ -50,7 +56,7 @@ layout (set = 0, binding = 0) uniform UBO { float debugViewInputs; float debugViewEquation; #endif -} ubo; +}; layout (set = 0, binding = 4) uniform UBOMaterials { Material materials[16]; @@ -76,65 +82,7 @@ layout (push_constant) uniform PushCsts { layout (location = 0) out vec4 outColor; -// Encapsulate the various inputs used by the various functions in the shading equation -// We store values in this struct to simplify the integration of alternative implementations -// of the shading terms, outlined in the Readme.MD Appendix. -struct PBRInfo -{ - float NdotL; // cos angle between normal and light direction - float NdotV; // cos angle between normal and view direction - float NdotH; // cos angle between normal and half vector - float LdotH; // cos angle between light direction and half vector - float VdotH; // cos angle between view direction and half vector - float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) - float metalness; // metallic value at the surface - vec3 reflectance0; // full reflectance color (normal incidence angle) - vec3 reflectance90; // reflectance color at grazing angle - float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) - vec3 diffuseColor; // color contribution from diffuse lighting - vec3 specularColor; // color contribution from specular lighting -}; - -const float M_PI = 3.141592653589793; -const float c_MinRoughness = 0.04; - -const float PBR_WORKFLOW_METALLIC_ROUGHNESS = 1.0; -const float PBR_WORKFLOW_SPECULAR_GLOSINESS = 2.0f; - -vec3 Uncharted2Tonemap(vec3 color) -{ - float A = 0.15; - float B = 0.50; - float C = 0.10; - float D = 0.20; - float E = 0.02; - float F = 0.30; - float W = 11.2; - return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; -} - -vec4 tonemap(vec4 color) -{ - vec3 outcol = Uncharted2Tonemap(color.rgb * ubo.exposure); - outcol = outcol * (1.0f / Uncharted2Tonemap(vec3(11.2f))); - return vec4(pow(outcol, vec3(1.0f / ubo.gamma)), color.a); -} - -vec4 SRGBtoLINEAR(vec4 srgbIn) -{ - #ifdef MANUAL_SRGB - #ifdef SRGB_FAST_APPROXIMATION - vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); - #else //SRGB_FAST_APPROXIMATION - vec3 bLess = step(vec3(0.04045),srgbIn.xyz); - vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); - #endif //SRGB_FAST_APPROXIMATION - return vec4(linOut,srgbIn.w);; - #else //MANUAL_SRGB - return srgbIn; - #endif //MANUAL_SRGB -} - +#include "pbr.inc" // Find the normal for this fragment, pulling either from a predefined normal map // or from the interpolated mesh normal and tangent attributes. vec3 getNormal() @@ -166,77 +114,26 @@ vec3 getNormal() // See our README.md on Environment Maps [3] for additional discussion. vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection) { - float lod = (pbrInputs.perceptualRoughness * ubo.prefilteredCubeMipLevels); + float lod = (pbrInputs.perceptualRoughness * prefilteredCubeMipLevels); // retrieve a scale and bias to F0. See [1], Figure 3 vec3 brdf = (texture(samplerBRDFLUT, vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb; - vec3 diffuseLight = SRGBtoLINEAR(tonemap(texture(samplerIrradiance, n))).rgb; + + vec3 diffuseLight = SRGBtoLINEAR(tonemap(texture(samplerIrradiance, n), exposure, gamma)).rgb; + vec3 specularLight = SRGBtoLINEAR(tonemap(textureLod(prefilteredMap, reflection, lod), exposure, gamma)).rgb; + //vec3 diffuseLight = texture(samplerIrradiance, n).rgb; + //vec3 specularLight = textureLod(prefilteredMap, reflection, lod).rgb; - vec3 specularLight = SRGBtoLINEAR(tonemap(textureLod(prefilteredMap, reflection, lod))).rgb; vec3 diffuse = diffuseLight * pbrInputs.diffuseColor; vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y); // For presentation, this allows us to disable IBL terms - diffuse *= ubo.scaleIBLAmbient; - specular *= ubo.scaleIBLAmbient; + diffuse *= scaleIBLAmbient; + specular *= scaleIBLAmbient; return diffuse + specular; } -// Basic Lambertian diffuse -// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog -// See also [1], Equation 1 -vec3 diffuse(PBRInfo pbrInputs) -{ - return pbrInputs.diffuseColor / M_PI; -} - -// The following equation models the Fresnel reflectance term of the spec equation (aka F()) -// Implementation of fresnel from [4], Equation 15 -vec3 specularReflection(PBRInfo pbrInputs) -{ - return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); -} - -// This calculates the specular geometric attenuation (aka G()), -// where rougher material will reflect less light back to the viewer. -// This implementation is based on [1] Equation 4, and we adopt their modifications to -// alphaRoughness as input as originally proposed in [2]. -float geometricOcclusion(PBRInfo pbrInputs) -{ - float NdotL = pbrInputs.NdotL; - float NdotV = pbrInputs.NdotV; - float r = pbrInputs.alphaRoughness; - - float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); - float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); - return attenuationL * attenuationV; -} - -// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) -// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz -// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. -float microfacetDistribution(PBRInfo pbrInputs) -{ - float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; - float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; - return roughnessSq / (M_PI * f * f); -} - -// Gets metallic factor from specular glossiness workflow inputs -float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { - float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); - float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); - if (perceivedSpecular < c_MinRoughness) { - return 0.0; - } - float a = c_MinRoughness; - float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; - float c = c_MinRoughness - perceivedSpecular; - float D = max(b * b - 4.0 * a * c, 0.0); - return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); -} - void main() { float perceptualRoughness; @@ -317,8 +214,8 @@ void main() vec3 specularEnvironmentR90 = vec3(1.0) * reflectance90; vec3 n = getNormal(); - vec3 v = normalize(ubo.camPos.xyz - inWorldPos); // Vector from surface point to camera - vec3 l = normalize(ubo.lightDir.xyz); // Vector from surface point to light + vec3 v = normalize(camPos.xyz - inWorldPos); // Vector from surface point to camera + vec3 l = normalize(lightDir.xyz); // Vector from surface point to light vec3 h = normalize(l+v); // Half vector between both l and v vec3 reflection = -normalize(reflect(v, n)); reflection.y *= -1.0f; @@ -374,11 +271,12 @@ void main() else if ((materials[materialIdx].tex1 & MAP_EMISSIVE) == MAP_EMISSIVE) color += SRGBtoLINEAR(texture(emissiveMap, inUV1)).rgb * u_EmissiveFactor; - outColor = vec4(color, baseColor.a); + //outColor = vec4(color, baseColor.a); + outColor = tonemap(vec4(color, baseColor.a), exposure, gamma); #ifdef DEBUG // Shader inputs debug visualization - if (ubo.debugViewInputs > 0.0) { - int index = int(ubo.debugViewInputs); + if (debugViewInputs > 0.0) { + int index = int(debugViewInputs); switch (index) { case 1: if ((materials[materialIdx].tex0 & MAP_COLOR) == MAP_COLOR) @@ -429,13 +327,13 @@ void main() outColor.rgb = vec3(0); break; } - outColor = SRGBtoLINEAR(outColor); + //outColor = SRGBtoLINEAR(outColor); } // PBR equation debug visualization // "none", "Diff (l,n)", "F (l,h)", "G (l,v,h)", "D (h)", "Specular" - if (ubo.debugViewEquation > 0.0) { - int index = int(ubo.debugViewEquation); + if (debugViewEquation > 0.0) { + int index = int(debugViewEquation); switch (index) { case 1: outColor.rgb = diffuseContrib; diff --git a/samples/pbr/shaders/prefilterenvmap.frag b/samples/pbr/shaders/prefilterenvmap.frag deleted file mode 100644 index ae1212e..0000000 --- a/samples/pbr/shaders/prefilterenvmap.frag +++ /dev/null @@ -1,105 +0,0 @@ -#version 450 - -layout (location = 0) in vec3 inPos; -layout (location = 0) out vec4 outColor; - -layout (binding = 0) uniform samplerCube samplerEnv; - -layout(push_constant) uniform PushConsts { - layout (offset = 64) float roughness; - layout (offset = 68) uint numSamples; -} consts; - -const float PI = 3.1415926536; - -// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ -float random(vec2 co) -{ - float a = 12.9898; - float b = 78.233; - float c = 43758.5453; - float dt= dot(co.xy ,vec2(a,b)); - float sn= mod(dt,3.14); - return fract(sin(sn) * c); -} - -vec2 hammersley2d(uint i, uint N) -{ - // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html - uint bits = (i << 16u) | (i >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - float rdi = float(bits) * 2.3283064365386963e-10; - return vec2(float(i) /float(N), rdi); -} - -// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf -vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) -{ - // Maps a 2D point to a hemisphere with spread based on roughness - float alpha = roughness * roughness; - float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; - float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); - float sinTheta = sqrt(1.0 - cosTheta * cosTheta); - vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); - - // Tangent space - vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); - vec3 tangentX = normalize(cross(up, normal)); - vec3 tangentY = normalize(cross(normal, tangentX)); - - // Convert to world Space - return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); -} - -// Normal Distribution function -float D_GGX(float dotNH, float roughness) -{ - float alpha = roughness * roughness; - float alpha2 = alpha * alpha; - float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; - return (alpha2)/(PI * denom*denom); -} - -vec3 prefilterEnvMap(vec3 R, float roughness) -{ - vec3 N = R; - vec3 V = R; - vec3 color = vec3(0.0); - float totalWeight = 0.0; - float envMapDim = float(textureSize(samplerEnv, 0).s); - for(uint i = 0u; i < consts.numSamples; i++) { - vec2 Xi = hammersley2d(i, consts.numSamples); - vec3 H = importanceSample_GGX(Xi, roughness, N); - vec3 L = 2.0 * dot(V, H) * H - V; - float dotNL = clamp(dot(N, L), 0.0, 1.0); - if(dotNL > 0.0) { - // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ - - float dotNH = clamp(dot(N, H), 0.0, 1.0); - float dotVH = clamp(dot(V, H), 0.0, 1.0); - - // Probability Distribution Function - float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; - // Slid angle of current smple - float omegaS = 1.0 / (float(consts.numSamples) * pdf); - // Solid angle of 1 pixel across all cube faces - float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); - // Biased (+1.0) mip level for better result - float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); - color += textureLod(samplerEnv, L, mipLevel).rgb * dotNL; - totalWeight += dotNL; - - } - } - return (color / totalWeight); -} - - -void main() -{ - vec3 N = normalize(inPos); - outColor = vec4(prefilterEnvMap(N, consts.roughness), 1.0); -} diff --git a/samples/pbr/shaders/skybox.frag b/samples/pbr/shaders/skybox.frag deleted file mode 100644 index 57a7dbe..0000000 --- a/samples/pbr/shaders/skybox.frag +++ /dev/null @@ -1,60 +0,0 @@ -#version 450 - -layout (binding = 2) uniform samplerCube samplerEnv; - -layout (set = 0, location = 0) in vec3 inUVW; - -layout (set = 0, location = 0) out vec4 outColor; - -layout (set = 0, binding = 0) uniform UBO { - mat4 projection; - mat4 model; - mat4 view; - vec3 camPos; - vec4 lightDir; - float exposure; - float gamma; -} ubo; - -// From http://filmicworlds.com/blog/filmic-tonemapping-operators/ -vec3 Uncharted2Tonemap(vec3 color) -{ - float A = 0.15; - float B = 0.50; - float C = 0.10; - float D = 0.20; - float E = 0.02; - float F = 0.30; - float W = 11.2; - return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; -} - -vec4 tonemap(vec4 color) -{ - vec3 outcol = Uncharted2Tonemap(color.rgb * ubo.exposure); - outcol = outcol * (1.0f / Uncharted2Tonemap(vec3(11.2f))); - return vec4(pow(outcol, vec3(1.0f / ubo.gamma)), color.a); -} - -#define MANUAL_SRGB 1 - -vec4 SRGBtoLINEAR(vec4 srgbIn) -{ - #ifdef MANUAL_SRGB - #ifdef SRGB_FAST_APPROXIMATION - vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); - #else //SRGB_FAST_APPROXIMATION - vec3 bLess = step(vec3(0.04045),srgbIn.xyz); - vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); - #endif //SRGB_FAST_APPROXIMATION - return vec4(linOut,srgbIn.w);; - #else //MANUAL_SRGB - return srgbIn; - #endif //MANUAL_SRGB -} - -void main() -{ - vec3 color = SRGBtoLINEAR(tonemap(textureLod(samplerEnv, inUVW, 1.5))).rgb; - outColor = vec4(color * 1.0, 1.0); -} \ No newline at end of file diff --git a/samples/pbr/shaders/skybox.vert b/samples/pbr/shaders/skybox.vert deleted file mode 100644 index 22e285e..0000000 --- a/samples/pbr/shaders/skybox.vert +++ /dev/null @@ -1,27 +0,0 @@ -#version 450 - -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable - -layout (location = 0) in vec3 inPos; - -layout (binding = 0) uniform UBO -{ - mat4 projection; - mat4 model; - mat4 view; -} ubo; - -layout (location = 0) out vec3 outUVW; - -out gl_PerVertex -{ - vec4 gl_Position; -}; - -void main() -{ - outUVW = inPos; - outUVW.y = -outUVW.y; - gl_Position = ubo.projection * mat4(mat3(ubo.view)) * vec4(inPos, 1.0); -} diff --git a/samples/voxels/Program.cs b/samples/voxels/Program.cs new file mode 100644 index 0000000..8916931 --- /dev/null +++ b/samples/voxels/Program.cs @@ -0,0 +1,10 @@ +using System; + +namespace voxels { + class Program { + static void Main (string [] args) + { + Console.WriteLine ("Hello World!"); + } + } +} diff --git a/samples/voxels/SimpleModel.cs b/samples/voxels/SimpleModel.cs new file mode 100644 index 0000000..69986b2 --- /dev/null +++ b/samples/voxels/SimpleModel.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2019 Jean-Philippe Bruyère jp_bruyere@hotmail.com +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +namespace voxels { + public class SimpleModel { + public SimpleModel () + { + } + } +} diff --git a/samples/voxels/VkCrowWindow.cs b/samples/voxels/VkCrowWindow.cs new file mode 100644 index 0000000..770d6cb --- /dev/null +++ b/samples/voxels/VkCrowWindow.cs @@ -0,0 +1,204 @@ +// Copyright (c) 2019 Jean-Philippe Bruyère +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +using System.Numerics; +using System.Runtime.InteropServices; +using Crow; +using Glfw; +using vke; +using Vulkan; + +namespace vke { + public class VkCrowWindow : VkWindow, Crow.IBackend, Crow.IValueChange { + #region IValueChange implementation + public event EventHandler ValueChanged; + public virtual void NotifyValueChanged (string MemberName, object _value) + { + ValueChanged?.Invoke (this, new Crow.ValueChangeEventArgs (MemberName, _value)); + } + #endregion + + public Image uiImage; + protected Crow.Interface iFace; + public bool MouseIsInInterface => + iFace.HoverWidget != null; + public Device Dev => dev; + public CommandPool CmdPool => cmdPool; + public Queue GraphicQueue => presentQueue; + + protected DescriptorSetWrites uiImageUpdate; + public static VkCrowWindow CurWin; + + protected VkCrowWindow () : base () + { + CurWin = this; + } + + protected void CreateInterface () { + iFace = new Crow.Interface ((int)Width, (int)Height, this); + iFace.Init (); + } + + public override void Update () + { + NotifyValueChanged ("fps", fps); + iFace.Update (); + } + + protected override void onMouseMove (double xPos, double yPos) + { + iFace.OnMouseMove ((int)xPos, (int)yPos); + } + protected override void onMouseButtonDown (Glfw.MouseButton button) + { + iFace.OnMouseButtonDown ((Crow.MouseButton)button); + } + protected override void onMouseButtonUp (Glfw.MouseButton button) + { + iFace.OnMouseButtonUp ((Crow.MouseButton)button); + } + protected override void onScroll (double xOffset, double yOffset) + { + if (KeyModifiers.HasFlag (Modifier.Shift)) + iFace.OnMouseWheelChanged ((float)xOffset); + else + iFace.OnMouseWheelChanged ((float)yOffset); + } + protected override void onKeyDown (Glfw.Key key, int scanCode, Modifier modifiers) + { + iFace.OnKeyDown ((Crow.Key)key); + } + protected override void onKeyUp (Glfw.Key key, int scanCode, Modifier modifiers) + { + iFace.OnKeyUp ((Crow.Key)key); + } + + protected override void OnResize () + { + base.OnResize (); + + iFace.ProcessResize (new Crow.Rectangle (0, 0, (int)Width, (int)Height)); + initUISurface (); + } + + protected override void Dispose (bool disposing) + { + dev.WaitIdle (); + uiImage?.Dispose (); + iFace.Dispose (); + base.Dispose (disposing); + } + + + void initUISurface () + { + iFace.surf?.Dispose (); + uiImage?.Dispose (); + + uiImage = new Image (dev, VkFormat.B8g8r8a8Srgb, VkImageUsageFlags.Sampled, + VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, Width, Height, VkImageType.Image2D, + VkSampleCountFlags.SampleCount1, VkImageTiling.Linear); + uiImage.CreateView (VkImageViewType.ImageView2D, VkImageAspectFlags.Color); + uiImage.CreateSampler (VkFilter.Nearest, VkFilter.Nearest, VkSamplerMipmapMode.Nearest, VkSamplerAddressMode.ClampToBorder); + uiImage.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; + uiImage.Map (); + + NotifyValueChanged ("uiImage", uiImage); + + uiImageUpdate?.Write (dev, uiImage.Descriptor); + + iFace.surf = new Crow.Cairo.ImageSurface (uiImage.MappedData, Crow.Cairo.Format.ARGB32, + (int)Width, (int)Height, (int)uiImage.GetSubresourceLayout ().rowPitch); + + CommandBuffer cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit); + uiImage.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.ShaderReadOnlyOptimal); + presentQueue.EndSubmitAndWait (cmd, true); + } + + public Widget loadWindow (string path, object dataSource = null) { + try { + Widget w = iFace.FindByName (path); + if (w != null) { + iFace.PutOnTop (w); + return w; + } + w = iFace.Load (path); + w.Name = path; + w.DataSource = dataSource; + return w; + + } catch (Exception ex) { + System.Diagnostics.Debug.WriteLine (ex.ToString ()); + } + return null; + } + public void closeWindow (string path) { + Widget g = iFace.FindByName (path); + if (g != null) + iFace.DeleteWidget (g); + } + + #region Crow.IBackend implementation + public void Init (Crow.Interface iFace) + { + initUISurface (); + } + + public void CleanUp () + { + uiImage?.Dispose (); + } + + public void Flush () + { + //throw new NotImplementedException (); + } + + public void ProcessEvents () + { + //throw new NotImplementedException (); + } + + public bool IsDown (Crow.Key key) + { + throw new NotImplementedException (); + } + + public bool Shift => false;// throw new NotImplementedException (); + + public bool Ctrl => false;//throw new NotImplementedException (); + + public bool Alt => false;// throw new NotImplementedException (); + + Crow.MouseCursor Crow.IBackend.Cursor { + set { + CursorShape cs = CursorShape.Arrow; + + switch (value) { + case MouseCursor.IBeam: + cs = CursorShape.IBeam; + break; + case MouseCursor.Crosshair: + cs = CursorShape.Crosshair; + break; + case MouseCursor.Hand: + cs = CursorShape.Hand; + break; + case MouseCursor.H: + case MouseCursor.Right: + case MouseCursor.Left: + cs = CursorShape.HResize; + break; + case MouseCursor.V: + case MouseCursor.Top: + case MouseCursor.Bottom: + cs = CursorShape.VResize; + break; + } + SetCursor (cs); + } + } + #endregion + } +} diff --git a/samples/voxels/Voxelization.cs b/samples/voxels/Voxelization.cs new file mode 100644 index 0000000..0b53ef6 --- /dev/null +++ b/samples/voxels/Voxelization.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2019 Jean-Philippe Bruyère jp_bruyere@hotmail.com +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +namespace voxels { + public class Voxelization { + public Voxelization () + { + } + } +} diff --git a/samples/voxels/shaders/constants.inc b/samples/voxels/shaders/constants.inc new file mode 100644 index 0000000..cda8c38 --- /dev/null +++ b/samples/voxels/shaders/constants.inc @@ -0,0 +1,10 @@ +using System; +namespace voxels.shaders +{ + public class constants + { + public constants() + { + } + } +} diff --git a/samples/voxels/shaders/voxel_visu.frag b/samples/voxels/shaders/voxel_visu.frag new file mode 100644 index 0000000..a9c3a26 --- /dev/null +++ b/samples/voxels/shaders/voxel_visu.frag @@ -0,0 +1,26 @@ +#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 (set = 1, binding = 3, rgba8) uniform image3D vxTex3d; + +layout (location = 0) in vec3 worldPositionFrag; +layout (location = 1) in vec3 normalFrag; + +vec3 scaleAndBias(vec3 p) { return 0.5f * p + vec3(0.5f); } + +bool isInsideCube(const vec3 p, float e) { return abs(p.x) < 1 + e && abs(p.y) < 1 + e && abs(p.z) < 1 + e; } + +void main() +{ + if(!isInsideCube(worldPositionFrag, 0)) return; + + vec3 voxel = scaleAndBias (worldPositionFrag); + ivec3 dim = imageSize (vxTex3d); + + imageStore(vxTex3d, ivec3(dim * voxel), vec4(1,0,0,1)); +} diff --git a/samples/voxels/shaders/voxel_visu.vert b/samples/voxels/shaders/voxel_visu.vert new file mode 100644 index 0000000..6ebf298 --- /dev/null +++ b/samples/voxels/shaders/voxel_visu.vert @@ -0,0 +1,34 @@ +#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 vec3 pos; +layout (location = 1) out vec3 outN; + + +layout(push_constant) uniform PushConsts { + mat4 model; +} pc; + +vec3 light = vec3(2.0,2.0,-2.0); + +void main() +{ + mat4 mod = ubo.modelMatrix;// * pc.model; + pos = (mod * vec4(inPos.xyz, 1.0)).xyz; + + //gl_Position = pos; + outN = mat3(mod)* inNormal; +} diff --git a/samples/voxels/shaders/voxelizer.frag b/samples/voxels/shaders/voxelizer.frag new file mode 100644 index 0000000..a9c3a26 --- /dev/null +++ b/samples/voxels/shaders/voxelizer.frag @@ -0,0 +1,26 @@ +#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 (set = 1, binding = 3, rgba8) uniform image3D vxTex3d; + +layout (location = 0) in vec3 worldPositionFrag; +layout (location = 1) in vec3 normalFrag; + +vec3 scaleAndBias(vec3 p) { return 0.5f * p + vec3(0.5f); } + +bool isInsideCube(const vec3 p, float e) { return abs(p.x) < 1 + e && abs(p.y) < 1 + e && abs(p.z) < 1 + e; } + +void main() +{ + if(!isInsideCube(worldPositionFrag, 0)) return; + + vec3 voxel = scaleAndBias (worldPositionFrag); + ivec3 dim = imageSize (vxTex3d); + + imageStore(vxTex3d, ivec3(dim * voxel), vec4(1,0,0,1)); +} diff --git a/samples/voxels/shaders/voxelizer.vert b/samples/voxels/shaders/voxelizer.vert new file mode 100644 index 0000000..6ebf298 --- /dev/null +++ b/samples/voxels/shaders/voxelizer.vert @@ -0,0 +1,34 @@ +#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 vec3 pos; +layout (location = 1) out vec3 outN; + + +layout(push_constant) uniform PushConsts { + mat4 model; +} pc; + +vec3 light = vec3(2.0,2.0,-2.0); + +void main() +{ + mat4 mod = ubo.modelMatrix;// * pc.model; + pos = (mod * vec4(inPos.xyz, 1.0)).xyz; + + //gl_Position = pos; + outN = mat3(mod)* inNormal; +} diff --git a/samples/voxels/voxels.csproj b/samples/voxels/voxels.csproj new file mode 100644 index 0000000..21dff5c --- /dev/null +++ b/samples/voxels/voxels.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp2.2 + + + diff --git a/vke.net.sln b/vke.net.sln index 2193466..498c316 100644 --- a/vke.net.sln +++ b/vke.net.sln @@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle", "samples\Triangl EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpirVTasks", "SpirVTasks\SpirVTasks.csproj", "{7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvironmentPipeline", "addons\EnvironmentPipeline\EnvironmentPipeline.csproj", "{F04C3F79-2E08-4D35-A804-43039DCB7F5E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,7 +47,6 @@ Global {642726F4-0592-4846-8EAF-A5D1964C85A7}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {642726F4-0592-4846-8EAF-A5D1964C85A7}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Debug|Any CPU.Build.0 = Debug|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|Any CPU.ActiveCfg = Release|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.Release|Any CPU.Build.0 = Release|Any CPU {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU @@ -57,65 +58,65 @@ Global {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {F3BBF67D-7E63-48F3-8156-ADC014D268BB}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {611541A0-CE88-4A83-A6FF-3917971841C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {611541A0-CE88-4A83-A6FF-3917971841C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {611541A0-CE88-4A83-A6FF-3917971841C9}.Release|Any CPU.ActiveCfg = Release|Any CPU {611541A0-CE88-4A83-A6FF-3917971841C9}.Release|Any CPU.Build.0 = Release|Any CPU {611541A0-CE88-4A83-A6FF-3917971841C9}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {611541A0-CE88-4A83-A6FF-3917971841C9}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU + {611541A0-CE88-4A83-A6FF-3917971841C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Debug|Any CPU.Build.0 = Debug|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|Any CPU.ActiveCfg = Release|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.Release|Any CPU.Build.0 = Release|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {7E10A906-8633-48E5-8FEF-94F84CD8844C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7E10A906-8633-48E5-8FEF-94F84CD8844C}.Debug|Any CPU.Build.0 = Debug|Any CPU {7E10A906-8633-48E5-8FEF-94F84CD8844C}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E10A906-8633-48E5-8FEF-94F84CD8844C}.Release|Any CPU.Build.0 = Release|Any CPU {7E10A906-8633-48E5-8FEF-94F84CD8844C}.DebugCrow|Any CPU.ActiveCfg = DebugCrow|Any CPU {7E10A906-8633-48E5-8FEF-94F84CD8844C}.DebugCrow|Any CPU.Build.0 = DebugCrow|Any CPU + {7E10A906-8633-48E5-8FEF-94F84CD8844C}.Debug|Any CPU.Build.0 = Debug|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77437C6D-28B5-4798-96CA-68F987770D65}.Debug|Any CPU.Build.0 = Debug|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Release|Any CPU.ActiveCfg = Release|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.Release|Any CPU.Build.0 = Release|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {77437C6D-28B5-4798-96CA-68F987770D65}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}.Release|Any CPU.Build.0 = Release|Any CPU {A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {96921211-C5A8-41FC-9F3D-F35A696203F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {96921211-C5A8-41FC-9F3D-F35A696203F7}.Debug|Any CPU.Build.0 = Debug|Any CPU {96921211-C5A8-41FC-9F3D-F35A696203F7}.Release|Any CPU.ActiveCfg = Release|Any CPU {96921211-C5A8-41FC-9F3D-F35A696203F7}.Release|Any CPU.Build.0 = Release|Any CPU {96921211-C5A8-41FC-9F3D-F35A696203F7}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {96921211-C5A8-41FC-9F3D-F35A696203F7}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU + {96921211-C5A8-41FC-9F3D-F35A696203F7}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1B2DF710-E500-49E5-8802-EBA71A05E827}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.Release|Any CPU.Build.0 = Release|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {1B2DF710-E500-49E5-8802-EBA71A05E827}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8185163E-A67C-4C0E-8548-67E2A9F16309}.Debug|Any CPU.Build.0 = Debug|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|Any CPU.ActiveCfg = Release|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.Release|Any CPU.Build.0 = Release|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {8185163E-A67C-4C0E-8548-67E2A9F16309}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {A30AEC45-54A3-4120-B341-B3299CC1B00E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A30AEC45-54A3-4120-B341-B3299CC1B00E}.Debug|Any CPU.Build.0 = Debug|Any CPU {A30AEC45-54A3-4120-B341-B3299CC1B00E}.Release|Any CPU.ActiveCfg = Release|Any CPU {A30AEC45-54A3-4120-B341-B3299CC1B00E}.Release|Any CPU.Build.0 = Release|Any CPU {A30AEC45-54A3-4120-B341-B3299CC1B00E}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {A30AEC45-54A3-4120-B341-B3299CC1B00E}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU + {A30AEC45-54A3-4120-B341-B3299CC1B00E}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.Release|Any CPU.Build.0 = Release|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU {7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.Release|Any CPU.Build.0 = Release|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU + {F04C3F79-2E08-4D35-A804-43039DCB7F5E}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E} = {4AA67AB0-C331-4CB2-9C00-B74F5DE31658} @@ -129,6 +130,7 @@ Global {1B2DF710-E500-49E5-8802-EBA71A05E827} = {16439374-B8DB-4643-8116-EB3358B49A12} {8185163E-A67C-4C0E-8548-67E2A9F16309} = {16439374-B8DB-4643-8116-EB3358B49A12} {A30AEC45-54A3-4120-B341-B3299CC1B00E} = {16439374-B8DB-4643-8116-EB3358B49A12} + {F04C3F79-2E08-4D35-A804-43039DCB7F5E} = {4AA67AB0-C331-4CB2-9C00-B74F5DE31658} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution Policies = $0 diff --git a/vke/shaders/preamble.inc b/vke/shaders/preamble.inc new file mode 100644 index 0000000..30b29c0 --- /dev/null +++ b/vke/shaders/preamble.inc @@ -0,0 +1,3 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable diff --git a/vke/src/base/CommandBuffer.cs b/vke/src/base/CommandBuffer.cs index 3066f81..126137b 100644 --- a/vke/src/base/CommandBuffer.cs +++ b/vke/src/base/CommandBuffer.cs @@ -117,6 +117,10 @@ namespace vke { public void BindDescriptorSet (VkPipelineBindPoint bindPoint, PipelineLayout pipelineLayout, DescriptorSet descriptorSet, uint firstSet = 0) { vkCmdBindDescriptorSets (handle, bindPoint, pipelineLayout.handle, firstSet, 1, ref descriptorSet.handle, 0, IntPtr.Zero); } + public void BindDescriptorSets (VkPipelineBindPoint bindPoint, PipelineLayout pipelineLayout, uint firstSet,params DescriptorSet[] descriptorSets) { + vkCmdBindDescriptorSets (handle, bindPoint, pipelineLayout.handle, firstSet, (uint)descriptorSets.Length, descriptorSets.Pin (), 0, IntPtr.Zero); + descriptorSets.Unpin (); + } public void BindVertexBuffer (Buffer vertices, uint binding = 0, ulong offset = 0) { vkCmdBindVertexBuffers (handle, binding, 1, ref vertices.handle, ref offset); } diff --git a/vke/src/base/RenderPass.cs b/vke/src/base/RenderPass.cs index 6fba72d..b4de166 100644 --- a/vke/src/base/RenderPass.cs +++ b/vke/src/base/RenderPass.cs @@ -14,11 +14,10 @@ namespace vke { public readonly VkSampleCountFlags Samples; - internal List attachments = new List (); - public List ClearValues = new List (); - internal List subpasses = new List (); + List attachments = new List (); + List subpasses = new List (); List dependencies = new List (); - + public List ClearValues = new List (); public VkAttachmentDescription [] Attachments => attachments.ToArray (); public SubPass [] SubPasses => subpasses.ToArray (); @@ -62,7 +61,7 @@ namespace vke { } /// - /// Create default renderpass with one color and one depth attachments. + /// Create default renderpass with one color, one depth attachments, and a resolve one if needed. /// public RenderPass (Device device, VkFormat colorFormat, VkFormat depthFormat, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1) : this (device){ diff --git a/vke/src/model/ObjMesh.cs b/vke/src/model/ObjMesh.cs index c2944c3..81c75b8 100644 --- a/vke/src/model/ObjMesh.cs +++ b/vke/src/model/ObjMesh.cs @@ -25,12 +25,12 @@ using System.Threading; namespace vke { - public class ObjMesh { + public class ObjMesh { public Model.Vertex[] vertices; - public ushort[] indices; + public T [] indices; public ObjMesh(string path) { - OBJMeshLoader loader = new OBJMeshLoader (path); + OBJMeshLoader loader = new OBJMeshLoader (path); vertices = new Model.Vertex[loader.VertexCount]; for (int i = 0; i < loader.VertexCount; i++) { vertices[i] = new Model.Vertex { -- 2.47.3