Skip to content

Commit

Permalink
tessellation, moves widget, smooth animation, wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jpbruyere committed Sep 11, 2021
1 parent 0198478 commit 6035757
Show file tree
Hide file tree
Showing 24 changed files with 994 additions and 547 deletions.
Binary file modified data/chess.blend
Binary file not shown.
50 changes: 28 additions & 22 deletions shaders/GBuffPbrInstanced.vert
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,36 @@ layout (location = 4) in vec4 inColor;
layout (location = 5) in mat4 inModel;

layout (set = 0, binding = 0) uniform UBO {
mat4 projection;
mat4 model;
mat4 view;
mat4 projection;
mat4 model;
mat4 view;
} ubo;

layout (location = 0) out vec3 outWorldPos;
layout (location = 1) out vec3 outNormal;
layout (location = 2) out vec2 outUV0;
layout (location = 3) out vec2 outUV1;
layout (location = 4) out vec4 outColor;
layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec2 outUV0;
layout (location = 2) out vec2 outUV1;
layout (location = 3) out vec4 outColor;

out gl_PerVertex
/*out gl_PerVertex
{
vec4 gl_Position;
};

void main()
{
vec4 locPos = ubo.model * inModel * vec4(inPos, 1.0);
//locPos.y = -locPos.y;
outNormal = normalize(transpose(inverse(mat3(ubo.model * inModel))) * inNormal);
outColor = inColor;
outWorldPos = locPos.xyz;
outUV0 = inUV0;
outUV1 = inUV1;
gl_Position = ubo.projection * ubo.view * vec4(outWorldPos, 1.0);
vec4 gl_Position;
};*/

void main()
{
/*vec4 locPos = ubo.model * inModel * vec4(inPos, 1.0);
outNormal = normalize(transpose(inverse(mat3(ubo.model * inModel))) * inNormal);
outColor = inColor;
outWorldPos = locPos.xyz;
outUV0 = inUV0;
outUV1 = inUV1;
gl_Position = ubo.projection * ubo.view * vec4(outWorldPos, 1.0);*/

outNormal = normalize(transpose(inverse(mat3(ubo.model * inModel))) * inNormal);
outUV0 = inUV0;
outUV1 = inUV1;
outColor = inColor;

gl_Position = ubo.model * inModel * vec4(inPos, 1.0);
}
298 changes: 149 additions & 149 deletions shaders/GBuffPbrTexArray.frag
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ 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;
vec4 diffuseFactor;
vec4 specularFactor;
float workflow;
uint tex0;
uint tex1;
int baseColorTex;
int physicalDescTex;
int normalTex;
int occlusionTex;
int emissiveTex;
float metallicFactor;
float roughnessFactor;
float alphaMask;
float alphaMaskCutoff;
vec4 baseColorFactor;
vec4 emissiveFactor;
vec4 diffuseFactor;
vec4 specularFactor;

float workflow;
uint tex0;
uint tex1;
int baseColorTex;

int physicalDescTex;
int normalTex;
int occlusionTex;
int emissiveTex;

float metallicFactor;
float roughnessFactor;
float alphaMask;
float alphaMaskCutoff;
};
const float M_PI = 3.141592653589793;
const float c_MinRoughness = 0.04;
Expand All @@ -50,13 +50,13 @@ layout (location = 3) in vec2 inUV1;
layout (location = 4) in vec4 inColor;

layout (set = 0, binding = 5) uniform UBOMaterials {
Material materials[MAT_COUNT];
Material materials[MAT_COUNT];
};
layout (set = 0, binding = 7) uniform sampler2DArray texArray;

layout (push_constant) uniform PushCsts {
layout(offset = 64)
int materialIdx;
layout(offset = 64)
int materialIdx;
};


Expand All @@ -67,147 +67,147 @@ 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
#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()
{
vec3 tangentNormal;
// Perturb normal, see http://www.thetenthplanet.de/archives/1180
if ((materials[materialIdx].tex0 & MAP_NORMAL) == MAP_NORMAL)
tangentNormal = texture(texArray, vec3(inUV0, materials[materialIdx].normalTex)).xyz * 2.0 - 1.0;
else if ((materials[materialIdx].tex1 & MAP_NORMAL) == MAP_NORMAL)
tangentNormal = texture(texArray, vec3(inUV1, materials[materialIdx].normalTex)).xyz * 2.0 - 1.0;
else
return normalize(inNormal);
vec3 q1 = dFdx(inWorldPos);
vec3 q2 = dFdy(inWorldPos);
vec2 st1 = dFdx(inUV0);
vec2 st2 = dFdy(inUV0);

vec3 N = normalize(inNormal);
vec3 T = normalize(q1 * st2.t - q2 * st1.t);
vec3 B = -normalize(cross(N, T));
mat3 TBN = mat3(T, B, N);

return normalize(TBN * tangentNormal);
vec3 tangentNormal;
// Perturb normal, see http://www.thetenthplanet.de/archives/1180
if ((materials[materialIdx].tex0 & MAP_NORMAL) == MAP_NORMAL)
tangentNormal = texture(texArray, vec3(inUV0, materials[materialIdx].normalTex)).xyz * 2.0 - 1.0;
else if ((materials[materialIdx].tex1 & MAP_NORMAL) == MAP_NORMAL)
tangentNormal = texture(texArray, vec3(inUV1, materials[materialIdx].normalTex)).xyz * 2.0 - 1.0;
else
return normalize(inNormal);

vec3 q1 = dFdx(inWorldPos);
vec3 q2 = dFdy(inWorldPos);
vec2 st1 = dFdx(inUV0);
vec2 st2 = dFdy(inUV0);

vec3 N = normalize(inNormal);
vec3 T = normalize(q1 * st2.t - q2 * st1.t);
vec3 B = -normalize(cross(N, T));
mat3 TBN = mat3(T, B, N);

return normalize(TBN * tangentNormal);
}

