102 lines
2.8 KiB
C++
102 lines
2.8 KiB
C++
#pragma once
|
|
|
|
inline const char* vertPart = R"(
|
|
#version 330 core
|
|
|
|
#ifndef USE_2D_BILLBOARD
|
|
#define USE_2D_BILLBOARD 1 //2D mesh => 1 ; 3D mesh => 0
|
|
#endif
|
|
|
|
// Mesh-Positions-Stream (per-vertex)
|
|
#if USE_2D_BILLBOARD
|
|
layout(location = 0) in vec2 meshPos; // z.B. Quad-Ecken (-0.5..0.5)
|
|
#else
|
|
layout(location = 0) in vec3 meshPos; // echte 3D-Mesh-Position
|
|
#endif
|
|
|
|
// Instanz-Attribute
|
|
layout(location = 1) in vec3 inPosition; // Partikelzentrum (Welt)
|
|
layout(location = 2) in float inSize; // Uniform-Scale
|
|
layout(location = 3) in float inRotation; // Rotation (nur im Billboard-Modus genutzt)
|
|
layout(location = 4) in vec4 inColor; // RGBA
|
|
|
|
uniform mat4 prMatrix;
|
|
uniform mat4 camMatrix;
|
|
|
|
out VS_OUT {
|
|
vec4 color;
|
|
#if USE_2D_BILLBOARD
|
|
vec2 uv; // optional: für runde Maske im FS
|
|
#endif
|
|
} vs;
|
|
|
|
// Kameraachsen aus View-Matrix (Spalten 0/1)
|
|
vec3 CameraRight(mat4 view) { return vec3(view[0][0], view[1][0], view[2][0]); }
|
|
vec3 CameraUp (mat4 view) { return vec3(view[0][1], view[1][1], view[2][1]); }
|
|
|
|
|
|
void main()
|
|
{
|
|
vs.color = inColor;
|
|
|
|
#if USE_2D_BILLBOARD
|
|
// 2D-Rotation im Billboard-Raum
|
|
float c = cos(inRotation);
|
|
float s = sin(inRotation);
|
|
vec2 q = vec2(c * meshPos.x - s * meshPos.y,
|
|
s * meshPos.x + c * meshPos.y);
|
|
|
|
vec3 right = CameraRight(camMatrix);
|
|
vec3 up = CameraUp(camMatrix);
|
|
|
|
// Uniform-Scaling über inSize
|
|
vec3 worldPos = inPosition + (q.x * inSize) * right
|
|
+ (q.y * inSize) * up;
|
|
|
|
// optionales UV für Kreis-Maske
|
|
vs.uv = meshPos * 0.5 + 0.5; // falls meshPos in -1..1: nimm (meshPos*0.5+0.5)
|
|
#else
|
|
// echtes 3D-Mesh: nur uniform Scale + Translation
|
|
vec3 worldPos = inPosition + meshPos * inSize;
|
|
#endif
|
|
|
|
gl_Position = prMatrix * camMatrix * vec4(worldPos, 1.0);
|
|
}
|
|
)";
|
|
|
|
inline const char* fragPart = R"(
|
|
#version 330 core
|
|
|
|
#ifndef USE_2D_BILLBOARD
|
|
#define USE_2D_BILLBOARD 1
|
|
#endif
|
|
|
|
// Optional runde Maske an/aus (nur sinnvoll im Billboard-Modus mit z.B. Quad)
|
|
#ifndef USE_ROUND_MASK
|
|
#define USE_ROUND_MASK 0
|
|
#endif
|
|
|
|
in VS_OUT {
|
|
vec4 color;
|
|
#if USE_2D_BILLBOARD
|
|
vec2 uv;
|
|
#endif
|
|
} fs;
|
|
|
|
layout(location = 0) out vec4 outColor;
|
|
|
|
void main()
|
|
{
|
|
#if USE_2D_BILLBOARD && USE_ROUND_MASK
|
|
// weiche Kreis-Maske (aus uv ~ 0..1)
|
|
vec2 c = fs.uv * 2.0 - 1.0; // nach [-1..1]
|
|
float r = length(c);
|
|
if (r > 1.0) discard;
|
|
float alpha = 1.0 - smoothstep(0.95, 1.0, r);
|
|
outColor = vec4(fs.color.rgb, fs.color.a * alpha);
|
|
#else
|
|
outColor = fs.color;
|
|
#endif
|
|
}
|
|
)";
|