102 lines
3.4 KiB
GLSL
102 lines
3.4 KiB
GLSL
#version 460
|
|
|
|
#extension GL_GOOGLE_include_directive : require
|
|
|
|
#include "bindless.glsl"
|
|
#include "scene_data.glsl"
|
|
#include "mesh_pcs.glsl"
|
|
#include "lighting.glsl"
|
|
|
|
layout (location = 0) in vec3 inPos;
|
|
layout (location = 1) in vec2 inUV;
|
|
layout (location = 2) in vec3 inNormal;
|
|
layout (location = 3) in vec4 inTangent;
|
|
layout (location = 4) in mat3 inTBN;
|
|
|
|
layout (location = 0) out vec4 outFragColor;
|
|
|
|
void main()
|
|
{
|
|
MaterialData material = pcs.sceneData.materials.data[pcs.materialID];
|
|
uint samplerID = pcs.sceneData.materials.data[pcs.materialID].textureFilteringMode;
|
|
|
|
vec4 diffuse = sampleTexture2D(material.diffuseTex, samplerID, inUV) * material.baseColor;
|
|
vec3 baseColor = diffuse.rgb;
|
|
|
|
// if (diffuse.a < 0.1) {
|
|
// discard;
|
|
// }
|
|
|
|
vec3 normal = normalize(inNormal);
|
|
// if (inTangent != vec4(0.0)) {
|
|
// // FIXME: sometimes Blender doesn't export tangents for some objects
|
|
// // for some reason. When we will start computing tangents manually,
|
|
// // this check can be removed
|
|
// normal = sampleTexture2DLinear(material.normalTex, inUV).rgb;
|
|
// // normal.y = 1 - normal.y; // flip to make OpenGL normal maps work
|
|
// normal = inTBN * normalize(normal * 2.0 - 1.0);
|
|
// normal = normalize(normal);
|
|
// }
|
|
|
|
float metallicF = material.metallicRoughnessEmissive.r;
|
|
float roughnessF = material.metallicRoughnessEmissive.g;
|
|
|
|
vec4 metallicRoughness = sampleTexture2DLinear(material.metallicRoughnessTex, inUV);
|
|
|
|
float roughness = roughnessF * metallicRoughness.g;
|
|
// roughness *= roughness; // from perceptual to linear
|
|
roughness = max(roughness, 1e-2); // 0.0 roughness leads to NaNs
|
|
|
|
float metallic = metallicF * metallicRoughness.b;
|
|
|
|
vec3 dielectricSpecular = vec3(0.04);
|
|
vec3 black = vec3(0.0);
|
|
vec3 diffuseColor = mix(baseColor * (1.0 - dielectricSpecular.r), black, metallic);
|
|
vec3 f0 = mix(dielectricSpecular, baseColor, metallic);
|
|
|
|
vec3 cameraPos = pcs.sceneData.cameraPos.xyz;
|
|
vec3 fragPos = inPos.xyz;
|
|
vec3 n = normal;
|
|
vec3 v = normalize(cameraPos - fragPos);
|
|
|
|
// forward+: only loop over the lights the culling pass put in this pixel's tile
|
|
uvec2 tileID = uvec2(gl_FragCoord.xy) / LIGHT_TILE_SIZE;
|
|
uint tileOffset = (tileID.y * pcs.sceneData.tileCountX + tileID.x) * LIGHT_TILE_STRIDE;
|
|
uint tileLightCount = pcs.sceneData.tileLightIndices.data[tileOffset];
|
|
|
|
vec3 fragColor = vec3(0.0);
|
|
for (uint i = 0; i < tileLightCount; i++) {
|
|
uint lightIndex = pcs.sceneData.tileLightIndices.data[tileOffset + 1 + i];
|
|
Light light = pcs.sceneData.lights.data[lightIndex];
|
|
|
|
fragColor += calculateLight(light, fragPos, n, v,
|
|
diffuseColor, roughness, metallic, f0);
|
|
}
|
|
|
|
// emissive
|
|
float emissiveF = material.metallicRoughnessEmissive.b;
|
|
vec3 emissiveColor = emissiveF * sampleTexture2DLinear(material.emissiveTex, inUV).rgb;
|
|
fragColor += emissiveColor;
|
|
|
|
// ambient
|
|
fragColor += baseColor * pcs.sceneData.ambientColor * pcs.sceneData.ambientIntensity;
|
|
|
|
if (pcs.sceneData.debugLightHeatmap != 0) {
|
|
fragColor = mix(fragColor, lightHeatmapColor(tileLightCount), 0.5);
|
|
}
|
|
|
|
#if 0
|
|
// TANGENT DEBUG
|
|
if (inTangent == vec4(0.0)) {
|
|
fragColor = vec3(1.0f, 0.0f, 0.0f);
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
// NORMAL DEBUG
|
|
fragColor = normal;
|
|
#endif
|
|
|
|
outFragColor = vec4(fragColor, diffuse.a);
|
|
}
|