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 ();
#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;
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;
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()
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;
--- /dev/null
+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
#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;
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.
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;
-#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;
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].
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)
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].
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;
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;
-#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);
+++ /dev/null
-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);
- }
- }
-
-}
Instance.VALIDATION = true;
Instance.RENDER_DOC_CAPTURE = false;
#endif
+ SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm;
+
using (Program vke = new Program ()) {
vke.Run ();
}
enabled_features.samplerAnisotropy = available_features.samplerAnisotropy;
}
- VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1;
+ VkSampleCountFlags samples = VkSampleCountFlags.SampleCount4;
FrameBuffers frameBuffers;
PBRPipeline pbrPipeline;
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
+++ /dev/null
-#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);
-}
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-// 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;
-}
// 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;
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;
float debugViewInputs;
float debugViewEquation;
#endif
-} ubo;
+};
layout (set = 0, binding = 4) uniform UBOMaterials {
Material materials[16];
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()
// 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;
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;
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)
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;
+++ /dev/null
-#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);
-}
+++ /dev/null
-#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
+++ /dev/null
-#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);
-}
--- /dev/null
+using System;
+
+namespace voxels {
+ class Program {
+ static void Main (string [] args)
+ {
+ Console.WriteLine ("Hello World!");
+ }
+ }
+}
--- /dev/null
+// 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 ()
+ {
+ }
+ }
+}
--- /dev/null
+// 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
+ }
+}
--- /dev/null
+// 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 ()
+ {
+ }
+ }
+}
--- /dev/null
+using System;
+namespace voxels.shaders
+{
+ public class constants
+ {
+ public constants()
+ {
+ }
+ }
+}
--- /dev/null
+#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));
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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));
+}
--- /dev/null
+#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;
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>netcoreapp2.2</TargetFramework>
+ </PropertyGroup>
+
+</Project>
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
{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
{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}
{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
--- /dev/null
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
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);
}
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 ();
}
/// <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){
namespace vke
{
- public class ObjMesh {
+ public class ObjMesh<T> {
public Model.Vertex[] vertices;
- public ushort[] indices;
+ public T [] 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 {