// Gets metallic factor from specular glossiness workflow inputs
// 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 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));
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()
void main()
{
float perceptualRoughness;
float metallic;
vec4 baseColor;
vec3 emissive = vec3(0);
baseColor = materials[materialIdx].baseColorFactor;
if (materials[materialIdx].workflow == PBR_WORKFLOW_METALLIC_ROUGHNESS) {
perceptualRoughness = materials[materialIdx].roughnessFactor;
metallic = materials[materialIdx].metallicFactor;
// Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
// This layout intentionally reserves the 'r' channel for (optional) occlusion map data
if ((materials[materialIdx].tex0 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS){
perceptualRoughness *= texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex)).g;
metallic *= texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex)).b;
}else if ((materials[materialIdx].tex1 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS){
perceptualRoughness *= texture(texArray, vec3(inUV1, materials[materialIdx].physicalDescTex)).g;
metallic *= texture(texArray, vec3(inUV1, materials[materialIdx].physicalDescTex)).b;
}
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
metallic = clamp(metallic, 0.0, 1.0);

// The albedo may be defined from a base texture or a flat color
if ((materials[materialIdx].tex0 & MAP_COLOR) == MAP_COLOR)
baseColor *= SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].baseColorTex)));
else if ((materials[materialIdx].tex1 & MAP_COLOR) == MAP_COLOR)
baseColor *= SRGBtoLINEAR(texture(texArray, vec3(inUV1, materials[materialIdx].baseColorTex)));
}
if (materials[materialIdx].alphaMask == 1.0f) {
if (baseColor.a < materials[materialIdx].alphaMaskCutoff)
discard;
}

if (materials[materialIdx].workflow == PBR_WORKFLOW_SPECULAR_GLOSINESS) {
// Values from specular glossiness workflow are converted to metallic roughness
if ((materials[materialIdx].tex0 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS)
perceptualRoughness = 1.0 - texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex)).a;
else if ((materials[materialIdx].tex1 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS)
perceptualRoughness = 1.0 - texture(texArray, vec3(inUV1, materials[materialIdx].physicalDescTex)).a;
else
perceptualRoughness = 0.0;

const float epsilon = 1e-6;

vec4 diffuse = SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].baseColorTex)));
vec3 specular = SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex))).rgb;

float maxSpecular = max(max(specular.r, specular.g), specular.b);

// Convert metallic value from specular glossiness inputs
metallic = convertMetallic(diffuse.rgb, specular, maxSpecular);

vec3 baseColorDiffusePart = diffuse.rgb * ((1.0 - maxSpecular) / (1 - c_MinRoughness) / max(1 - metallic, epsilon)) * materials[materialIdx].diffuseFactor.rgb;
vec3 baseColorSpecularPart = specular - (vec3(c_MinRoughness) * (1 - metallic) * (1 / max(metallic, epsilon))) * materials[materialIdx].specularFactor.rgb;
baseColor = vec4(mix(baseColorDiffusePart, baseColorSpecularPart, metallic * metallic), diffuse.a);

}
baseColor *= inColor;
const float u_OcclusionStrength = 1.0f;
const float u_EmissiveFactor = 1.0f;
float ao = 1.0f;
if ((materials[materialIdx].tex0 & MAP_EMISSIVE) == MAP_EMISSIVE)
emissive = SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].emissiveTex))).rgb * u_EmissiveFactor;
else if ((materials[materialIdx].tex1 & MAP_EMISSIVE) == MAP_EMISSIVE)
emissive = SRGBtoLINEAR(texture(texArray, vec3(inUV1, materials[materialIdx].emissiveTex))).rgb * u_EmissiveFactor;
if ((materials[materialIdx].tex0 & MAP_AO) == MAP_AO)
ao = texture(texArray, vec3(inUV0, materials[materialIdx].occlusionTex)).r;
else if ((materials[materialIdx].tex1 & MAP_AO) == MAP_AO)
ao = texture(texArray, vec3(inUV1, materials[materialIdx].occlusionTex)).r;
vec3 n = getNormal();
vec3 p = inWorldPos;
outColorRough = vec4 (baseColor.rgb, perceptualRoughness);
outEmitMetal = vec4 (emissive, metallic);
outN_AO = vec4 (n, ao);
outPos = vec4 (p, linearDepth(gl_FragCoord.z));
float perceptualRoughness;
float metallic;
vec4 baseColor;
vec3 emissive = vec3(0);

