This repository has been archived by the owner on Jan 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreflectiveShader.fs
147 lines (118 loc) · 6.1 KB
/
reflectiveShader.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#version 330 core
#define NR_POINT_LIGHTS 1
struct Material {
sampler2D specular;//reflection intensity + texture Of Object
float shininess;//metalicity
sampler2D diffuse;//color + texture Of Object
sampler2D emission;//color + texture Of Object
};
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct PointLight {
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct SpotLight {
vec3 position;
vec3 direction;
float cutOff;
float outerCutOff;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
out vec4 FragColor;
in VS_OUT {
vec3 FragPos;
vec3 Normal;
vec2 TexCoords;
vec4 FragPosLightSpace;
} fs_in;
uniform Material material;
uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform SpotLight spotLight;
uniform sampler2D shadowMap;
// function prototypes
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, float shadow);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, float shadow);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, float shadow);
float ShadowCalculation(vec4 fragPosLightSpace){
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;// perform perspective divide
projCoords = projCoords * 0.5 + 0.5;// transform to [0,1] range
float closestDepth = texture(shadowMap, projCoords.xy).r; // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
float currentDepth = projCoords.z;// get depth of current fragment from light's perspective
vec3 normal = normalize(fs_in.Normal);// calculate bias (based on depth map resolution and slope)
//vec3 lightDir = normalize(pointLights[0].position - fs_in.FragPos);
float bias = max(0.05 * (1.0 - dot(normal, normalize(dirLight.direction))), 0.005);
// check whether current frag pos is in shadow
// float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
// PCF
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(shadowMap, 0);
for(int x = -1; x <= 1; ++x){
for(int y = -1; y <= 1; ++y){
float pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0;
}
}
shadow /= 9.0;
// keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
if(projCoords.z > 1.0)
shadow = 0.0;
return shadow;
}
void main(){
vec3 color = texture(material.diffuse, fs_in.TexCoords).rgb;
vec3 norm = normalize(fs_in.Normal);
vec3 viewDir = normalize(viewPos - fs_in.FragPos);
vec3 lightColor = vec3(0.3);
float shadow = ShadowCalculation(fs_in.FragPosLightSpace);
vec3 result = CalcDirLight(dirLight, norm, viewDir, shadow);//directional light
for(int i = 0; i < NR_POINT_LIGHTS; i++)// phase 2: point lights
result += CalcPointLight(pointLights[i], norm, fs_in.FragPos, viewDir, shadow);
result += CalcSpotLight(spotLight, norm, fs_in.FragPos, viewDir, shadow);// phase 3: spot light
FragColor = vec4(result, 1.0);
//FragColor.rgb = pow(FragColor.rgb, vec3(1.0/2.2));//gamma correction - gamma = 2.2
}
//----------------------------------------------------------- Lighting Functions ----------------------------------------------------------------------
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, float shadow){//directional light
vec3 lightDir = normalize(-light.direction);
vec3 halfwayDir = normalize(lightDir + viewDir);
return ((light.ambient * vec3(texture(material.diffuse, fs_in.TexCoords))) + (1.0 - shadow) *
(light.diffuse * max(dot(normal, lightDir), 0.0) * vec3(texture(material.diffuse, fs_in.TexCoords)) +
light.specular * pow(max(dot(viewDir, reflect(-lightDir, normal)), 0.0), material.shininess) * vec3(texture(material.specular, fs_in.TexCoords))));
}
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, float shadow){//point light
vec3 lightDir = normalize(light.position - fragPos);
vec3 halfwayDir = normalize(lightDir + viewDir);
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));// attenuation
return ((light.ambient * vec3(texture(material.diffuse, fs_in.TexCoords)) * attenuation) + (1.0 - shadow) *
(light.diffuse * max(dot(normal, lightDir), 0.0) * vec3(texture(material.diffuse, fs_in.TexCoords)) * attenuation +
light.specular * pow(max(dot(viewDir, reflect(-lightDir, normal)), 0.0), material.shininess) * vec3(texture(material.specular, fs_in.TexCoords)) * attenuation));
}
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, float shadow){//spot light
vec3 lightDir = normalize(light.position - fragPos);
vec3 halfwayDir = normalize(lightDir + viewDir);
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));// attenuation
// theta------------------------------------- epsilon-------------------------
float attenuationIntensity = attenuation * clamp((dot(lightDir, normalize(-light.direction)) - light.outerCutOff) / (light.cutOff - light.outerCutOff), 0.0, 1.0);// spotlight intensity
return ((light.ambient * vec3(texture(material.diffuse, fs_in.TexCoords)) * attenuationIntensity) + (1.0 - shadow) *
(light.diffuse * max(dot(normal, lightDir), 0.0) * vec3(texture(material.diffuse, fs_in.TexCoords)) * attenuationIntensity +
light.specular * pow(max(dot(viewDir, reflect(-lightDir, normal)), 0.0), material.shininess) * vec3(texture(material.specular, fs_in.TexCoords)) * attenuationIntensity));
}