]> O.S.I.I.S - jp/vke.net.git/commitdiff
wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 31 Dec 2019 17:44:15 +0000 (18:44 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 31 Dec 2019 17:44:15 +0000 (18:44 +0100)
32 files changed:
samples/Model/main.cs
samples/deferred/shaders/GBuffPbr.frag
samples/deferred/shaders/GBuffPbrCommon.inc [new file with mode: 0644]
samples/deferred/shaders/GBuffPbrTexArray.frag
samples/deferred/shaders/compose.frag
samples/deferred/shaders/compose_with_shadows.frag
samples/deferred/shaders/tone_mapping.frag
samples/pbr/EnvironmentPipeline.cs [deleted file]
samples/pbr/main.cs
samples/pbr/shaders/filtercube.vert [deleted file]
samples/pbr/shaders/genbrdflut.frag [deleted file]
samples/pbr/shaders/genbrdflut.vert [deleted file]
samples/pbr/shaders/irradiancecube.frag [deleted file]
samples/pbr/shaders/pbr_khr.frag
samples/pbr/shaders/prefilterenvmap.frag [deleted file]
samples/pbr/shaders/skybox.frag [deleted file]
samples/pbr/shaders/skybox.vert [deleted file]
samples/voxels/Program.cs [new file with mode: 0644]
samples/voxels/SimpleModel.cs [new file with mode: 0644]
samples/voxels/VkCrowWindow.cs [new file with mode: 0644]
samples/voxels/Voxelization.cs [new file with mode: 0644]
samples/voxels/shaders/constants.inc [new file with mode: 0644]
samples/voxels/shaders/voxel_visu.frag [new file with mode: 0644]
samples/voxels/shaders/voxel_visu.vert [new file with mode: 0644]
samples/voxels/shaders/voxelizer.frag [new file with mode: 0644]
samples/voxels/shaders/voxelizer.vert [new file with mode: 0644]
samples/voxels/voxels.csproj [new file with mode: 0644]
vke.net.sln
vke/shaders/preamble.inc [new file with mode: 0644]
vke/src/base/CommandBuffer.cs
vke/src/base/RenderPass.cs
vke/src/model/ObjMesh.cs

index 05bae06a65b558d35d481c4945ad5b7d4b4178ff..d4ce8648313d78155a3629953c30f1d5fbe85004 100644 (file)
@@ -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 ();
index c6e116068abb6a5b89b3d8436d2b7f6917f754b3..9e30cabc439db8c0286929654ee6db3b8928be4f 100644 (file)
@@ -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 (file)
index 0000000..4146fa5
--- /dev/null
@@ -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
index 3d666d0386ceb52cb998b579209116554b7094eb..cddf49f476c9b3460a343aa10c6e513233b2ad0d 100644 (file)
@@ -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;
index 81312bd9d798df949a77b462cc839c57f887c1f3..e6ab256bedd1e6281774e37429c5864f57c89d97 100644 (file)
@@ -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)
index 42473933be5184c12b5f53e908614587d4b8dea5..68fc8bf25fb21ade696376661a33b577c3e7b705 100644 (file)
@@ -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;
index 6a1a8d428d8737f4b1e15a65908c9fd75e2a8528..138bea8949f21a7950878f5fa542f766eb199cdf 100644 (file)
@@ -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 (file)
index c4f883c..0000000
+++ /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<float> (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<string> cubemapPathes = new List<string>() {
-                       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<Matrix4x4> () + 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<Matrix4x4> ());
-                                                               cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf<Matrix4x4> () + 4);
-                                                       } else {
-                                                               cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, roughness, (uint)Marshal.SizeOf<Matrix4x4> ());
-                                                               cmd.PushConstant (pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 32u, (uint)Marshal.SizeOf<Matrix4x4> () + 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);
-               }
-       }
-
-}
index abb69aef77d69f1802953c7c5b02a3b93e97f57d..94d41850e63b5339f49a0852d161acf9931c4f8c 100644 (file)
@@ -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 (file)
index 34adf73..0000000
+++ /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 (file)
index b6290dd..0000000
+++ /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 (file)
index f3dd233..0000000
+++ /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 (file)
index 340d679..0000000
+++ /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;
-}
index 6992f2666f2093923a822cedb1633a0b5ee6fe45..6b133932d2d5fc26f22337aee9e409d034d8d2d2 100644 (file)
@@ -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 (file)
index ae1212e..0000000
+++ /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 (file)
index 57a7dbe..0000000
+++ /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 (file)
index 22e285e..0000000
+++ /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 (file)
index 0000000..8916931
--- /dev/null
@@ -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 (file)
index 0000000..69986b2
--- /dev/null
@@ -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 (file)
index 0000000..770d6cb
--- /dev/null
@@ -0,0 +1,204 @@
+// 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;
+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<Crow.ValueChangeEventArgs> 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 (file)
index 0000000..0b53ef6
--- /dev/null
@@ -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 (file)
index 0000000..cda8c38
--- /dev/null
@@ -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 (file)
index 0000000..a9c3a26
--- /dev/null
@@ -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 (file)
index 0000000..6ebf298
--- /dev/null
@@ -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 (file)
index 0000000..a9c3a26
--- /dev/null
@@ -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 (file)
index 0000000..6ebf298
--- /dev/null
@@ -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 (file)
index 0000000..21dff5c
--- /dev/null
@@ -0,0 +1,8 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp2.2</TargetFramework>
+  </PropertyGroup>
+
+</Project>
index 21934665de5fa9540cd66a7059ecd84d5c8ecb48..498c316e4829f6bb592832b2d15cdb4375453dbb 100644 (file)
@@ -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 (file)
index 0000000..30b29c0
--- /dev/null
@@ -0,0 +1,3 @@
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
index 3066f812792f8962ec801253d28723660947f12f..126137b476053d193b6a8a1b1388702c9b028d59 100644 (file)
@@ -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);
         }
