-
Notifications
You must be signed in to change notification settings - Fork 63
/
im3d.glsl
128 lines (106 loc) · 3.64 KB
/
im3d.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
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
#if !defined(POINTS) && !defined(LINES) && !defined(TRIANGLES)
#error No primitive type defined
#endif
#if !defined(VERTEX_SHADER) && !defined(FRAGMENT_SHADER)
#error No shader stage defined
#endif
#define kAntialiasing 2.0
#ifdef VERTEX_SHADER
/* This vertex shader fetches Im3d vertex data manually from a uniform buffer (uVertexData). It assumes that the bound vertex buffer contains 4 vertices as follows:
-1,1 1,1
2 ------- 3
| \ |
| \ |
| \ |
| \ |
0 ------- 1
-1,-1 1,-1
Both the vertex ID and the vertex position are used for point/line expansion. This vertex buffer is valid for both triangle strip rendering (points/lines), and
triangle render using vertices 0,1,2.
See im3d_opengl31.cpp for more details.
*/
struct VertexData
{
vec4 m_positionSize;
uint m_color;
};
uniform VertexDataBlock
{
VertexData uVertexData[(64 * 1024) / 32]; // assume a 64kb block size, 32 is the aligned size of VertexData
};
uniform mat4 uViewProjMatrix;
uniform vec2 uViewport;
in vec4 aPosition;
#if defined(POINTS)
noperspective out vec2 vUv;
#elif defined(LINES)
noperspective out float vEdgeDistance;
#endif
noperspective out float vSize;
smooth out vec4 vColor;
vec4 UintToRgba(uint _u)
{
vec4 ret = vec4(0.0);
ret.r = float((_u & 0xff000000u) >> 24u) / 255.0;
ret.g = float((_u & 0x00ff0000u) >> 16u) / 255.0;
ret.b = float((_u & 0x0000ff00u) >> 8u) / 255.0;
ret.a = float((_u & 0x000000ffu) >> 0u) / 255.0;
return ret;
}
void main()
{
#if defined(POINTS)
int vid = gl_InstanceID;
vSize = max(uVertexData[vid].m_positionSize.w, kAntialiasing);
vColor = UintToRgba(uVertexData[vid].m_color);
vColor.a *= smoothstep(0.0, 1.0, vSize / kAntialiasing);
gl_Position = uViewProjMatrix * vec4(uVertexData[vid].m_positionSize.xyz, 1.0);
vec2 scale = 1.0 / uViewport * vSize;
gl_Position.xy += aPosition.xy * scale * gl_Position.w;
vUv = aPosition.xy * 0.5 + 0.5;
#elif defined(LINES)
int vid0 = gl_InstanceID * 2; // line start
int vid1 = vid0 + 1; // line end
int vid = (gl_VertexID % 2 == 0) ? vid0 : vid1; // data for this vertex
vColor = UintToRgba(uVertexData[vid].m_color);
vSize = uVertexData[vid].m_positionSize.w;
vColor.a *= smoothstep(0.0, 1.0, vSize / kAntialiasing);
vSize = max(vSize, kAntialiasing);
vEdgeDistance = vSize * aPosition.y;
vec4 pos0 = uViewProjMatrix * vec4(uVertexData[vid0].m_positionSize.xyz, 1.0);
vec4 pos1 = uViewProjMatrix * vec4(uVertexData[vid1].m_positionSize.xyz, 1.0);
vec2 dir = (pos0.xy / pos0.w) - (pos1.xy / pos1.w);
dir = normalize(vec2(dir.x, dir.y * uViewport.y / uViewport.x)); // correct for aspect ratio
vec2 tng = vec2(-dir.y, dir.x) * vSize / uViewport;
gl_Position = (gl_VertexID % 2 == 0) ? pos0 : pos1;
gl_Position.xy += tng * aPosition.y * gl_Position.w;
#elif defined(TRIANGLES)
int vid = gl_InstanceID * 3 + gl_VertexID;
vColor = UintToRgba(uVertexData[vid].m_color);
gl_Position = uViewProjMatrix * vec4(uVertexData[vid].m_positionSize.xyz, 1.0);
#endif
}
#endif
#ifdef FRAGMENT_SHADER
#if defined(POINTS)
noperspective in vec2 vUv;
#elif defined(LINES)
noperspective in float vEdgeDistance;
#endif
noperspective in float vSize;
smooth in vec4 vColor;
out vec4 fResult;
void main()
{
fResult = vColor;
#if defined(LINES)
float d = abs(vEdgeDistance) / vSize;
d = smoothstep(1.0, 1.0 - (kAntialiasing / vSize), d);
fResult.a *= d;
#elif defined(POINTS)
float d = length(vUv - vec2(0.5));
d = smoothstep(0.5, 0.5 - (kAntialiasing / vSize), d);
fResult.a *= d;
#endif
}
#endif