191 lines
6.8 KiB
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
|
|
} |