index 6fba72d4f27c6e0ba00e6e370584b9b954a39368..b4de166ffce7bd3f9add99320d4ec1a38695b146 100644 (file)
@@ -14,11 +14,10 @@ namespace vke {
 
                public readonly VkSampleCountFlags Samples;
 
-        internal List<VkAttachmentDescription> attachments = new List<VkAttachmentDescription> ();
-        public List<VkClearValue> ClearValues = new List<VkClearValue> ();
-        internal List<SubPass> subpasses = new List<SubPass> ();
+        List<VkAttachmentDescription> attachments = new List<VkAttachmentDescription> ();
+        List<SubPass> subpasses = new List<SubPass> ();
         List<VkSubpassDependency> dependencies = new List<VkSubpassDependency> ();
-
+               public List<VkClearValue> ClearValues = new List<VkClearValue> ();
                public VkAttachmentDescription [] Attachments => attachments.ToArray ();
                public SubPass [] SubPasses => subpasses.ToArray ();
 
@@ -62,7 +61,7 @@ namespace vke {
 
                }
         /// <summary>
-        /// 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.
         /// </summary>
         public RenderPass (Device device, VkFormat colorFormat, VkFormat depthFormat, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1)
             : this (device){
index c2944c375f0fd53fbef45eedfacf48d9930dbb41..81c75b8997fcb1e9dc4682228bb66da1939b32bd 100644 (file)
@@ -25,12 +25,12 @@ using System.Threading;
 
 namespace vke
 {
-       public class ObjMesh {
+       public class ObjMesh<T> {
                public Model.Vertex[] vertices;
-               public ushort[] indices;
+               public [] indices;
 
                public ObjMesh(string path) {
-                       OBJMeshLoader<ushort> loader = new OBJMeshLoader<ushort> (path);
+                       OBJMeshLoader<T> loader = new OBJMeshLoader<T> (path);
                        vertices = new Model.Vertex[loader.VertexCount];
                        for (int i = 0; i < loader.VertexCount; i++) {
                                vertices[i] = new Model.Vertex {