151 lines
3.9 KiB
Plaintext
151 lines
3.9 KiB
Plaintext
|
||
#version 460
|
||
|
||
layout (lines) in;
|
||
|
||
layout (triangle_strip, max_vertices = 5) out;
|
||
|
||
uniform mat4 transform;
|
||
uniform vec3 lightPositionAndSize;
|
||
|
||
in vec2 originalPos[];
|
||
|
||
out vec4 penumbras;
|
||
|
||
mat2 adjugate(mat2 m) {
|
||
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]);
|
||
}
|
||
|
||
void workWithSegmentForward(float x) {
|
||
vec2 endpoint_a = originalPos[0];
|
||
vec2 endpoint_b = originalPos[1];
|
||
|
||
vec2 endpoint = mix(endpoint_a, endpoint_b, x);
|
||
float light_radius = lightPositionAndSize.z;
|
||
|
||
// Deltas from the segment to the light center.
|
||
vec2 delta_a = endpoint_a - lightPositionAndSize.xy;
|
||
vec2 delta_b = endpoint_b - lightPositionAndSize.xy;
|
||
vec2 delta = endpoint - lightPositionAndSize.xy;
|
||
|
||
// Offsets from the light center to the edge of the light volume.
|
||
vec2 offset_a = vec2(-light_radius, light_radius) * normalize(delta_a).xy;
|
||
vec2 offset_b = vec2( light_radius, -light_radius) * normalize(delta_b).xy;
|
||
vec2 offset = mix(offset_a, offset_b, x);
|
||
|
||
vec2 penumbra_a = adjugate(mat2( offset_a, -delta_a))*(delta - mix(offset, delta_a, 0));
|
||
vec2 penumbra_b = adjugate(mat2(-offset_b, delta_b))*(delta - mix(offset, delta_b, 0));
|
||
|
||
// Vertex projection.
|
||
gl_Position = transform * vec4(delta - offset, 0.0, 1.0);
|
||
EmitVertex();
|
||
}
|
||
|
||
void main() {
|
||
vec4 a = gl_in[0].gl_Position;
|
||
vec4 b = gl_in[1].gl_Position;
|
||
|
||
vec2 aInv = originalPos[0];
|
||
vec2 bInv = originalPos[1];
|
||
|
||
vec2 lightPosition = lightPositionAndSize.xy;
|
||
float lightSize = lightPositionAndSize.z;
|
||
|
||
gl_Position = b;
|
||
EmitVertex();
|
||
|
||
gl_Position = a;
|
||
EmitVertex();
|
||
|
||
workWithSegmentForward(0);
|
||
workWithSegmentForward(1);
|
||
|
||
EndPrimitive();
|
||
|
||
// hard shadow geometry (umbra)
|
||
//gl_Position = transform * vec4(aInv + (aInv - lightPositionAndSize.xy) * 10000, 0, 1);
|
||
//EmitVertex();
|
||
|
||
//gl_Position = transform * vec4(bInv + (bInv - lightPositionAndSize.xy) * 10000, 0, 1);
|
||
//EmitVertex();
|
||
|
||
// находим направления к вершинам линии
|
||
/*vec2 deltaA = normalize(aInv - lightPosition);
|
||
vec2 deltaB = normalize(bInv - lightPosition);
|
||
|
||
// находим наклон прямых из центра
|
||
float degA = acos(deltaA.x);
|
||
float degB = acos(deltaB.x);
|
||
|
||
// корректируем угол в зависимости, находимся ли мы в отрицательном Y
|
||
if (deltaA.y < 0) {
|
||
degA = -degA;
|
||
}
|
||
|
||
if (deltaB.y < 0) {
|
||
degB = -degB;
|
||
}
|
||
|
||
/*if (degA < 0) {
|
||
degA = 360 + degA;
|
||
}
|
||
|
||
if (degB < 0) {
|
||
degB = 360 + degB;
|
||
}
|
||
|
||
// определяем, находимся ли мы "сзади"
|
||
if (degA < degB) {
|
||
vec2 temp = aInv;
|
||
aInv = bInv;
|
||
bInv = temp;
|
||
|
||
// находим направления к вершинам линии
|
||
deltaA = normalize(aInv - lightPosition);
|
||
deltaB = normalize(bInv - lightPosition);
|
||
|
||
// находим наклон прямых из центра
|
||
degA = acos(deltaA.x);
|
||
degB = acos(deltaB.x);
|
||
|
||
// корректируем угол в зависимости, находимся ли мы в отрицательном Y
|
||
if (deltaA.y < 0) {
|
||
degA = -degA;
|
||
}
|
||
|
||
if (deltaB.y < 0) {
|
||
degB = -degB;
|
||
}
|
||
|
||
if (degA < 0) {
|
||
degA = 360 + degA;
|
||
}
|
||
|
||
if (degB < 0) {
|
||
degB = 360 + degB;
|
||
}
|
||
}*/
|
||
|
||
// поворачиваем наши углы на 90 градусов
|
||
/*degA -= 1.57079632;
|
||
degB += 1.57079632;
|
||
|
||
// Теперь для каждой вершины вычисляем касательную точку на окружности
|
||
vec2 pointA = vec2(cos(degA), sin(degA)) * lightSize + lightPosition;
|
||
vec2 pointB = vec2(cos(degB), sin(degB)) * lightSize + lightPosition;
|
||
|
||
// мы нашли касательные точки, теперь просто надо провести прямые начиная от вершин
|
||
|
||
// это у нас "hard shadows"
|
||
gl_Position = transform * vec4(aInv + (aInv - pointA) * 10000, 0, 1);
|
||
EmitVertex();
|
||
|
||
gl_Position = transform * vec4(bInv + (bInv - pointB) * 10000, 0, 1);
|
||
EmitVertex();
|
||
|
||
gl_Position = b;
|
||
EmitVertex();
|
||
|
||
EndPrimitive();*/
|
||
}
|