KStarbound/src/main/resources/shaders/soft_light_geometry.gsh
2022-09-14 20:28:19 +07:00

151 lines
3.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();*/
}