-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsdf-fragment.glsl
More file actions
147 lines (136 loc) · 4.23 KB
/
sdf-fragment.glsl
File metadata and controls
147 lines (136 loc) · 4.23 KB
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
uniform float iGlobalTime;
uniform vec3 uCameraPos;
uniform vec3 uCameraDir;
uniform vec2 uViewport;
in vec2 vPosition;
out vec4 frag_color;
float epsilon = 0.0001;
float minDist = 1.0;
float maxDist = 200.0;
int marchingSteps = 300;
struct external {
float sdfDist;
} external;
float sdfDist(vec3 point) {
return external.sdfDist;
}
/*
* Normalized direction to march in from the eye point
* for a single pixel.
*/
vec3 rayDirection(float fieldOfView, vec2 size, vec2 fragCoord) {
vec2 xy = fragCoord - size / 2.0;
float z = size.y / tan(radians(fieldOfView) / 2.0);
return normalize(vec3(xy, -z));
}
/*
* Returns a transform matrix that will transform
* a ray from view space to world coordinates.
*/
mat3 viewMatrix(vec3 eye, vec3 center, vec3 up) {
vec3 f = normalize(center - eye);
vec3 s = cross(f, up);
vec3 u = cross(s, f);
return mat3(s, u, -f);
}
vec3 estimateNormal(vec3 point) {
return normalize(vec3(
sdfDist(vec3(point.x + epsilon, point.y, point.z)) - sdfDist(vec3(point.x - epsilon, point.y, point.z)),
sdfDist(vec3(point.x, point.y + epsilon, point.z)) - sdfDist(vec3(point.x, point.y - epsilon, point.z)),
sdfDist(vec3(point.x, point.y, point.z + epsilon)) - sdfDist(vec3(point.x, point.y, point.z - epsilon))
));
}
/*
* Lighting contribution of a single point light source
* via phong illumination.
*
*/
vec3 phongContribForLight(vec3 diffuse, vec3 specular, float alpha,
vec3 point, vec3 eye, vec3 lightPos, vec3 lightIntensity) {
vec3 N = estimateNormal(point);
vec3 L = normalize(lightPos - point);
vec3 V = normalize(eye - point);
vec3 R = normalize(reflect(L * -1.0, N));
float dotLN = dot(L, N);
float dotRV = dot(R, V);
if (dotLN < 0.0) {
/* Light not visible from this point on the surface */
return vec3(0.0, 0.0, 0.0);
}
if (dotRV < 0.0) {
/* Light reflection in opposite direction, apply only diffuse */
return lightIntensity * (diffuse * dotLN);
}
return lightIntensity * (diffuse * dotLN + specular * pow(dotRV, alpha));
}
/*
* Lighting via phong illumination
* https://en.wikipedia.org/wiki/Phong_reflection_model#Description
*/
vec3 phongIllumination(vec3 ambient, vec3 diffuse, vec3 specular,
float alpha, vec3 point, vec3 eye) {
vec3 ambientLight = vec3(0.5, 0.5, 0.5);
vec3 color = ambientLight * ambient;
vec3 light1Pos = vec3(4.0 * sin(iGlobalTime),
2.0,
4.0 * cos(iGlobalTime));
vec3 light1Intensity = vec3(0.4, 0.4, 0.4);
color += phongContribForLight(diffuse, specular, alpha,
point, eye,
light1Pos,
light1Intensity);
vec3 light2Pos = vec3(2.0 * sin(0.37 * iGlobalTime),
2.0 * cos(0.37 * iGlobalTime),
2.0);
vec3 light2Intensity = vec3(0.4, 0.4, 0.4);
color += phongContribForLight(diffuse, specular, alpha,
point, eye,
light2Pos,
light2Intensity);
return color;
}
float shortestDistance(vec3 eye, vec3 dir) {
float depth = minDist;
float end = maxDist;
for (int i = 0; i < marchingSteps; i++) {
float dist = sdfDist(eye + depth * dir);
if (dist < epsilon) {
return depth;
}
depth += dist;
if (depth >= end) {
/* Moved beyond end */
return end;
}
}
return end;
}
void main2() {
float xc = (vPosition.x + 1.0) / 2;
vec2 fragCoord = ((vPosition + vec2(1.0, -1.0)) * vec2(0.5, -0.5)) * uViewport;
frag_color = vec4(
fragCoord.x / uViewport.x,
fragCoord.y / uViewport.y
,0.0,1.0);
}
void main() {
vec2 fragCoord = ((vPosition + vec2(1.0, -1.0)) * vec2(0.5, -0.5)) * uViewport;
vec3 viewDir = rayDirection(45.0, uViewport, fragCoord);
vec3 eye = uCameraPos;
mat3 viewToWorld = viewMatrix(eye, uCameraPos + (uCameraDir * 4.0), vec3(0.0, 1.0, 0.0));
vec3 worldDir = viewToWorld * viewDir;
float dist = shortestDistance(eye, worldDir);
if (dist > (maxDist - epsilon)) {
/* No shape in ray */
frag_color = vec4(0.0, 0.0, 0.0, 1.0);
} else {
vec3 p = eye + dist * worldDir;
vec3 alpha = (estimateNormal(p) + vec3(1.0)) / 2.0;
vec3 diffuse = alpha;
vec3 specular = vec3(1.0, 1.0, 1.0);
float shininess = 10.0;
vec3 color = phongIllumination(alpha, diffuse, specular, shininess, p, eye);
frag_color = vec4(color, 1.0);
}
}