This repository has been archived by the owner on Jan 8, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfragment.glsl
84 lines (80 loc) · 2.56 KB
/
fragment.glsl
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
#version 420 core
#define POINTLIGHT 0
#define DIRLIGHT 1
#define DPLIGHT 2
#define pointlight(x) ((x==POINTLIGHT)||(x==DPLIGHT))
#define double float//I like precision but can't implic cast from dvec to vec and
//probably we don't need that much of precision... and float color is already
//MUCH better than 1/256 8-bit colors.
struct Light{
int kind;//0:point light, 1:directional light, 2:directional point light
vec3 direction;
vec3 color;
vec3 pos;
double diffusestr;
double specularstr;
double constant;
double linear;
double quadratic;
double dpfull;
double dpzero;
};
struct Material{
sampler2D diffuse;
sampler2D specular;
sampler2D emission;
bool hasemission;
double shininess;
};
out vec4 FragColor;
layout(location = 0) in vec4 ffpos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tc;
#define lightcount $$LIGHT_COUNT
uniform Light lights[lightcount];
uniform Material material;
uniform vec3 ambient;
uniform vec3 campos;
uniform double ambstr;
vec3 fpos;
vec4 blend(vec4 a,vec4 b){
return vec4((a.rgb*a.a+b.rgb*b.a)/(a.a+b.a),(1-(1-a.a)*(1-b.a)));
}
vec3 calculateLighting(Light lgt,Material mater,vec2 texc, vec3 normx){
vec3 norm = normalize(normx),ldir;
if(pointlight(lgt.kind)){
ldir = normalize(lgt.pos-fpos);
}else if(lgt.kind==DIRLIGHT){
ldir = normalize(-lgt.direction);
}
double attenu = 1.0;
if(pointlight(lgt.kind)){
double dist = length(lgt.pos-fpos);
attenu = 1.0/(lgt.constant+(lgt.linear+lgt.quadratic*dist)*dist);
}
double diffstr = max(dot(norm,ldir),0.0);
vec3 diffuse = lgt.diffusestr*lgt.color*(diffstr*texture(mater.diffuse,texc).rgb);
vec3 viewdir = normalize(campos-fpos);
vec3 rfdir = reflect(-ldir,norm);
double spec = pow(max(dot(viewdir,rfdir),0.0),mater.shininess);
vec3 specular = lgt.specularstr*lgt.color*(spec*texture(mater.specular,texc).rgb);
vec3 emmis = vec3(0.0);
if(mater.hasemission){
emmis = texture(mater.emission,texc).rgb;
}
if(lgt.kind==DPLIGHT){
double fragangle = dot(ldir,normalize(-lgt.direction));
double thresh = lgt.dpfull-lgt.dpzero;
attenu *= clamp((fragangle-lgt.dpzero)/thresh,0.0,1.0);
}
return (diffuse+specular)*attenu+emmis;
}
void main(){
fpos = ffpos.xyz/ffpos.w;
vec3 lighting = vec3(0.0);
lighting += (ambient+texture(material.diffuse,tc).rgb)*ambstr;
for(int i=0;i<lightcount;i++){
lighting += calculateLighting(lights[i],material,tc,normal);
}
FragColor = vec4(lighting,1.0);
}