Files
TSE/TSE_OpenGlImpl/src/shader/basicParticleShaderGLSL.hpp

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
}
)";