Metaballs: Let's get together !!!
Conversion shaders from
https://www.shadertoy.com/view/4lKXzdmetaballs.vs#version 330
// Входные атрибуты
layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 vertexTexCoord;
layout(location = 2) in vec3 vertexNormal;
layout(location = 3) in vec4 vertexColor;
// Выходные переменные
out vec2 fragCoord;
// Uniform-переменные
uniform mat4 mvp;
void main()
{
fragCoord = vertexPosition.xy;
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
metaballs.fs#version 330
// Входные переменные из вершинного шейдера
in vec2 fragCoord;
out vec4 fragColor;
// Uniform-переменные
uniform vec2 resolution;
const float TWO_PI = 6.28318530718;
const float vertices = 8.;
const float startIndex = vertices;
const float endIndex = vertices * 2.;
float metaballs
(vec2 uv
, float time) { float size = 0.5;
float radSegment = TWO_PI / vertices;
for(float i = startIndex; i < endIndex; i++) {
float rads = i * radSegment;
float radius
= 1.
+ 1.5 * sin(time + rads
* 1.
); vec2 ctrlPoint
= radius
* vec2
(sin(rads
), cos(rads
)); size
+= 1.
/ pow(i
, distance
(uv
, ctrlPoint
)); }
return size;
}
void main() {
vec2 uv = (2. * fragCoord - resolution.xy) / resolution.y;
uv *= 3.;
float col
= metaballs
(uv
, time); col = smoothstep(0., fwidth(col)*1.5, col - 1.);
fragColor
= vec4
(1.
- sqrt(vec3
(col
)), 1.
);}
MetaballsExampleprogram MetaballsExample;
uses
raylib, math;
const
ScreenWidth = 800;
ScreenHeight = 600;
var
Shader: TShader;
TimeLoc: Integer;
ResLoc: Integer;
Time: Single;
Resolution: array[0..1] of Single; // Массив для передачи разрешения
begin
// Инициализация окна
InitWindow(ScreenWidth, ScreenHeight, 'Metaballs Example with Raylib');
SetTargetFPS(60);
// Загрузка шейдера
Shader := LoadShader('metaballs.vs', 'metaballs.fs');
// Получение location uniform-переменных
TimeLoc := GetShaderLocation(Shader, 'time');
ResLoc := GetShaderLocation(Shader, 'resolution');
// Установка разрешения
Resolution[0] := ScreenWidth;
Resolution[1] := ScreenHeight;
SetShaderValue(Shader, ResLoc, @Resolution, SHADER_UNIFORM_VEC2);
while not WindowShouldClose do
begin
// Обновление времени
Time := GetTime();
SetShaderValue(Shader, TimeLoc, @Time, SHADER_UNIFORM_FLOAT);
// Отрисовка
BeginDrawing();
ClearBackground(BLACK);
BeginShaderMode(Shader);
// Рисуем прямоугольник на весь экран для применения шейдера
DrawRectangle(0, 0, ScreenWidth, ScreenHeight, WHITE);
EndShaderMode();
// Вывод FPS
DrawFPS(10, 10);
EndDrawing();
end;
// Очистка
UnloadShader(Shader);
CloseWindow();
end.