193 lines
4.9 KiB
GLSL
193 lines
4.9 KiB
GLSL
|
|
#version 460
|
||
|
|
|
||
|
|
#define M_PI 3.14159265359
|
||
|
|
|
||
|
|
layout(location = 0) in vec2 inUV;
|
||
|
|
|
||
|
|
layout(location = 0) out vec4 outColor;
|
||
|
|
// layout(location = 1) out vec4 outBloomThreshold;
|
||
|
|
|
||
|
|
layout(set = 1, binding = 1) uniform sampler2D inAlbedo;
|
||
|
|
layout(set = 1, binding = 2) uniform sampler2D inNormal;
|
||
|
|
layout(set = 1, binding = 3) uniform sampler2D inPosition;
|
||
|
|
layout(set = 1, binding = 4) uniform sampler2D inPbr;
|
||
|
|
// layout(set = 1, binding = 5) uniform sampler2D shadowMap;
|
||
|
|
|
||
|
|
float ggx_normal_distr(float NoH, float roughness) {
|
||
|
|
float a = NoH * roughness;
|
||
|
|
float k = roughness / (1.0 - NoH * NoH + a * a);
|
||
|
|
return k * k * (1.0 / M_PI);
|
||
|
|
}
|
||
|
|
|
||
|
|
vec3 schlick(float VoH, vec3 f0) {
|
||
|
|
return f0 + (vec3(1.0) - f0) * pow(1.0 - VoH, 5.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
float ggx_smith_correlated(float NoV, float NoL, float a) {
|
||
|
|
float a2 = a * a;
|
||
|
|
float GGXL = NoV * sqrt((-NoL * a2 + NoL) * NoL + a2);
|
||
|
|
float GGXV = NoL * sqrt((-NoV * a2 + NoV) * NoV + a2);
|
||
|
|
return 0.5 / (GGXV + GGXL + 0.0001);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
vec3 lambert_diffuse(vec3 albedo) {
|
||
|
|
return albedo / M_PI;
|
||
|
|
}
|
||
|
|
|
||
|
|
layout(set = 0, binding = 0) uniform Camera {
|
||
|
|
mat4 proj;
|
||
|
|
mat4 view;
|
||
|
|
vec4 position;
|
||
|
|
} cam;
|
||
|
|
|
||
|
|
struct Light {
|
||
|
|
mat4 view;
|
||
|
|
vec4 color;
|
||
|
|
vec4 position;
|
||
|
|
};
|
||
|
|
|
||
|
|
layout(set = 1, binding = 0) uniform Lights {
|
||
|
|
Light lights[];
|
||
|
|
} lights;
|
||
|
|
|
||
|
|
#define AMBIENT 0.1
|
||
|
|
|
||
|
|
float linearize_depth(float depth) {
|
||
|
|
float n = 1000.0f;
|
||
|
|
float f = 1.0f;
|
||
|
|
float z = depth;
|
||
|
|
return (2.0 * n) / (f + n - z * (f - n));
|
||
|
|
}
|
||
|
|
|
||
|
|
float textureProj(vec4 shadowCoord, vec2 off) {
|
||
|
|
return 0.0f;
|
||
|
|
/* float shadow = 0.0f;
|
||
|
|
|
||
|
|
float dist = texture( shadowMap, shadowCoord.st + off ).r;
|
||
|
|
if ( shadowCoord.w > 0.0 )
|
||
|
|
{
|
||
|
|
shadow = (dist < shadowCoord.z) ? 1.0f : 0.0f;
|
||
|
|
}
|
||
|
|
return shadow; */
|
||
|
|
}
|
||
|
|
|
||
|
|
float filterPCF(vec4 sc) {
|
||
|
|
return 0.0f;
|
||
|
|
/* ivec2 texDim = textureSize(shadowMap, 0);
|
||
|
|
float scale = 6.0f;
|
||
|
|
float dx = scale * 1.0 / float(texDim.x);
|
||
|
|
float dy = scale * 1.0 / float(texDim.y);
|
||
|
|
|
||
|
|
float shadowFactor = 0.0;
|
||
|
|
int count = 0;
|
||
|
|
int range = 12;
|
||
|
|
|
||
|
|
for (int x = -range; x <= range; x++)
|
||
|
|
{
|
||
|
|
for (int y = -range; y <= range; y++)
|
||
|
|
{
|
||
|
|
shadowFactor += textureProj(sc, vec2(dx*x, dy*y));
|
||
|
|
count++;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
return shadowFactor / count; */
|
||
|
|
}
|
||
|
|
|
||
|
|
const mat4 biasMat = mat4(
|
||
|
|
0.5, 0.0, 0.0, 0.0,
|
||
|
|
0.0, 0.5, 0.0, 0.0,
|
||
|
|
0.0, 0.0, 1.0, 0.0,
|
||
|
|
0.5, 0.5, 0.0, 1.0
|
||
|
|
);
|
||
|
|
|
||
|
|
|
||
|
|
float get_shadow(int lightIdx, vec4 position) {
|
||
|
|
Light light = lights.lights[0];
|
||
|
|
vec4 relativePosition = light.view * position;
|
||
|
|
vec4 shadowCoords = relativePosition / relativePosition.w;
|
||
|
|
|
||
|
|
float shadow = filterPCF(biasMat * shadowCoords);
|
||
|
|
|
||
|
|
return shadow;
|
||
|
|
}
|
||
|
|
|
||
|
|
vec3 bsdf(vec3 normal, vec3 viewDir, vec3 lightDir, vec3 baseColor, float metallic, float roughness) {
|
||
|
|
vec3 halfway = normalize(viewDir + lightDir);
|
||
|
|
float NoH = max(0.0, dot(normal, halfway));
|
||
|
|
float NoL = max(0.0, dot(normal, lightDir));
|
||
|
|
float NoV = abs(dot(normal, viewDir)) + 1e-5;
|
||
|
|
float VoH = max(0.0, dot(viewDir, halfway));
|
||
|
|
float LoH = max(0.0, dot(lightDir, halfway));
|
||
|
|
|
||
|
|
|
||
|
|
/* color at 0 degree angle */
|
||
|
|
vec3 f0 = 0.16 * (1.0 - roughness) * (1.0 - roughness) * (1.0 - metallic) + baseColor * metallic;
|
||
|
|
vec3 diffuseColor = (1.0 - metallic) * baseColor.rgb;
|
||
|
|
|
||
|
|
/* normal distribution of the dome */
|
||
|
|
float D = ggx_normal_distr(NoH, roughness);
|
||
|
|
/* occlusion of microfacets */
|
||
|
|
float G = ggx_smith_correlated(NoV, NoL, roughness);
|
||
|
|
/* fresnel */
|
||
|
|
vec3 F = schlick(VoH, f0);
|
||
|
|
|
||
|
|
vec3 specular = D * G * F; /// (4.0 * NoV * NoL + 0.0001);
|
||
|
|
/* light emmited back by material (not reflection) */
|
||
|
|
|
||
|
|
vec3 diffuse = lambert_diffuse(diffuseColor);
|
||
|
|
|
||
|
|
return (diffuse + specular) * NoL * 4.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
vec3 bloom_threshold(vec3 base) {
|
||
|
|
float threshold = 0.8f;
|
||
|
|
float knee = 0.5f;
|
||
|
|
float intensity = 0.4f;
|
||
|
|
vec4 curveThreshold = vec4(threshold - knee, knee * 2.0f, 0.25f / max(1e-5f, knee), threshold);
|
||
|
|
|
||
|
|
// Pixel brightness
|
||
|
|
float br = max((base).x, max((base).y, (base).z));
|
||
|
|
|
||
|
|
// Under-threshold part: quadratic curve
|
||
|
|
float rq = clamp(br - curveThreshold.x, 0.0, curveThreshold.y);
|
||
|
|
rq = curveThreshold.z * rq * rq;
|
||
|
|
|
||
|
|
// Combine and apply the brightness response curve.
|
||
|
|
base *= max(rq, br - curveThreshold.w) / max(1e-5, br);
|
||
|
|
|
||
|
|
// Clamp pixel intensity if clamping enabled
|
||
|
|
if (intensity > 0.0) {
|
||
|
|
br = max(1e-5, max((base).x, max((base).y, (base).z)));
|
||
|
|
base *= 1.0 - max(0.0, br - intensity) / br;
|
||
|
|
}
|
||
|
|
|
||
|
|
return base;
|
||
|
|
}
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
vec3 color = texture(inAlbedo, inUV).rgb;
|
||
|
|
float metallic = texture(inPbr, inUV).r;
|
||
|
|
float roughness = texture(inPbr, inUV).g;
|
||
|
|
roughness *= roughness;
|
||
|
|
vec3 normal = texture(inNormal, inUV).rgb;
|
||
|
|
vec3 position = texture(inPosition, inUV).rgb;
|
||
|
|
|
||
|
|
vec3 viewDir = normalize(-cam.position.xyz - position);
|
||
|
|
|
||
|
|
vec3 lightDir = -normalize(vec3(lights.lights[0].view[0][2], lights.lights[0].view[1][2], lights.lights[0].view[2][2]));
|
||
|
|
|
||
|
|
float occlusion = get_shadow(0, vec4(position, 1.0));
|
||
|
|
|
||
|
|
float lightIntensity = 1.5f;
|
||
|
|
vec3 Lo = bsdf(normal, viewDir, lightDir, color, metallic, roughness);
|
||
|
|
|
||
|
|
vec3 ambient = vec3(0.2) * color;
|
||
|
|
vec3 prd = ambient + Lo * (1.0 - occlusion) * lightIntensity;
|
||
|
|
|
||
|
|
outColor = vec4(prd, 1.0);
|
||
|
|
|
||
|
|
// outBloomThreshold = vec4(bloom_threshold(prd), dot(bloom_threshold(prd), bloom_threshold(prd)));
|
||
|
|
}
|