239 lines
6.3 KiB
GLSL
239 lines
6.3 KiB
GLSL
#version 330 core
|
|
out vec4 FragColor;
|
|
|
|
const int MAX_POINT_LIGHTS = 10;
|
|
|
|
in vec3 FragPosition;
|
|
in vec3 Normal;
|
|
in vec3 Color;
|
|
|
|
struct BaseLight
|
|
{
|
|
vec3 color;
|
|
float ambientIntensity;
|
|
float diffuseIntensity;
|
|
};
|
|
|
|
struct Attenuation
|
|
{
|
|
float constant;
|
|
float linear;
|
|
float exponential;
|
|
};
|
|
|
|
struct PointLight
|
|
{
|
|
BaseLight base;
|
|
Attenuation atten;
|
|
vec3 position;
|
|
float farPlane;
|
|
samplerCube depthMap;
|
|
};
|
|
|
|
struct Material
|
|
{
|
|
vec3 ambientColor;
|
|
vec3 diffuseColor;
|
|
vec3 specularColor;
|
|
float shininess;
|
|
};
|
|
|
|
uniform int numOfPointLights;
|
|
uniform PointLight pointLights[MAX_POINT_LIGHTS];
|
|
uniform Material material;
|
|
|
|
//uniform sampler2D diffuseTexture;
|
|
|
|
|
|
uniform vec3 viewPosition;
|
|
|
|
//uniform float farPlane;
|
|
//uniform bool shadows;
|
|
|
|
vec3 gridSamplingDisk[20] = vec3[]
|
|
(
|
|
vec3(1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
|
vec3(1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
|
vec3(1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
|
vec3(1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
|
|
vec3(0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
|
|
);
|
|
|
|
int bayer[64] = int[64](
|
|
0, 32, 8, 40, 2, 34, 10, 42,
|
|
48, 16, 56, 24, 50, 18, 58, 26,
|
|
12, 44, 4, 36, 14, 46, 6, 38,
|
|
60, 28, 52, 20, 62, 30, 54, 22,
|
|
3, 35, 11, 43, 1, 33, 9, 41,
|
|
51, 19, 59, 27, 49, 17, 57, 25,
|
|
15, 47, 7, 39, 13, 45, 5, 37,
|
|
63, 31, 55, 23, 61, 29, 53, 21
|
|
);
|
|
|
|
float ShadowCalculation(PointLight light, vec3 normal)
|
|
{
|
|
// get vector between fragment position and light position
|
|
vec3 fragToLight = FragPosition - light.position;
|
|
float currentDepth = length(fragToLight);
|
|
|
|
vec3 lightDir = normalize(light.position - FragPosition);
|
|
|
|
float shadow = 0.0;
|
|
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
|
|
//float bias = 0.15;
|
|
int samples = 20;
|
|
float viewDistance = length(viewPosition - FragPosition);
|
|
float diskRadius = (1.0 + (viewDistance / light.farPlane)) / 25.0;
|
|
for(int i = 0; i < samples; ++i)
|
|
{
|
|
float closestDepth = texture(light.depthMap, fragToLight + gridSamplingDisk[i] * diskRadius).r;
|
|
//FragColor = vec4(vec3(closestDepth / farPlane), 1.0);
|
|
closestDepth *= light.farPlane; // undo mapping [0;1]
|
|
if(currentDepth - bias > closestDepth)
|
|
shadow += 1.0;
|
|
}
|
|
shadow /= float(samples);
|
|
|
|
//shadow = dither(shadow);
|
|
|
|
// display closestDepth as debug (to visualize depth cubemap)
|
|
// FragColor = vec4(vec3(closestDepth / farPlane), 1.0);
|
|
|
|
return shadow;
|
|
}
|
|
|
|
vec4 dither(vec4 color)
|
|
{
|
|
float downsampleFactor = 2;
|
|
float ditherSize = 0.05;
|
|
float colorSize = 8.0;
|
|
|
|
float _x = (gl_FragCoord.x/downsampleFactor);
|
|
float _y = (gl_FragCoord.y/downsampleFactor);
|
|
_x = mod(_x, 8);
|
|
_y = mod(_y, 8);
|
|
int _M = bayer[8*int(_y) + int(_x)];
|
|
float _z = float(_M) * (1.0 / pow(8, 2.0));
|
|
_z -= 0.5;
|
|
|
|
color.x += _z * ditherSize;
|
|
color.y += _z * ditherSize;
|
|
color.z += _z * ditherSize;
|
|
|
|
//color = greyscale;
|
|
color = floor(color * (colorSize - 1) + 0.5) / (colorSize - 1);
|
|
vec3 greyscale = vec3(0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b);
|
|
|
|
return color;
|
|
}
|
|
|
|
/*vec3 diffuse(vec3 _lightColor, vec3 _lightPosition)
|
|
{
|
|
// diffuse
|
|
vec3 lightDir = normalize(_lightPosition - FragPosition);
|
|
vec3 lightDist = _lightPosition - FragPosition;
|
|
float diff = max(dot(lightDir, Normal), 0.0);
|
|
|
|
float linear = 0.2;
|
|
float exponential = 0.2;
|
|
// Apply attenuation: light fades over distance
|
|
float attenuation = 1.0 / (1.0 + (linear * length(lightDist)) + (exponential * pow(length(lightDist), 2.0)));
|
|
|
|
vec3 diffuse = diff * lightColor;
|
|
return diffuse;
|
|
}*/
|
|
|
|
/*vec3 specular(vec3 _lightPosition)
|
|
{
|
|
// specular
|
|
vec3 lightDir = normalize(_lightPosition - FragPosition);
|
|
vec3 viewDir = normalize(viewPosition - FragPosition);
|
|
vec3 reflectDir = reflect(-lightDir, Normal);
|
|
float spec = 0.0;
|
|
vec3 halfwayDir = normalize(lightDir + viewDir);
|
|
spec = pow(max(dot(Normal, halfwayDir), 0.0), 64.0);
|
|
vec3 specular = spec * lightColor;
|
|
return specular;
|
|
}*/
|
|
|
|
vec4 calculateAmbient(BaseLight light)
|
|
{
|
|
vec4 ambientColor = vec4(light.color, 1.0) *
|
|
light.ambientIntensity *
|
|
vec4(material.ambientColor, 1.0);
|
|
|
|
return ambientColor;
|
|
}
|
|
|
|
vec4 calculateDiffuse(BaseLight light, vec3 lightDirection, vec3 normal)
|
|
{
|
|
vec4 diffuseColor = vec4(0.0);
|
|
float diffuseFactor = dot(normal, -lightDirection);
|
|
|
|
if (diffuseFactor > 0.0)
|
|
{
|
|
diffuseColor = vec4(light.color, 1.0) *
|
|
light.diffuseIntensity *
|
|
vec4(material.diffuseColor, 1.0) *
|
|
diffuseFactor;
|
|
}
|
|
|
|
return diffuseColor;
|
|
}
|
|
|
|
vec4 calculateSpecular(BaseLight light, vec3 lightDirection, vec3 normal)
|
|
{
|
|
vec4 specularColor = vec4(0.0);
|
|
vec3 pixelToCamera = normalize(viewPosition - FragPosition);
|
|
vec3 lightReflect = normalize(reflect(lightDirection, normal));
|
|
float specularFactor = dot(pixelToCamera, lightReflect);
|
|
|
|
if (specularFactor > 0.0)
|
|
{
|
|
specularColor = vec4(light.color, 1.0) *
|
|
light.diffuseIntensity *
|
|
vec4(material.specularColor, 1.0) *
|
|
specularFactor;
|
|
}
|
|
|
|
return specularColor * material.shininess;
|
|
}
|
|
|
|
vec4 caclulatePointLight(int index, vec3 normal)
|
|
{
|
|
vec3 lightDirection = FragPosition - pointLights[index].position;
|
|
float lightDistance = length(lightDirection);
|
|
lightDirection = normalize(lightDirection);
|
|
|
|
float shadow = 1.0 - ShadowCalculation(pointLights[index], normal);
|
|
|
|
vec4 color = calculateAmbient(pointLights[index].base) +
|
|
shadow *
|
|
(calculateDiffuse(pointLights[index].base, lightDirection, normal) +
|
|
calculateSpecular(pointLights[index].base, lightDirection, normal));
|
|
|
|
|
|
// color = vec4(Color, 1.0);
|
|
|
|
float attenuation = pointLights[index].atten.constant +
|
|
pointLights[index].atten.linear * lightDistance +
|
|
pointLights[index].atten.exponential * (lightDistance * lightDistance);
|
|
|
|
return color / attenuation;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
vec3 normal = normalize(Normal);
|
|
vec4 totalLight = vec4(0.0, 0.0, 0.0, 0.0);
|
|
|
|
for (int i = 0; i < numOfPointLights; i++)
|
|
{
|
|
totalLight += caclulatePointLight(i, normal);
|
|
}
|
|
|
|
//totalLight = dither(totalLight);
|
|
FragColor = totalLight;
|
|
}
|
|
|