forked from stackgl/glsl-lighting-walkthrough
-
Notifications
You must be signed in to change notification settings - Fork 0
/
phong.frag
92 lines (75 loc) · 2.73 KB
/
phong.frag
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
#extension GL_OES_standard_derivatives : enable
precision highp float;
//our custom Light struct
struct Light {
vec3 position;
vec3 color;
vec3 ambient;
float falloff;
float radius;
};
varying vec2 vUv;
varying vec3 vViewPosition;
varying vec3 vNormal;
//import some common functions
#pragma glslify: faceNormals = require('glsl-face-normal')
#pragma glslify: perturb = require('glsl-perturb-normal')
#pragma glslify: computeDiffuse = require('glsl-diffuse-oren-nayar')
#pragma glslify: computeSpecular = require('glsl-specular-phong')
#pragma glslify: attenuation = require('./madams-attenuation')
#pragma glslify: toLinear = require('glsl-gamma/in')
#pragma glslify: toGamma = require('glsl-gamma/out')
//some settings for the look and feel of the material
const vec2 UV_SCALE = vec2(8.0, 1.0);
const float specularScale = 0.65;
const float shininess = 20.0;
const float roughness = 1.0;
const float albedo = 0.95;
uniform sampler2D texDiffuse;
uniform sampler2D texNormal;
uniform sampler2D texSpecular;
uniform int flatShading;
uniform mat4 model;
uniform mat4 view;
uniform Light light;
//account for gamma-corrected images
vec4 textureLinear(sampler2D uTex, vec2 uv) {
return toLinear(texture2D(uTex, uv));
}
void main() {
//determine the type of normals for lighting
vec3 normal = vec3(0.0);
if (flatShading == 1) {
normal = faceNormals(vViewPosition);
} else {
normal = vNormal;
}
//determine surface to light direction
vec4 lightPosition = view * vec4(light.position, 1.0);
vec3 lightVector = lightPosition.xyz - vViewPosition;
vec3 color = vec3(0.0);
//calculate attenuation
float lightDistance = length(lightVector);
float falloff = attenuation(light.radius, light.falloff, lightDistance);
//now sample from our repeating brick texture
//assume its in sRGB, so we need to correct for gamma
vec2 uv = vUv * UV_SCALE;
vec3 diffuseColor = textureLinear(texDiffuse, uv).rgb;
vec3 normalMap = textureLinear(texNormal, uv).rgb * 2.0 - 1.0;
float specularStrength = textureLinear(texSpecular, uv).r;
//our normal map has an inverted green channel
normalMap.y *= -1.0;
vec3 L = normalize(lightVector); //light direction
vec3 V = normalize(vViewPosition); //eye direction
vec3 N = perturb(normalMap, normal, -V, vUv); //surface normal
//compute our diffuse & specular terms
float specular = specularStrength * computeSpecular(L, V, N, shininess) * specularScale * falloff;
vec3 diffuse = light.color * computeDiffuse(L, V, N, roughness, albedo) * falloff;
vec3 ambient = light.ambient;
//add the lighting
color += diffuseColor * (diffuse + ambient) + specular;
//re-apply gamma to output buffer
color = toGamma(color);
gl_FragColor.rgb = color;
gl_FragColor.a = 1.0;
}