-
Notifications
You must be signed in to change notification settings - Fork 35
/
VoxelShader.cs
131 lines (105 loc) · 2.61 KB
/
VoxelShader.cs
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
namespace meshing;
public static class VoxelShader
{
public static ShaderProgram shader;
public static bool Active => shader?.Active ?? false;
public static void Initialise()
{
shader = new(VertexShader, FragmentShader);
mvp = new(shader, "mvp");
worldPosition = new(shader, "worldPosition");
showWireframe = new(shader, "showWireframe");
}
public static void UseProgram()
{
if (shader == null)
Initialise();
shader.UseProgram();
}
public static ShaderValue mvp;
public static ShaderValue worldPosition;
public static ShaderValue showWireframe;
public static string FragmentShader = @"
out vec4 gColor;
in vec2 vUV;
in vec2 vBary;
flat in float vBrightness;
uniform bool showWireframe;
float barycentric(vec2 vBC, float width)
{
vec3 bary = vec3(vBC.x, vBC.y, 1.0 - vBC.x - vBC.y);
vec3 d = fwidth(bary);
vec3 a3 = smoothstep(d * (width - 0.5), d * (width + 0.5), bary);
return min(min(a3.x, a3.y), a3.z);
}
void main()
{
// Grid pattern
bool gridX = mod(vUV.x, 1.0) > 0.5;
bool gridY = mod(vUV.y, 1.0) > 0.5;
float grid = gridX != gridY ? 1.0 : 0.7;
gColor = vec4(vBrightness * grid);
if (showWireframe)
{
gColor.rgb *= 0.25;
gColor.rgb += vec3(1.0 - barycentric(vBary, 1.0));
}
}
";
public static string VertexShader = @$"
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aBary;
layout (location = 3) in int aTextureID;
out vec2 vUV;
out vec2 vBary;
flat out float vBrightness;
uniform mat4 mvp;
uniform vec3 worldPosition;
void main()
{{
vec3 vPosition = aPosition + worldPosition;
vBary = aBary;
int face;
if (aNormal.y >= 0.5)
{{
face = {(int)FaceType.yp};
vBrightness = 1.0;
vUV = vPosition.xz;
}}
else if (aNormal.y <= -0.5)
{{
face = {(int)FaceType.yn};
vBrightness = 0.25;
vUV = vPosition.xz;
}}
else if (aNormal.x >= 0.5)
{{
face = {(int)FaceType.xp};
vBrightness = 0.75;
vUV = vPosition.zy;
}}
else if (aNormal.x <= -0.5)
{{
face = {(int)FaceType.xn};
vBrightness = 0.75;
vUV = vPosition.zy;
}}
else if (aNormal.z >= 0.5)
{{
face = {(int)FaceType.zp};
vBrightness = 0.5;
vUV = vPosition.xy;
}}
else
{{
face = {(int)FaceType.zn};
vBrightness = 0.5;
vUV = vPosition.xy;
}}
vUV *= 2.0;
// World to screen pos
gl_Position = mvp * vec4(vPosition, 1.0);
}}
";
}