keid-render-basic-0.1.8.0: src/Render/Lit/Material/Code.hs
module Render.Lit.Material.Code
( vert
, frag
) where
import RIO
import Render.Code (Code, glsl)
import Render.Code.Lit (litMain, shadowFuns, structLight, structMaterial, brdfSpecular)
import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5, set0binding6)
vert :: Code
vert = fromString
[glsl|
#version 450
invariant gl_Position;
${set0binding0}
// vertexPos
layout(location = 0) in vec3 vPosition;
// vertexAttrs
layout(location = 1) in vec2 vTexCoord0;
layout(location = 2) in vec2 vTexCoord1;
layout(location = 3) in vec3 vNormal;
layout(location = 4) in vec3 vTangent;
layout(location = 5) in uint vMaterial;
// transformMat
layout(location = 6) in mat4 iModel;
layout(location = 0) out vec4 fPosition;
layout(location = 1) out vec2 fTexCoord0;
layout(location = 2) out vec2 fTexCoord1;
layout(location = 3) flat out uint fMaterial;
layout(location = 4) out mat3 fTBN;
void main() {
fPosition = iModel * vec4(vPosition, 1.0);
gl_Position
= scene.projection
* scene.view
* fPosition;
fTexCoord0 = vTexCoord0;
fTexCoord1 = vTexCoord1;
vec3 t = normalize(vec3(iModel * vec4(vTangent, 0.0)));
vec3 n = normalize(vec3(iModel * vec4(vNormal, 0.0)));
vec3 to = normalize(t - dot(t, n) * n); // re-orthogonalize T with respect to N
fTBN = mat3(to, cross(n, to), n);
fMaterial = vMaterial;
}
|]
frag :: Code
frag = fromString
[glsl|
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
layout(early_fragment_tests) in;
// XXX: copypasta from Lit.Colored
// TODO: move to spec constant
const uint MAX_LIGHTS = 255;
const float PCF_STEP = 1.5 / 4096;
const uint MAX_MATERIALS = 2048;
${structLight}
${structMaterial}
${set0binding0}
${set0binding1}
${set0binding2}
${set0binding3}
${set0binding4} // lights
${set0binding5} // shadowmap
${set0binding6} // materials
layout(location = 0) in vec4 fPosition;
layout(location = 1) in vec2 fTexCoord0;
layout(location = 2) in vec2 fTexCoord1;
layout(location = 3) flat in uint fMaterial;
layout(location = 4) in mat3 fTBN;
layout(location = 0) out vec4 oColor;
${shadowFuns}
${brdfSpecular}
void main() {
Material material = materials[fMaterial];
vec4 baseColor = material.baseColor;
float metallic = material.metallicRoughness[0];
float roughness = material.metallicRoughness[1];
float nonOcclusion = 1.0;
vec4 emissive = material.emissive;
if (material.baseColorTex > -1) {
baseColor *= texture(
sampler2D(
textures[nonuniformEXT(material.baseColorTex)],
samplers[0]
),
fTexCoord0
);
}
if (baseColor.a < material.alphaCutoff) {
discard;
}
baseColor.rgb *= baseColor.a;
if (material.metallicRoughnessTex > -1) {
vec3 packed = texture(
sampler2D(
textures[nonuniformEXT(material.metallicRoughnessTex)],
samplers[0]
),
fTexCoord0
).rgb;
// XXX: assuming sRGB textures, even for AMR
packed = pow(packed, vec3(1.0/2.2));
nonOcclusion -= packed.r;
metallic *= packed.b;
roughness *= packed.g;
}
// // TODO: combine with MR as channel R.
// float occlusion = texture(
// sampler2D(
// textures[nonuniformEXT(max(0, material.ambientOcclusionTex))],
// samplers[0]
// ),
// fTexCoord0
// ).r;
// nonOcclusion -= pow(occlusion, 1.0/2.2);
if (material.emissiveTex > -1) {
emissive *= texture(
sampler2D(
textures[nonuniformEXT(material.emissiveTex)],
samplers[0]
),
fTexCoord0
);
}
vec3 normal = fTBN[2];
if (material.normalTex > -1) {
vec3 normalsColor = texture(
sampler2D(
textures[nonuniformEXT(material.normalTex)],
samplers[0]
),
fTexCoord0
).rgb;
// XXX: convert normal non-colors to linear values from sRGB texture colorspace
vec3 normals = pow(normalsColor, vec3(1.0/2.2)) * 2.0 - 1.0;
normal = normalize(fTBN * normals);
} else {
normal = normalize(normal);
}
${litMain}
oColor.rgb += pow(emissive.rgb, vec3(2.2));
}
|]