baseColor = materials[materialIdx].baseColorFactor;

if (materials[materialIdx].workflow == PBR_WORKFLOW_METALLIC_ROUGHNESS) {
perceptualRoughness = materials[materialIdx].roughnessFactor;
metallic = materials[materialIdx].metallicFactor;
// Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
// This layout intentionally reserves the 'r' channel for (optional) occlusion map data
if ((materials[materialIdx].tex0 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS){
perceptualRoughness *= texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex)).g;
metallic *= texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex)).b;
}else if ((materials[materialIdx].tex1 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS){
perceptualRoughness *= texture(texArray, vec3(inUV1, materials[materialIdx].physicalDescTex)).g;
metallic *= texture(texArray, vec3(inUV1, materials[materialIdx].physicalDescTex)).b;
}
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
metallic = clamp(metallic, 0.0, 1.0);

// The albedo may be defined from a base texture or a flat color
if ((materials[materialIdx].tex0 & MAP_COLOR) == MAP_COLOR)
baseColor *= SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].baseColorTex)));
else if ((materials[materialIdx].tex1 & MAP_COLOR) == MAP_COLOR)
baseColor *= SRGBtoLINEAR(texture(texArray, vec3(inUV1, materials[materialIdx].baseColorTex)));
}

if (materials[materialIdx].alphaMask == 1.0f) {
if (baseColor.a < materials[materialIdx].alphaMaskCutoff)
discard;
}

if (materials[materialIdx].workflow == PBR_WORKFLOW_SPECULAR_GLOSINESS) {
// Values from specular glossiness workflow are converted to metallic roughness
if ((materials[materialIdx].tex0 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS)
perceptualRoughness = 1.0 - texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex)).a;
else if ((materials[materialIdx].tex1 & MAP_METALROUGHNESS) == MAP_METALROUGHNESS)
perceptualRoughness = 1.0 - texture(texArray, vec3(inUV1, materials[materialIdx].physicalDescTex)).a;
else
perceptualRoughness = 0.0;

const float epsilon = 1e-6;

vec4 diffuse = SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].baseColorTex)));
vec3 specular = SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].physicalDescTex))).rgb;

float maxSpecular = max(max(specular.r, specular.g), specular.b);

// Convert metallic value from specular glossiness inputs
metallic = convertMetallic(diffuse.rgb, specular, maxSpecular);

vec3 baseColorDiffusePart = diffuse.rgb * ((1.0 - maxSpecular) / (1 - c_MinRoughness) / max(1 - metallic, epsilon)) * materials[materialIdx].diffuseFactor.rgb;
vec3 baseColorSpecularPart = specular - (vec3(c_MinRoughness) * (1 - metallic) * (1 / max(metallic, epsilon))) * materials[materialIdx].specularFactor.rgb;
baseColor = vec4(mix(baseColorDiffusePart, baseColorSpecularPart, metallic * metallic), diffuse.a);

}

baseColor *= inColor;

const float u_OcclusionStrength = 1.0f;
const float u_EmissiveFactor = 1.0f;
float ao = 1.0f;

if ((materials[materialIdx].tex0 & MAP_EMISSIVE) == MAP_EMISSIVE)
emissive = SRGBtoLINEAR(texture(texArray, vec3(inUV0, materials[materialIdx].emissiveTex))).rgb * u_EmissiveFactor;
else if ((materials[materialIdx].tex1 & MAP_EMISSIVE) == MAP_EMISSIVE)
emissive = SRGBtoLINEAR(texture(texArray, vec3(inUV1, materials[materialIdx].emissiveTex))).rgb * u_EmissiveFactor;

if ((materials[materialIdx].tex0 & MAP_AO) == MAP_AO)
ao = texture(texArray, vec3(inUV0, materials[materialIdx].occlusionTex)).r;
else if ((materials[materialIdx].tex1 & MAP_AO) == MAP_AO)
ao = texture(texArray, vec3(inUV1, materials[materialIdx].occlusionTex)).r;

vec3 n = getNormal();
vec3 p = inWorldPos;

outColorRough = vec4 (baseColor.rgb, perceptualRoughness);
outEmitMetal = vec4 (emissive, metallic);
outN_AO = vec4 (n, ao);
outPos = vec4 (p, linearDepth(gl_FragCoord.z));
}
Loading

0 comments on commit 6035757

Please sign in to comment.