engine/bin/data/shaders/base/graph/frag.glsl

191 lines
6.8 KiB
GLSL

#version 450
#pragma shader_stage(fragment)
#define FORWARD 0
#define FRAGMENT 1
#define PBR 1
layout (constant_id = 0) const uint TEXTURES = 1;
layout (constant_id = 1) const uint CUBEMAPS = 128;
#include "../../common/macros.h"
#include "../../common/structs.h"
layout (binding = 6, set = 1) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 7, set = 1) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 8, set = 0) uniform sampler3D samplerNoise;
#if VXGI
layout (binding = 9, set = 0) uniform sampler3D voxelOutput[CASCADES];
#endif
#if RT
layout (binding = 10, set = 0) uniform accelerationStructureEXT tlas;
#endif
layout (std140, binding = 11, set = 0) readonly buffer DrawCommands { DrawCommand drawCommands[]; };
layout (std140, binding = 12, set = 0) readonly buffer Instances { Instance instances[]; };
layout (std140, binding = 13, set = 0) readonly buffer InstanceAddresseses { InstanceAddresses addresses[]; };
layout (std140, binding = 14, set = 0) readonly buffer Materials { Material materials[]; };
layout (std140, binding = 15, set = 0) readonly buffer Textures { Texture textures[]; };
layout (std140, binding = 16, set = 0) readonly buffer Lights { Light lights[]; };
layout (std140, binding = 17, set = 0) readonly buffer Objects { Object objects[]; };
layout (binding = 18) uniform Camera { Viewport viewport[2]; } camera;
// to-do: bind UBO for settings?
/*
layout (binding = 19) uniform UBO { EyeMatrices eyes[2]; Settings settings; } ubo;
*/
#include "../../common/functions.h"
//#include "../../common/light.h"
//#include "../../common/shadows.h"
layout (location = 0) flat in uvec4 inId;
layout (location = 1) flat in vec4 inPOS0;
layout (location = 2) in vec4 inPOS1;
layout (location = 3) in vec3 inPosition;
layout (location = 4) sample in vec2 inUv;
layout (location = 5) in vec4 inColor;
layout (location = 6) in vec2 inSt;
layout (location = 7) in vec3 inNormal;
layout (location = 8) in vec3 inTangent;
layout (location = 0) out vec4 outFragColor;
void main() {
const uint triangleID = gl_PrimitiveID;
const uint drawID = uint(inId.y);
const uint instanceID = uint(inId.z);
#if 0
#if CAN_DISCARD
const DrawCommand drawCommand = drawCommands[drawID];
const Instance instance = instances[instanceID];
const Material material = materials[instance.materialID];
surface.uv.xy = wrap(inUv.xy);
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
surface.st.xy = wrap(inSt.xy);
surface.st.z = mipLevel(dFdx(inSt), dFdy(inSt));
vec4 A = inColor * material.colorBase;
// sample albedo
if ( validTextureIndex( material.indexAlbedo ) ) {
A = sampleTexture( material.indexAlbedo );
}
if ( A.a < 0.0001 ) discard;
#endif
outFragColor.rgb = A.rgb;
outFragColor.a = A.a;
#else
const DrawCommand drawCommand = drawCommands[drawID];
surface.instance = instances[instanceID];
surface.object = objects[surface.instance.objectID];
const Material material = materials[surface.instance.materialID];
surface.uv.xy = wrap(inUv.xy);
surface.st.xy = wrap(inSt.xy);
surface.dUvDx = dFdx(inUv);
surface.dUvDy = dFdy(inUv);
surface.dStDx = dFdx(inSt);
surface.dStDy = dFdy(inSt);
surface.uv.z = mipLevel(surface.dUvDx, surface.dUvDy);
surface.st.z = mipLevel(surface.dStDx, surface.dStDy);
surface.position.world = inPosition;
surface.position.eye = vec3( inverse( surface.object.model ) * vec4(surface.position.world, 1.0) );
surface.normal.world = normalize(inNormal);
surface.tangent.world = normalize(inTangent);
vec3 bitangent = cross(surface.normal.world, surface.tangent.world);
surface.tbn = mat3(surface.tangent.world, bitangent, surface.normal.world);
//
surface.material.albedo = material.colorBase;
surface.material.metallic = material.factorMetallic;
surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion;
surface.material.lightmapped = false;
surface.light = material.colorEmissive;
if ( validTextureIndex( material.indexAlbedo ) ) {
surface.material.albedo *= sampleTexture( material.indexAlbedo );
}
// OPAQUE
if ( material.modeAlpha == 0 ) {
surface.material.albedo.a = 1;
// BLEND
} else if ( material.modeAlpha == 1 ) {
// MASK
} else if ( material.modeAlpha == 2 ) {
// EMISSIVE
} else if ( material.modeAlpha == 3 ) {
surface.light.rgb *= surface.material.albedo.rgb * surface.material.albedo.a;
surface.material.albedo.a = 1.0;
}
// Emissive mapping
if ( validTextureIndex( material.indexEmissive ) ) {
surface.light *= sampleTexture( material.indexEmissive );
}
// (Occlusion/)Metallic/Roughness map
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
vec4 samp = sampleTexture( material.indexMetallicRoughness );
surface.material.metallic *= samp.b;
surface.material.roughness *= samp.g;
if ( material.indexOcclusion == material.indexMetallicRoughness ) {
surface.material.occlusion = mix(1.0, samp.r, material.factorOcclusion);
}
}
// Occlusion mapping
if ( validTextureIndex( material.indexOcclusion ) && material.indexOcclusion != material.indexMetallicRoughness ) {
float occ = sampleTexture( material.indexOcclusion ).r;
surface.material.occlusion = mix(1.0, occ, material.factorOcclusion);
}
// Normal mapping
if ( validTextureIndex( material.indexNormal ) && surface.tangent.world != vec3(0) ) {
surface.normal.world = surface.tbn * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
}
{
surface.normal.eye = normalize(vec3( inverse( surface.object.model ) * vec4(surface.normal.world, 0.0) ));
}
// Light mapping
if ( /*( bool(ubo.settings.lighting.useLightmaps)) &&*/ validTextureIndex( surface.instance.lightmapID ) ) {
surface.material.lightmapped = true; // light.a > 0.001;
vec4 light = decodeRGBE( sampleTexture( surface.instance.lightmapID, surface.st.xy, 0.0 ) );
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
const vec3 Lo = normalize(-surface.position.eye);
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
const vec3 F = F0 + (max(vec3(1.0 - surface.material.roughness), F0) - F0) * pow(clamp(1.0 - cosLo, 0.0, 1.0), 5.0);
const vec3 kD = (vec3(1.0) - F) * (1.0 - surface.material.metallic);
surface.light.rgb += (kD * surface.material.albedo.rgb * light.rgb) * surface.material.occlusion;
}
if ( surface.material.albedo.a < 0.0001 && dot(surface.light.rgb, vec3(1.0)) < 0.0001 ) discard;
surface.fragment = vec4(0.0);
surface.light.rgb += surface.material.albedo.rgb /* ubo.settings.lighting.ambient.rgb*/ * surface.material.occlusion;
/*
#if PBR
pbr();
#elif LAMBERT
lambert();
#endif
*/
outFragColor.rgb = surface.fragment.rgb + surface.light.rgb;
outFragColor.a = surface.material.albedo.a;
#endif
}