Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ SHADERS = \
shaders/shaders_palette_switch \
shaders/shaders_postprocessing \
shaders/shaders_raymarching \
shaders/shaders_shadowmap \
shaders/shaders_shapes_textures \
shaders/shaders_simple_mask \
shaders/shaders_spotlight \
Expand Down
1 change: 1 addition & 0 deletions examples/Makefile.Web
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ SHADERS = \
shaders/shaders_palette_switch \
shaders/shaders_postprocessing \
shaders/shaders_raymarching \
shaders/shaders_shadowmap \
shaders/shaders_shapes_textures \
shaders/shaders_simple_mask \
shaders/shaders_spotlight \
Expand Down
Binary file added examples/shaders/resources/models/robot.glb
Binary file not shown.
86 changes: 86 additions & 0 deletions examples/shaders/resources/shaders/glsl120/shadowmap.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#version 120

precision mediump float;

// This shader is based on the basic lighting shader
// This only supports one light, which is directional, and it (of course) supports shadows

// Input vertex attributes (from vertex shader)
varying in vec3 fragPosition;
varying in vec2 fragTexCoord;
//varying in vec4 fragColor;
varying in vec3 fragNormal;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

// Input lighting values
uniform vec3 lightDir;
uniform vec4 lightColor;
uniform vec4 ambient;
uniform vec3 viewPos;

// Input shadowmapping values
uniform mat4 lightVP; // Light source view-projection matrix
uniform sampler2D shadowMap;

uniform int shadowMapResolution;

void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture2D(texture0, fragTexCoord);
vec3 lightDot = vec3(0.0);
vec3 normal = normalize(fragNormal);
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);

vec3 l = -lightDir;

float NdotL = max(dot(normal, l), 0.0);
lightDot += lightColor.rgb*NdotL;

float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(l), normal))), 16.0); // 16 refers to shine
specular += specCo;

vec4 finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));

// Shadow calculations
vec4 fragPosLightSpace = lightVP * vec4(fragPosition, 1);
fragPosLightSpace.xyz /= fragPosLightSpace.w; // Perform the perspective division
fragPosLightSpace.xyz = (fragPosLightSpace.xyz + 1.0f) / 2.0f; // Transform from [-1, 1] range to [0, 1] range
vec2 sampleCoords = fragPosLightSpace.xy;
float curDepth = fragPosLightSpace.z;
// Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene.
// The solution is adding a small bias to the depth
// In this case, the bias is proportional to the slope of the surface, relative to the light
float bias = max(0.0008 * (1.0 - dot(normal, l)), 0.00008);
int shadowCounter = 0;
const int numSamples = 9;
// PCF (percentage-closer filtering) algorithm:
// Instead of testing if just one point is closer to the current point,
// we test the surrounding points as well.
// This blurs shadow edges, hiding aliasing artifacts.
vec2 texelSize = vec2(1.0f / float(shadowMapResolution));
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
float sampleDepth = texture2D(shadowMap, sampleCoords + texelSize * vec2(x, y)).r;
if (curDepth - bias > sampleDepth)
{
shadowCounter++;
}
}
}
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter) / float(numSamples));

// Add ambient lighting whether in shadow or not
finalColor += texelColor*(ambient/10.0)*colDiffuse;

// Gamma correction
finalColor = pow(finalColor, vec4(1.0/2.2));
gl_FragColor = finalColor;
}
32 changes: 32 additions & 0 deletions examples/shaders/resources/shaders/glsl120/shadowmap.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#version 120

// Input vertex attributes
attribute vec3 vertexPosition;
attribute vec2 vertexTexCoord;
attribute vec3 vertexNormal;
attribute vec4 vertexColor;

// Input uniform values
uniform mat4 mvp;
uniform mat4 matModel;
uniform mat4 matNormal;

// Output vertex attributes (to fragment shader)
varying vec3 fragPosition;
varying vec2 fragTexCoord;
varying vec4 fragColor;
varying vec3 fragNormal;

// NOTE: Add here your custom variables

void main()
{
// Send vertex attributes to fragment shader
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));

// Calculate final vertex position
gl_Position = mvp*vec4(vertexPosition, 1.0);
}
86 changes: 86 additions & 0 deletions examples/shaders/resources/shaders/glsl330/shadowmap.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#version 330

// This shader is based on the basic lighting shader
// This only supports one light, which is directional, and it (of course) supports shadows

// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
in vec2 fragTexCoord;
//in vec4 fragColor;
in vec3 fragNormal;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

// Output fragment color
out vec4 finalColor;

// Input lighting values
uniform vec3 lightDir;
uniform vec4 lightColor;
uniform vec4 ambient;
uniform vec3 viewPos;

// Input shadowmapping values
uniform mat4 lightVP; // Light source view-projection matrix
uniform sampler2D shadowMap;

uniform int shadowMapResolution;

void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord);
vec3 lightDot = vec3(0.0);
vec3 normal = normalize(fragNormal);
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);

vec3 l = -lightDir;

float NdotL = max(dot(normal, l), 0.0);
lightDot += lightColor.rgb*NdotL;

float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(l), normal))), 16.0); // 16 refers to shine
specular += specCo;

finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));

// Shadow calculations
vec4 fragPosLightSpace = lightVP * vec4(fragPosition, 1);
fragPosLightSpace.xyz /= fragPosLightSpace.w; // Perform the perspective division
fragPosLightSpace.xyz = (fragPosLightSpace.xyz + 1.0f) / 2.0f; // Transform from [-1, 1] range to [0, 1] range
vec2 sampleCoords = fragPosLightSpace.xy;
float curDepth = fragPosLightSpace.z;
// Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene.
// The solution is adding a small bias to the depth
// In this case, the bias is proportional to the slope of the surface, relative to the light
float bias = max(0.0002 * (1.0 - dot(normal, l)), 0.00002) + 0.00001;
int shadowCounter = 0;
const int numSamples = 9;
// PCF (percentage-closer filtering) algorithm:
// Instead of testing if just one point is closer to the current point,
// we test the surrounding points as well.
// This blurs shadow edges, hiding aliasing artifacts.
vec2 texelSize = vec2(1.0f / float(shadowMapResolution));
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
float sampleDepth = texture(shadowMap, sampleCoords + texelSize * vec2(x, y)).r;
if (curDepth - bias > sampleDepth)
{
shadowCounter++;
}
}
}
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter) / float(numSamples));

// Add ambient lighting whether in shadow or not
finalColor += texelColor*(ambient/10.0)*colDiffuse;

// Gamma correction
finalColor = pow(finalColor, vec4(1.0/2.2));
}
32 changes: 32 additions & 0 deletions examples/shaders/resources/shaders/glsl330/shadowmap.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#version 330

// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexColor;

// Input uniform values
uniform mat4 mvp;
uniform mat4 matModel;
uniform mat4 matNormal;

// Output vertex attributes (to fragment shader)
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec4 fragColor;
out vec3 fragNormal;

// NOTE: Add here your custom variables

void main()
{
// Send vertex attributes to fragment shader
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));

// Calculate final vertex position
gl_Position = mvp*vec4(vertexPosition, 1.0);
}
Loading