readme
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
#version 330 core
|
||||
in vec2 TexCoords;
|
||||
out vec4 color;
|
||||
|
||||
uniform sampler2D text;
|
||||
uniform vec4 textColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
||||
color = textColor * sampled;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
|
||||
out vec2 TexCoords;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 ndc = (vertex.xy / screenSize) * 2.0 - 1.0;
|
||||
ndc.y = -ndc.y;
|
||||
|
||||
gl_Position = vec4(ndc, 0.0, 1.0);
|
||||
TexCoords = vertex.zw;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform float rounding = 0.0f;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform vec2 normalizedCenterPos;
|
||||
uniform vec2 normalizedCenterScale;
|
||||
uniform vec2 pixelScale;
|
||||
uniform vec2 pixelPos;
|
||||
|
||||
uniform vec4 Color = {0.0f,0.0f,0.0f,1.0f};
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = Color;
|
||||
|
||||
|
||||
float rounding = clamp(rounding,0.0f,1.0f);
|
||||
if (rounding != 0.0f) {
|
||||
float roundingfactor = min(pixelScale.x,pixelScale.y)/2 * rounding;
|
||||
vec2 r1 = pixelScale/2 - vec2(roundingfactor);
|
||||
vec2 fragPosTopLeft = vec2(gl_FragCoord.x, screenSize.y - gl_FragCoord.y);
|
||||
vec2 absrelcoord = abs(fragPosTopLeft - pixelScale/2 - pixelPos);
|
||||
|
||||
if (!(absrelcoord.x < r1.x || absrelcoord.y < r1.y)) {
|
||||
vec2 cornerOffset = absrelcoord - r1;
|
||||
if (dot(cornerOffset, cornerOffset) > roundingfactor * roundingfactor) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec2 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform vec2 pixelPos;
|
||||
uniform vec2 pixelScale;
|
||||
|
||||
uniform float z;
|
||||
uniform float rotation;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 unitPos = aPos * 0.5 + 0.5;
|
||||
vec2 pixelPosTopLeft = pixelPos + unitPos * pixelScale;
|
||||
vec2 ndc = (pixelPosTopLeft / screenSize) * 2.0 - 1.0;
|
||||
ndc.y = -ndc.y;
|
||||
|
||||
gl_Position = vec4(ndc, 0.0f, 1.0f);
|
||||
|
||||
TexCoords = aTexCoords;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform vec3 hitboxColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(hitboxColor, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 modl;
|
||||
uniform mat4 view;
|
||||
uniform mat4 proj;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = proj * view * modl * vec4(aPos, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform float rounding = 0.0f;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform vec2 normalizedCenterPos;
|
||||
uniform vec2 normalizedCenterScale;
|
||||
uniform vec2 pixelScale;
|
||||
uniform vec2 pixelPos;
|
||||
|
||||
uniform vec4 Color = {0.0f,0.0f,0.0f,1.0f};
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = Color * texture(tex,TexCoords);
|
||||
|
||||
|
||||
float rounding = clamp(rounding,0.0f,1.0f);
|
||||
if (rounding != 0.0f) {
|
||||
float roundingfactor = min(pixelScale.x,pixelScale.y)/2 * rounding;
|
||||
vec2 r1 = pixelScale/2 - vec2(roundingfactor);
|
||||
vec2 fragPosTopLeft = vec2(gl_FragCoord.x, screenSize.y - gl_FragCoord.y);
|
||||
vec2 absrelcoord = abs(fragPosTopLeft - pixelScale/2 - pixelPos);
|
||||
|
||||
if (!(absrelcoord.x < r1.x || absrelcoord.y < r1.y)) {
|
||||
vec2 cornerOffset = absrelcoord - r1;
|
||||
if (dot(cornerOffset, cornerOffset) > roundingfactor * roundingfactor) {
|
||||
discard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec2 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform vec2 pixelPos;
|
||||
uniform vec2 pixelScale;
|
||||
|
||||
uniform float z;
|
||||
uniform float rotation;
|
||||
|
||||
uniform int uvMode = 0; // 0 = stretch, 1 = tile
|
||||
uniform vec3 tileScale = vec3(1.0);
|
||||
uniform vec2 uvOffset = vec2(0.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 unitPos = aPos * 0.5 + 0.5;
|
||||
vec2 pixelPosTopLeft = pixelPos + unitPos * pixelScale;
|
||||
vec2 ndc = (pixelPosTopLeft / screenSize) * 2.0 - 1.0;
|
||||
ndc.y = -ndc.y;
|
||||
|
||||
gl_Position = vec4(ndc, 0.0f, 1.0f);
|
||||
|
||||
// Screen y runs down here, so flip v to keep images the right way up
|
||||
vec2 uv = vec2(aTexCoords.x, 1.0 - aTexCoords.y);
|
||||
TexCoords = (uvMode == 1 ? uv * tileScale.xy : uv) + uvOffset;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 normal;
|
||||
in vec2 texCoord;
|
||||
in vec3 FragPos;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture(tex,texCoord) * color;
|
||||
if (base.w == 0.0f) {
|
||||
discard;
|
||||
}
|
||||
FragColor = base;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTex;
|
||||
layout(location = 3) in mat4 modl;
|
||||
|
||||
out vec3 normal;
|
||||
out vec2 texCoord;
|
||||
out vec3 FragPos;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 proj;
|
||||
|
||||
uniform int uvMode = 0; // 0 = stretch, 1 = tile
|
||||
uniform vec3 tileScale = vec3(1.0);
|
||||
uniform vec2 uvOffset = vec2(0.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
FragPos = vec3(modl * vec4(aPos, 1.0));
|
||||
normal = aNormal;
|
||||
texCoord = (uvMode == 1 ? aPos.xy * tileScale.xy : aTex) + uvOffset;
|
||||
gl_Position = proj* view * modl * vec4(aPos,1.0f);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D screenTexture;
|
||||
uniform sampler2D bloomTexture;
|
||||
uniform float bloomStrength = 0.0f;
|
||||
uniform float brightness = 0.0f;
|
||||
uniform float colorContrast = 0.0f;
|
||||
uniform float saturation = 1.0f;
|
||||
uniform float exposure = 1.0f;
|
||||
|
||||
vec3 ACESFilm(vec3 x)
|
||||
{
|
||||
const float a = 2.51;
|
||||
const float b = 0.03;
|
||||
const float c = 2.43;
|
||||
const float d = 0.59;
|
||||
const float e = 0.14;
|
||||
return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Added before tonemapping, while everything is still in HDR
|
||||
vec3 originalcolor = texture(screenTexture, TexCoords).rgb
|
||||
+ texture(bloomTexture, TexCoords).rgb * bloomStrength;
|
||||
vec3 finalcolor = ACESFilm(originalcolor * exposure);
|
||||
|
||||
const float gamma = 2.2;
|
||||
finalcolor = pow(finalcolor, vec3(1.0 / gamma));
|
||||
|
||||
finalcolor = mix(finalcolor,vec3(1.0f) - finalcolor,colorContrast);
|
||||
|
||||
float average = (finalcolor[0]+finalcolor[1]+finalcolor[2])/3.0f;
|
||||
|
||||
finalcolor = mix(vec3(average), finalcolor, saturation);
|
||||
|
||||
FragColor = vec4(finalcolor,1.0f);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec2 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
|
||||
TexCoords = aTexCoords;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D image;
|
||||
uniform int horizontal;
|
||||
|
||||
const float weights[5] = float[](0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texel = 1.0 / vec2(textureSize(image, 0));
|
||||
vec2 direction = horizontal != 0 ? vec2(texel.x, 0.0) : vec2(0.0, texel.y);
|
||||
|
||||
vec3 color = texture(image, TexCoords).rgb * weights[0];
|
||||
for (int i = 1; i < 5; i++) {
|
||||
color += texture(image, TexCoords + direction * float(i)).rgb * weights[i];
|
||||
color += texture(image, TexCoords - direction * float(i)).rgb * weights[i];
|
||||
}
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D screenTexture;
|
||||
uniform float threshold;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Averaged, since a quarter size target would otherwise skip most of the screen's pixels
|
||||
vec2 texel = 1.0 / vec2(textureSize(screenTexture, 0));
|
||||
vec3 color = (texture(screenTexture, TexCoords + texel * vec2(-1.0, -1.0)).rgb
|
||||
+ texture(screenTexture, TexCoords + texel * vec2(1.0, -1.0)).rgb
|
||||
+ texture(screenTexture, TexCoords + texel * vec2(-1.0, 1.0)).rgb
|
||||
+ texture(screenTexture, TexCoords + texel * vec2(1.0, 1.0)).rgb) * 0.25;
|
||||
|
||||
// A single blown out specular pixel would otherwise flash a huge glow
|
||||
color = min(color, vec3(20.0));
|
||||
|
||||
// Keeps the hue of whatever is over the threshold, and fades in instead of cutting off
|
||||
float brightness = max(color.r, max(color.g, color.b));
|
||||
float contribution = max(brightness - threshold, 0.0) / max(brightness, 1e-4);
|
||||
|
||||
FragColor = vec4(color * contribution, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 normal;
|
||||
in vec2 texCoord;
|
||||
in vec3 FragPos;
|
||||
in vec4 fragposlightspace;
|
||||
|
||||
struct DirLight {
|
||||
vec3 direction;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
struct PointLight {
|
||||
vec3 position;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
float radius;
|
||||
int shadowTile;
|
||||
};
|
||||
|
||||
struct SpotLight {
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
float radius;
|
||||
float innerCos;
|
||||
float outerCos;
|
||||
int shadowTile;
|
||||
};
|
||||
|
||||
// The array sizes have to match Light.h
|
||||
#define MAX_DIRECTIONAL_LIGHTS 4
|
||||
#define MAX_POINT_LIGHTS 16
|
||||
#define MAX_SPOT_LIGHTS 8
|
||||
#define SHADOW_ATLAS_COLUMNS 6
|
||||
#define SHADOW_ATLAS_TILES (SHADOW_ATLAS_COLUMNS * SHADOW_ATLAS_COLUMNS)
|
||||
|
||||
uniform DirLight dirLight; // the sun, the only light with a shadow map
|
||||
uniform DirLight directionalLights[MAX_DIRECTIONAL_LIGHTS];
|
||||
uniform int directionalLightCount = 0;
|
||||
uniform PointLight pointLights[MAX_POINT_LIGHTS];
|
||||
uniform int pointLightCount = 0;
|
||||
uniform SpotLight spotLights[MAX_SPOT_LIGHTS];
|
||||
uniform int spotLightCount = 0;
|
||||
uniform sampler2DShadow localShadowMap;
|
||||
uniform mat4 shadowTileMatrices[SHADOW_ATLAS_TILES];
|
||||
|
||||
uniform vec3 viewPos;
|
||||
|
||||
uniform sampler2DShadow shadowMap;
|
||||
uniform sampler2D tex;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform vec4 colorOverride = vec4(0.0);
|
||||
uniform int useTexture = 0;
|
||||
uniform float metallic = 0.0;
|
||||
uniform float roughness = 0.7;
|
||||
uniform float ao = 1.0;
|
||||
uniform float emissive = 0.0;
|
||||
uniform float envIntensity = 0.8;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
// Plain Blinn-Phong: ambient, Lambert diffuse and a half vector highlight.
|
||||
// Roughness sets how tight and strong the highlight is, metallic tints it and takes away the diffuse.
|
||||
|
||||
// Close enough to the 2.2 curve and much cheaper than pow
|
||||
vec3 ToLinear(vec3 c)
|
||||
{
|
||||
return c * c;
|
||||
}
|
||||
|
||||
// Light from one direction, L points from the surface toward the light.
|
||||
// diffuse and specular are already scaled for this pixel, see main.
|
||||
vec3 ShadeLight(vec3 L, vec3 radiance, vec3 N, vec3 V, vec3 diffuse, vec3 specular, float power)
|
||||
{
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
vec3 H = normalize(V + L);
|
||||
float highlight = pow(max(dot(N, H), 0.0), power);
|
||||
return (diffuse + specular * highlight) * radiance * NdotL;
|
||||
}
|
||||
|
||||
// Inverse square falloff, windowed so it reaches exactly zero at the radius
|
||||
float PointAttenuation(float distanceSquared, float radius)
|
||||
{
|
||||
float ratio = distanceSquared / (radius * radius);
|
||||
float window = clamp(1.0 - ratio * ratio, 0.0, 1.0);
|
||||
return window * window / max(distanceSquared, 0.01);
|
||||
}
|
||||
|
||||
// Which of a point light's 6 atlas tiles covers offset, the order is set in RenderLocalShadows
|
||||
int PointShadowFace(vec3 offset)
|
||||
{
|
||||
vec3 size = abs(offset);
|
||||
if (size.x >= size.y && size.x >= size.z) return offset.x > 0.0 ? 0 : 1;
|
||||
if (size.y >= size.z) return offset.y > 0.0 ? 2 : 3;
|
||||
return offset.z > 0.0 ? 4 : 5;
|
||||
}
|
||||
|
||||
// 1 = lit, 0 = shadowed. Stays inside the tile so the filter can't pick up its neighbours.
|
||||
float LocalShadow(int tile, vec3 worldPos, vec3 N)
|
||||
{
|
||||
vec4 clipPos = shadowTileMatrices[tile] * vec4(worldPos + N * 0.04, 1.0);
|
||||
if (clipPos.w <= 0.0)
|
||||
return 1.0;
|
||||
|
||||
vec3 projCoords = clipPos.xyz / clipPos.w * 0.5 + 0.5;
|
||||
if (any(lessThan(projCoords, vec3(0.0))) || any(greaterThan(projCoords, vec3(1.0))))
|
||||
return 1.0;
|
||||
|
||||
float tileSize = 1.0 / float(SHADOW_ATLAS_COLUMNS);
|
||||
vec2 tileOrigin = vec2(float(tile % SHADOW_ATLAS_COLUMNS), float(tile / SHADOW_ATLAS_COLUMNS)) * tileSize;
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(localShadowMap, 0));
|
||||
vec2 uv = tileOrigin + projCoords.xy * tileSize;
|
||||
|
||||
float shadow = 0.0;
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
vec2 sampleUV = clamp(uv + vec2(x, y) * texelSize, tileOrigin + texelSize, tileOrigin + tileSize - texelSize);
|
||||
shadow += texture(localShadowMap, vec3(sampleUV, projCoords.z - 0.0002));
|
||||
}
|
||||
}
|
||||
return shadow / 9.0;
|
||||
}
|
||||
|
||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 N, vec3 L)
|
||||
{
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
if (projCoords.z > 1.0 || any(lessThan(projCoords, vec3(0.0))) ||
|
||||
any(greaterThan(projCoords, vec3(1.0))))
|
||||
return 1.0;
|
||||
|
||||
float bias = max(0.004 * (1.0 - dot(N, L)), 0.001);
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(shadowMap, 0));
|
||||
float shadow = 0.0;
|
||||
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
vec2 offset = vec2(x, y) * texelSize;
|
||||
shadow += texture(shadowMap, vec3(projCoords.xy + offset, projCoords.z - bias));
|
||||
}
|
||||
}
|
||||
return shadow / 9.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedoSample = vec4(0.8, 0.8, 0.8, 1.0);
|
||||
if (useTexture != 0) {
|
||||
albedoSample = texture(tex, texCoord);
|
||||
if (albedoSample.a < 0.1)
|
||||
discard;
|
||||
albedoSample.rgb = ToLinear(albedoSample.rgb);
|
||||
}
|
||||
|
||||
albedoSample.rgb = mix(albedoSample.rgb, colorOverride.rgb, colorOverride.w);
|
||||
|
||||
vec3 albedo = albedoSample.rgb;
|
||||
float metal = clamp(metallic, 0.0, 1.0);
|
||||
float rough = clamp(roughness, 0.04, 1.0);
|
||||
|
||||
vec3 N = normalize(normal);
|
||||
vec3 V = normalize(viewPos - FragPos);
|
||||
|
||||
float smoothness = 1.0 - clamp(rough, 0.0, 1.0);
|
||||
float power = exp2(10.0 * smoothness + 1.0); // 2 when fully rough, 2048 when mirror smooth
|
||||
vec3 specularColor = mix(vec3(0.5 * smoothness * smoothness), albedo * (0.25 + 0.75 * smoothness), metal);
|
||||
vec3 diffuseBRDF = albedo * (1.0 - metal) / PI; // the light intensities were tuned with the 1/PI in
|
||||
vec3 specularBRDF = specularColor / PI;
|
||||
vec3 direct = vec3(0.0);
|
||||
|
||||
// Facing away from the sun has no direct light, so skip the BRDF and the 9 shadow samples
|
||||
vec3 sunL = normalize(-dirLight.direction);
|
||||
if (dot(N, sunL) > 0.0) {
|
||||
float shadow = ShadowCalculation(fragposlightspace, N, sunL);
|
||||
direct += ShadeLight(sunL, dirLight.color * dirLight.intensity, N, V, diffuseBRDF, specularBRDF, power) * shadow;
|
||||
}
|
||||
|
||||
for (int i = 0; i < directionalLightCount; i++) {
|
||||
vec3 L = normalize(-directionalLights[i].direction);
|
||||
vec3 radiance = directionalLights[i].color * directionalLights[i].intensity;
|
||||
direct += ShadeLight(L, radiance, N, V, diffuseBRDF, specularBRDF, power);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pointLightCount; i++) {
|
||||
vec3 toLight = pointLights[i].position - FragPos;
|
||||
float distanceSquared = dot(toLight, toLight);
|
||||
float radius = pointLights[i].radius;
|
||||
if (distanceSquared >= radius * radius)
|
||||
continue;
|
||||
|
||||
vec3 radiance = pointLights[i].color * pointLights[i].intensity * PointAttenuation(distanceSquared, radius);
|
||||
vec3 L = toLight / sqrt(distanceSquared);
|
||||
if (dot(N, L) <= 0.0)
|
||||
continue;
|
||||
|
||||
vec3 lit = ShadeLight(L, radiance, N, V, diffuseBRDF, specularBRDF, power);
|
||||
if (pointLights[i].shadowTile >= 0)
|
||||
lit *= LocalShadow(pointLights[i].shadowTile + PointShadowFace(-toLight), FragPos, N);
|
||||
direct += lit;
|
||||
}
|
||||
|
||||
for (int i = 0; i < spotLightCount; i++) {
|
||||
vec3 toLight = spotLights[i].position - FragPos;
|
||||
float distanceSquared = dot(toLight, toLight);
|
||||
float radius = spotLights[i].radius;
|
||||
if (distanceSquared >= radius * radius)
|
||||
continue;
|
||||
|
||||
vec3 L = toLight / sqrt(distanceSquared);
|
||||
float cone = smoothstep(spotLights[i].outerCos, spotLights[i].innerCos, dot(-L, spotLights[i].direction));
|
||||
if (cone <= 0.0)
|
||||
continue;
|
||||
|
||||
if (dot(N, L) <= 0.0)
|
||||
continue;
|
||||
|
||||
vec3 radiance = spotLights[i].color * spotLights[i].intensity * PointAttenuation(distanceSquared, radius) * cone;
|
||||
vec3 lit = ShadeLight(L, radiance, N, V, diffuseBRDF, specularBRDF, power);
|
||||
if (spotLights[i].shadowTile >= 0)
|
||||
lit *= LocalShadow(spotLights[i].shadowTile, FragPos, N);
|
||||
direct += lit;
|
||||
}
|
||||
|
||||
// Ambient is the sky's blurred colour in the direction the surface faces
|
||||
vec3 ambient = ToLinear(textureLod(environmentMap, N, 7.0).rgb) * envIntensity * albedo * ao;
|
||||
|
||||
FragColor = vec4(direct + ambient + albedo * emissive * 4.0, albedoSample.a);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTex;
|
||||
|
||||
out vec3 normal;
|
||||
out vec2 texCoord;
|
||||
out vec3 FragPos;
|
||||
out vec4 fragposlightspace;
|
||||
uniform mat4 modl;
|
||||
uniform mat4 view;
|
||||
uniform mat4 proj;
|
||||
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
|
||||
uniform int uvMode = 0; // 0 = stretch, 1 = tile
|
||||
uniform vec3 tileScale = vec3(1.0);
|
||||
uniform vec2 uvOffset = vec2(0.0);
|
||||
|
||||
// Same direction as transpose(inverse(m)) for normals, without the per vertex inverse
|
||||
mat3 CofactorMatrix(mat3 m)
|
||||
{
|
||||
return mat3(cross(m[1], m[2]), cross(m[2], m[0]), cross(m[0], m[1]));
|
||||
}
|
||||
|
||||
// Tiling ignores the mesh's uvs and projects from whichever axis the surface faces,
|
||||
// so every face of a stretched cube repeats at the same size
|
||||
vec2 SurfaceUV()
|
||||
{
|
||||
if (uvMode == 0) return aTex + uvOffset;
|
||||
|
||||
// Unscale the normal first, so a stretched mesh picks the axis it faces in the world
|
||||
vec3 n = abs(aNormal / max(tileScale, vec3(1e-4)));
|
||||
vec3 p = aPos * tileScale;
|
||||
if (n.y >= n.x && n.y >= n.z) return p.xz + uvOffset;
|
||||
if (n.x >= n.z) return p.zy + uvOffset;
|
||||
return p.xy + uvOffset;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 worldPos = modl * vec4(aPos, 1.0);
|
||||
FragPos = worldPos.xyz;
|
||||
normal = CofactorMatrix(mat3(modl)) * aNormal;
|
||||
texCoord = SurfaceUV();
|
||||
fragposlightspace = lightSpaceMatrix * worldPos;
|
||||
gl_Position = proj * view * worldPos;
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
struct DirLight {
|
||||
vec3 direction;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
struct PointLight {
|
||||
vec3 position;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
float radius;
|
||||
int shadowTile;
|
||||
};
|
||||
|
||||
struct SpotLight {
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
float radius;
|
||||
float innerCos;
|
||||
float outerCos;
|
||||
int shadowTile;
|
||||
};
|
||||
|
||||
// The array sizes have to match Light.h
|
||||
#define MAX_DIRECTIONAL_LIGHTS 4
|
||||
#define MAX_POINT_LIGHTS 16
|
||||
#define MAX_SPOT_LIGHTS 8
|
||||
#define SHADOW_ATLAS_COLUMNS 6
|
||||
#define SHADOW_ATLAS_TILES (SHADOW_ATLAS_COLUMNS * SHADOW_ATLAS_COLUMNS)
|
||||
|
||||
uniform DirLight dirLight; // the sun, the only light with a shadow map
|
||||
uniform DirLight directionalLights[MAX_DIRECTIONAL_LIGHTS];
|
||||
uniform int directionalLightCount = 0;
|
||||
uniform PointLight pointLights[MAX_POINT_LIGHTS];
|
||||
uniform int pointLightCount = 0;
|
||||
uniform SpotLight spotLights[MAX_SPOT_LIGHTS];
|
||||
uniform int spotLightCount = 0;
|
||||
uniform sampler2DShadow localShadowMap;
|
||||
uniform mat4 shadowTileMatrices[SHADOW_ATLAS_TILES];
|
||||
|
||||
uniform vec3 viewPos;
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
|
||||
uniform sampler2D gPosition;
|
||||
uniform sampler2D gNormal;
|
||||
uniform sampler2D gAlbedo;
|
||||
uniform sampler2D gMaterial;
|
||||
uniform sampler2DShadow shadowMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform float envIntensity = 0.8;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
// Plain Blinn-Phong: ambient, Lambert diffuse and a half vector highlight.
|
||||
// Roughness sets how tight and strong the highlight is, metallic tints it and takes away the diffuse.
|
||||
|
||||
// Close enough to the 2.2 curve and much cheaper than pow
|
||||
vec3 ToLinear(vec3 c)
|
||||
{
|
||||
return c * c;
|
||||
}
|
||||
|
||||
// Light from one direction, L points from the surface toward the light.
|
||||
// diffuse and specular are already scaled for this pixel, see main.
|
||||
vec3 ShadeLight(vec3 L, vec3 radiance, vec3 N, vec3 V, vec3 diffuse, vec3 specular, float power)
|
||||
{
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
vec3 H = normalize(V + L);
|
||||
float highlight = pow(max(dot(N, H), 0.0), power);
|
||||
return (diffuse + specular * highlight) * radiance * NdotL;
|
||||
}
|
||||
|
||||
// Inverse square falloff, windowed so it reaches exactly zero at the radius
|
||||
float PointAttenuation(float distanceSquared, float radius)
|
||||
{
|
||||
float ratio = distanceSquared / (radius * radius);
|
||||
float window = clamp(1.0 - ratio * ratio, 0.0, 1.0);
|
||||
return window * window / max(distanceSquared, 0.01);
|
||||
}
|
||||
|
||||
// Which of a point light's 6 atlas tiles covers offset, the order is set in RenderLocalShadows
|
||||
int PointShadowFace(vec3 offset)
|
||||
{
|
||||
vec3 size = abs(offset);
|
||||
if (size.x >= size.y && size.x >= size.z) return offset.x > 0.0 ? 0 : 1;
|
||||
if (size.y >= size.z) return offset.y > 0.0 ? 2 : 3;
|
||||
return offset.z > 0.0 ? 4 : 5;
|
||||
}
|
||||
|
||||
// 1 = lit, 0 = shadowed. Stays inside the tile so the filter can't pick up its neighbours.
|
||||
float LocalShadow(int tile, vec3 worldPos, vec3 N)
|
||||
{
|
||||
vec4 clipPos = shadowTileMatrices[tile] * vec4(worldPos + N * 0.04, 1.0);
|
||||
if (clipPos.w <= 0.0)
|
||||
return 1.0;
|
||||
|
||||
vec3 projCoords = clipPos.xyz / clipPos.w * 0.5 + 0.5;
|
||||
if (any(lessThan(projCoords, vec3(0.0))) || any(greaterThan(projCoords, vec3(1.0))))
|
||||
return 1.0;
|
||||
|
||||
float tileSize = 1.0 / float(SHADOW_ATLAS_COLUMNS);
|
||||
vec2 tileOrigin = vec2(float(tile % SHADOW_ATLAS_COLUMNS), float(tile / SHADOW_ATLAS_COLUMNS)) * tileSize;
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(localShadowMap, 0));
|
||||
vec2 uv = tileOrigin + projCoords.xy * tileSize;
|
||||
|
||||
float shadow = 0.0;
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
vec2 sampleUV = clamp(uv + vec2(x, y) * texelSize, tileOrigin + texelSize, tileOrigin + tileSize - texelSize);
|
||||
shadow += texture(localShadowMap, vec3(sampleUV, projCoords.z - 0.0002));
|
||||
}
|
||||
}
|
||||
return shadow / 9.0;
|
||||
}
|
||||
|
||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 N, vec3 L)
|
||||
{
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
if (projCoords.z > 1.0 || any(lessThan(projCoords, vec3(0.0))) ||
|
||||
any(greaterThan(projCoords, vec3(1.0))))
|
||||
return 1.0;
|
||||
|
||||
float bias = max(0.004 * (1.0 - dot(N, L)), 0.001);
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(shadowMap, 0));
|
||||
float shadow = 0.0;
|
||||
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
vec2 offset = vec2(x, y) * texelSize;
|
||||
shadow += texture(shadowMap, vec3(projCoords.xy + offset, projCoords.z - bias));
|
||||
}
|
||||
}
|
||||
return shadow / 9.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = texture(gNormal, TexCoord).rgb;
|
||||
|
||||
// Nothing was written here, keep the skybox underneath
|
||||
if (dot(normal, normal) < 0.01)
|
||||
discard;
|
||||
|
||||
vec3 FragPos = texture(gPosition, TexCoord).rgb;
|
||||
vec4 albedoSample = texture(gAlbedo, TexCoord);
|
||||
vec4 material = texture(gMaterial, TexCoord);
|
||||
|
||||
vec3 albedo = albedoSample.rgb;
|
||||
float metal = material.r;
|
||||
float rough = material.g;
|
||||
float ao = material.b;
|
||||
|
||||
vec3 N = normalize(normal);
|
||||
vec3 V = normalize(viewPos - FragPos);
|
||||
|
||||
float smoothness = 1.0 - clamp(rough, 0.0, 1.0);
|
||||
float power = exp2(10.0 * smoothness + 1.0); // 2 when fully rough, 2048 when mirror smooth
|
||||
vec3 specularColor = mix(vec3(0.5 * smoothness * smoothness), albedo * (0.25 + 0.75 * smoothness), metal);
|
||||
vec3 diffuseBRDF = albedo * (1.0 - metal) / PI; // the light intensities were tuned with the 1/PI in
|
||||
vec3 specularBRDF = specularColor / PI;
|
||||
vec3 direct = vec3(0.0);
|
||||
|
||||
// Facing away from the sun has no direct light, so skip the BRDF and the 9 shadow samples
|
||||
vec3 sunL = normalize(-dirLight.direction);
|
||||
if (dot(N, sunL) > 0.0) {
|
||||
float shadow = ShadowCalculation(lightSpaceMatrix * vec4(FragPos, 1.0), N, sunL);
|
||||
direct += ShadeLight(sunL, dirLight.color * dirLight.intensity, N, V, diffuseBRDF, specularBRDF, power) * shadow;
|
||||
}
|
||||
|
||||
for (int i = 0; i < directionalLightCount; i++) {
|
||||
vec3 L = normalize(-directionalLights[i].direction);
|
||||
vec3 radiance = directionalLights[i].color * directionalLights[i].intensity;
|
||||
direct += ShadeLight(L, radiance, N, V, diffuseBRDF, specularBRDF, power);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pointLightCount; i++) {
|
||||
vec3 toLight = pointLights[i].position - FragPos;
|
||||
float distanceSquared = dot(toLight, toLight);
|
||||
float radius = pointLights[i].radius;
|
||||
if (distanceSquared >= radius * radius)
|
||||
continue;
|
||||
|
||||
vec3 radiance = pointLights[i].color * pointLights[i].intensity * PointAttenuation(distanceSquared, radius);
|
||||
vec3 L = toLight / sqrt(distanceSquared);
|
||||
if (dot(N, L) <= 0.0)
|
||||
continue;
|
||||
|
||||
vec3 lit = ShadeLight(L, radiance, N, V, diffuseBRDF, specularBRDF, power);
|
||||
if (pointLights[i].shadowTile >= 0)
|
||||
lit *= LocalShadow(pointLights[i].shadowTile + PointShadowFace(-toLight), FragPos, N);
|
||||
direct += lit;
|
||||
}
|
||||
|
||||
for (int i = 0; i < spotLightCount; i++) {
|
||||
vec3 toLight = spotLights[i].position - FragPos;
|
||||
float distanceSquared = dot(toLight, toLight);
|
||||
float radius = spotLights[i].radius;
|
||||
if (distanceSquared >= radius * radius)
|
||||
continue;
|
||||
|
||||
vec3 L = toLight / sqrt(distanceSquared);
|
||||
float cone = smoothstep(spotLights[i].outerCos, spotLights[i].innerCos, dot(-L, spotLights[i].direction));
|
||||
if (cone <= 0.0)
|
||||
continue;
|
||||
|
||||
if (dot(N, L) <= 0.0)
|
||||
continue;
|
||||
|
||||
vec3 radiance = spotLights[i].color * spotLights[i].intensity * PointAttenuation(distanceSquared, radius) * cone;
|
||||
vec3 lit = ShadeLight(L, radiance, N, V, diffuseBRDF, specularBRDF, power);
|
||||
if (spotLights[i].shadowTile >= 0)
|
||||
lit *= LocalShadow(spotLights[i].shadowTile, FragPos, N);
|
||||
direct += lit;
|
||||
}
|
||||
|
||||
// Ambient is the sky's blurred colour in the direction the surface faces
|
||||
vec3 ambient = ToLinear(textureLod(environmentMap, N, 7.0).rgb) * envIntensity * albedo * ao;
|
||||
|
||||
vec3 emission = albedo * material.a * 4.0;
|
||||
|
||||
FragColor = vec4(direct + ambient + emission, albedoSample.a);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec2 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoord = aTexCoord;
|
||||
gl_Position = vec4(aPos, 0.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
uniform sampler2D gPosition;
|
||||
uniform sampler2D gNormal;
|
||||
uniform sampler2D gAlbedo;
|
||||
uniform sampler2D gMaterial;
|
||||
uniform sampler2D depthTex;
|
||||
uniform sampler2D shadowTex;
|
||||
uniform sampler2D bloomTex;
|
||||
|
||||
uniform float nearPlane;
|
||||
uniform float farPlane;
|
||||
|
||||
uniform int debugMode; // 1 = position, 2 = normal, 3 = albedo, 4 = material, 5 = depth, 6 = shadow map, 7 = bloom
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if (debugMode == 1) {
|
||||
vec3 v = texture(gPosition, TexCoord).rgb;
|
||||
FragColor = vec4(v * 0.01 + 0.5, 1.0);
|
||||
}
|
||||
else if (debugMode == 2) {
|
||||
vec3 n = texture(gNormal, TexCoord).rgb;
|
||||
if (length(n) >= 0.1)
|
||||
FragColor = vec4(normalize(n) * 0.5 + 0.5, 1.0);
|
||||
}
|
||||
else if (debugMode == 3) {
|
||||
FragColor = vec4(pow(texture(gAlbedo, TexCoord).rgb, vec3(1.0 / 2.2)), 1.0);
|
||||
}
|
||||
else if (debugMode == 4) {
|
||||
FragColor = vec4(texture(gMaterial, TexCoord).rgb, 1.0);
|
||||
}
|
||||
else if (debugMode == 5) {
|
||||
// Perspective depth is nearly 1.0 everywhere, so linearize it and spread it out
|
||||
float z = texture(depthTex, TexCoord).r * 2.0 - 1.0;
|
||||
float linearDepth = (2.0 * nearPlane * farPlane) / (farPlane + nearPlane - z * (farPlane - nearPlane));
|
||||
float d = log(1.0 + linearDepth) / log(1.0 + farPlane);
|
||||
FragColor = vec4(vec3(d), 1.0);
|
||||
}
|
||||
else if (debugMode == 6) {
|
||||
FragColor = vec4(vec3(texture(shadowTex, TexCoord).r), 1.0);
|
||||
}
|
||||
else if (debugMode == 7) {
|
||||
FragColor = vec4(texture(bloomTex, TexCoord).rgb, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec2 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoord = aTexCoord;
|
||||
gl_Position = vec4(aPos, 0.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#version 330 core
|
||||
layout (location = 0) out vec3 gPosition;
|
||||
layout (location = 1) out vec3 gNormal;
|
||||
layout (location = 2) out vec4 gAlbedo; // linear rgb + alpha
|
||||
layout (location = 3) out vec4 gMaterial; // r = metallic, g = roughness, b = ao, a = emissive
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoord;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform vec4 colorOverride = vec4(0.0);
|
||||
uniform int useTexture = 0;
|
||||
uniform float metallic = 0.0;
|
||||
uniform float roughness = 0.7;
|
||||
uniform float ao = 1.0;
|
||||
uniform float emissive = 0.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo = vec4(0.8, 0.8, 0.8, 1.0);
|
||||
if (useTexture != 0) {
|
||||
albedo = texture(tex, TexCoord);
|
||||
if (albedo.a < 0.1)
|
||||
discard;
|
||||
albedo.rgb = albedo.rgb * albedo.rgb; // same cheap 2.2 stand-in as the lighting shaders
|
||||
}
|
||||
|
||||
albedo.rgb = mix(albedo.rgb, colorOverride.rgb, colorOverride.w);
|
||||
|
||||
gPosition = FragPos;
|
||||
gNormal = normalize(Normal);
|
||||
gAlbedo = albedo;
|
||||
gMaterial = vec4(clamp(metallic, 0.0, 1.0), clamp(roughness, 0.04, 1.0), ao, clamp(emissive, 0.0, 1.0));
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
out vec2 TexCoord;
|
||||
|
||||
uniform mat4 proj;
|
||||
uniform mat4 view;
|
||||
uniform mat4 modl;
|
||||
|
||||
uniform int uvMode = 0; // 0 = stretch, 1 = tile
|
||||
uniform vec3 tileScale = vec3(1.0);
|
||||
uniform vec2 uvOffset = vec2(0.0);
|
||||
|
||||
// Same direction as transpose(inverse(m)) for normals, without the per vertex inverse
|
||||
mat3 CofactorMatrix(mat3 m)
|
||||
{
|
||||
return mat3(cross(m[1], m[2]), cross(m[2], m[0]), cross(m[0], m[1]));
|
||||
}
|
||||
|
||||
// Tiling ignores the mesh's uvs and projects from whichever axis the surface faces,
|
||||
// so every face of a stretched cube repeats at the same size
|
||||
vec2 SurfaceUV()
|
||||
{
|
||||
if (uvMode == 0) return aTexCoord + uvOffset;
|
||||
|
||||
// Unscale the normal first, so a stretched mesh picks the axis it faces in the world
|
||||
vec3 n = abs(aNormal / max(tileScale, vec3(1e-4)));
|
||||
vec3 p = aPos * tileScale;
|
||||
if (n.y >= n.x && n.y >= n.z) return p.xz + uvOffset;
|
||||
if (n.x >= n.z) return p.zy + uvOffset;
|
||||
return p.xy + uvOffset;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 worldPos = modl * vec4(aPos, 1.0);
|
||||
FragPos = worldPos.xyz;
|
||||
Normal = normalize(CofactorMatrix(mat3(modl)) * aNormal);
|
||||
TexCoord = SurfaceUV();
|
||||
gl_Position = proj * view * worldPos;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
layout (location = 3) in ivec4 boneIds;
|
||||
layout (location = 4) in vec4 weights;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
out vec2 TexCoord;
|
||||
|
||||
uniform mat4 proj;
|
||||
uniform mat4 view;
|
||||
uniform mat4 modl;
|
||||
|
||||
const int MAX_BONES = 100;
|
||||
const int MAX_BONE_INFLUENCE = 4;
|
||||
uniform mat4 finalBonesMatrices[MAX_BONES];
|
||||
|
||||
uniform int uvMode = 0; // 0 = stretch, 1 = tile
|
||||
uniform vec3 tileScale = vec3(1.0);
|
||||
uniform vec2 uvOffset = vec2(0.0);
|
||||
|
||||
// Same direction as transpose(inverse(m)) for normals, without the per vertex inverse
|
||||
mat3 CofactorMatrix(mat3 m)
|
||||
{
|
||||
return mat3(cross(m[1], m[2]), cross(m[2], m[0]), cross(m[0], m[1]));
|
||||
}
|
||||
|
||||
// Tiling ignores the mesh's uvs and projects from whichever axis the surface faces.
|
||||
// Done on the bind pose, so the pattern stays stuck to the character as it moves.
|
||||
vec2 SurfaceUV()
|
||||
{
|
||||
if (uvMode == 0) return aTexCoord + uvOffset;
|
||||
|
||||
vec3 n = abs(aNormal);
|
||||
vec3 p = aPos * tileScale;
|
||||
if (n.y >= n.x && n.y >= n.z) return p.xz + uvOffset;
|
||||
if (n.x >= n.z) return p.zy + uvOffset;
|
||||
return p.xy + uvOffset;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 totalPosition = vec4(0.0);
|
||||
vec3 totalNormal = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < MAX_BONE_INFLUENCE; i++)
|
||||
{
|
||||
if (boneIds[i] == -1) continue;
|
||||
if (boneIds[i] >= MAX_BONES)
|
||||
{
|
||||
totalPosition = vec4(aPos, 1.0);
|
||||
totalNormal = aNormal;
|
||||
break;
|
||||
}
|
||||
totalPosition += (finalBonesMatrices[boneIds[i]] * vec4(aPos, 1.0)) * weights[i];
|
||||
totalNormal += mat3(finalBonesMatrices[boneIds[i]]) * aNormal * weights[i];
|
||||
}
|
||||
|
||||
vec4 worldPos = modl * totalPosition;
|
||||
|
||||
FragPos = worldPos.xyz;
|
||||
Normal = normalize(CofactorMatrix(mat3(modl)) * totalNormal);
|
||||
TexCoord = SurfaceUV();
|
||||
gl_Position = proj * view * worldPos;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
uniform mat4 modl;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = lightSpaceMatrix * modl * vec4(aPos, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 pos;
|
||||
layout(location = 1) in vec3 norm;
|
||||
layout(location = 2) in vec2 tex;
|
||||
layout(location = 3) in ivec4 boneIds;
|
||||
layout(location = 4) in vec4 weights;
|
||||
|
||||
uniform mat4 proj;
|
||||
uniform mat4 view;
|
||||
uniform mat4 modl;
|
||||
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
|
||||
const int MAX_BONES = 100;
|
||||
const int MAX_BONE_INFLUENCE = 4;
|
||||
uniform mat4 finalBonesMatrices[MAX_BONES];
|
||||
|
||||
out vec3 normal;
|
||||
out vec2 texCoord;
|
||||
out vec3 FragPos;
|
||||
out vec4 fragposlightspace;
|
||||
|
||||
uniform int uvMode = 0; // 0 = stretch, 1 = tile
|
||||
uniform vec3 tileScale = vec3(1.0);
|
||||
uniform vec2 uvOffset = vec2(0.0);
|
||||
|
||||
// Same direction as transpose(inverse(m)) for normals, without the per vertex inverse
|
||||
mat3 CofactorMatrix(mat3 m)
|
||||
{
|
||||
return mat3(cross(m[1], m[2]), cross(m[2], m[0]), cross(m[0], m[1]));
|
||||
}
|
||||
|
||||
// Tiling ignores the mesh's uvs and projects from whichever axis the surface faces.
|
||||
// Done on the bind pose, so the pattern stays stuck to the character as it moves.
|
||||
vec2 SurfaceUV()
|
||||
{
|
||||
if (uvMode == 0) return tex + uvOffset;
|
||||
|
||||
vec3 n = abs(norm);
|
||||
vec3 p = pos * tileScale;
|
||||
if (n.y >= n.x && n.y >= n.z) return p.xz + uvOffset;
|
||||
if (n.x >= n.z) return p.zy + uvOffset;
|
||||
return p.xy + uvOffset;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 totalPosition = vec4(0.0);
|
||||
vec3 totalNormal = vec3(0.0);
|
||||
|
||||
int bonescontributed = 0;
|
||||
for(int i = 0; i < MAX_BONE_INFLUENCE; i++)
|
||||
{
|
||||
if(boneIds[i] == -1) continue;
|
||||
if(boneIds[i] >= MAX_BONES)
|
||||
{
|
||||
totalPosition = vec4(pos, 1.0);
|
||||
totalNormal = norm;
|
||||
break;
|
||||
}
|
||||
bonescontributed ++;
|
||||
totalPosition += (finalBonesMatrices[boneIds[i]] * vec4(pos, 1.0))* weights[i];
|
||||
totalNormal += mat3(finalBonesMatrices[boneIds[i]]) * norm * weights[i];
|
||||
}
|
||||
vec4 worldPos = modl * totalPosition;
|
||||
FragPos = worldPos.xyz;
|
||||
fragposlightspace = lightSpaceMatrix * worldPos;
|
||||
gl_Position = proj * view * worldPos;
|
||||
normal = normalize(CofactorMatrix(mat3(modl)) * totalNormal);
|
||||
texCoord = SurfaceUV();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#version 430 core
|
||||
layout(location = 0) in vec3 pos;
|
||||
layout(location = 3) in ivec4 boneIds;
|
||||
layout(location = 4) in vec4 weights;
|
||||
|
||||
uniform mat4 modl;
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
|
||||
const int MAX_BONES = 100;
|
||||
const int MAX_BONE_INFLUENCE = 4;
|
||||
uniform mat4 finalBonesMatrices[MAX_BONES];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 totalPosition = vec4(0.0);
|
||||
for (int i = 0; i < MAX_BONE_INFLUENCE; i++)
|
||||
{
|
||||
if (boneIds[i] == -1) continue;
|
||||
if (boneIds[i] >= MAX_BONES)
|
||||
{
|
||||
totalPosition = vec4(pos, 1.0);
|
||||
break;
|
||||
}
|
||||
totalPosition += finalBonesMatrices[boneIds[i]] * vec4(pos, 1.0) * weights[i];
|
||||
}
|
||||
gl_Position = lightSpaceMatrix * modl * totalPosition;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#version 330 core
|
||||
|
||||
void main()
|
||||
{
|
||||
//gl_FragDepth = gl_FragCoord.z;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 TexCoords;
|
||||
|
||||
uniform samplerCube skybox;
|
||||
|
||||
void main()
|
||||
{
|
||||
float gamma = 2.2;
|
||||
FragColor = vec4(pow(texture(skybox, TexCoords).rgb, vec3(gamma)),1.0f);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 TexCoords;
|
||||
|
||||
uniform mat4 proj;
|
||||
uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = aPos;
|
||||
vec4 pos = proj * view * vec4(aPos, 1.0);
|
||||
gl_Position = pos.xyww; // sits on the far plane, so it only draws where no geometry is
|
||||
}
|
||||
Reference in New Issue
Block a user