summaryrefslogtreecommitdiff
path: root/gfx
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2026-02-28 13:49:27 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2026-02-28 13:54:13 +0000
commit9ecec749060a05705d7c7eb200949e17a84702a1 (patch)
treedb36f49685662d6c423eb196fc5e64c5f89f5daa /gfx
parentUse RelativeDistance in Camera near/fear and expose member variables (diff)
downloadilt-9ecec749060a05705d7c7eb200949e17a84702a1.tar.bz2
ilt-9ecec749060a05705d7c7eb200949e17a84702a1.tar.xz
ilt-9ecec749060a05705d7c7eb200949e17a84702a1.zip
Add BillboardProgram to SceneShader
The implementation is overly simple/incomplete, I'm not even convince what is there is right, but it's a decent start.
Diffstat (limited to 'gfx')
-rw-r--r--gfx/gl/sceneRenderer.cpp1
-rw-r--r--gfx/gl/sceneShader.cpp14
-rw-r--r--gfx/gl/sceneShader.h12
-rw-r--r--gfx/gl/shaders/billboard.frag28
-rw-r--r--gfx/gl/shaders/billboard.vert23
5 files changed, 77 insertions, 1 deletions
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index 463ee8a..e693787 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -107,6 +107,7 @@ SceneRenderer::render(const SceneProvider & scene) const
glEnable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_PROGRAM_POINT_SIZE);
scene.content(shader, camera);
}
diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp
index 72cde91..43e54a5 100644
--- a/gfx/gl/sceneShader.cpp
+++ b/gfx/gl/sceneShader.cpp
@@ -1,4 +1,6 @@
#include "sceneShader.h"
+#include <gfx/gl/shaders/billboard-frag.h>
+#include <gfx/gl/shaders/billboard-vert.h>
#include <gfx/gl/shaders/dynamicPoint-vert.h>
#include <gfx/gl/shaders/dynamicPointInst-vert.h>
#include <gfx/gl/shaders/fixedPoint-vert.h>
@@ -30,7 +32,7 @@ inline void
SceneShader::allPrograms(auto member, auto &&... ps) const
{
for (const auto & prog : std::initializer_list<const SceneProgram *> {&basic, &basicInst, &water, &landmass,
- &absolute, &pointLightInst, &spotLightInst, &networkStraight, &networkCurve}) {
+ &absolute, &pointLightInst, &spotLightInst, &networkStraight, &networkCurve, &billboard}) {
(prog->*member)(std::forward<decltype(ps)>(ps)...);
}
}
@@ -89,6 +91,16 @@ SceneShader::BasicProgram::use(Location const & location) const
setModel(location);
}
+SceneShader::BillboardProgram::BillboardProgram() : SceneProgram {billboard_vert, billboard_frag} { }
+
+void
+SceneShader::BillboardProgram::use(RelativeDistance size, RelativePosition3D centre) const
+{
+ Program::use();
+ glUniform(sizeLoc, size);
+ glUniform(centreLoc, centre);
+}
+
void
SceneShader::LandmassProgram::use(const glm::vec3 colourBias) const
{
diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h
index 47d4397..faba4a4 100644
--- a/gfx/gl/sceneShader.h
+++ b/gfx/gl/sceneShader.h
@@ -32,6 +32,17 @@ class SceneShader {
RequiredUniformLocation modelPosLoc {*this, "modelPos"};
};
+ class BillboardProgram : public SceneProgram {
+ public:
+ BillboardProgram();
+
+ void use(RelativeDistance size, RelativePosition3D centre) const;
+
+ private:
+ RequiredUniformLocation sizeLoc {*this, "size"};
+ RequiredUniformLocation centreLoc {*this, "centre"};
+ };
+
class AbsolutePosProgram : public SceneProgram {
public:
using Program::use;
@@ -74,6 +85,7 @@ public:
BasicProgram basic;
WaterProgram water;
AbsolutePosProgram basicInst, absolute, spotLightInst, pointLightInst;
+ BillboardProgram billboard;
LandmassProgram landmass;
NetworkProgram networkStraight, networkCurve;
diff --git a/gfx/gl/shaders/billboard.frag b/gfx/gl/shaders/billboard.frag
new file mode 100644
index 0000000..1e2c4ae
--- /dev/null
+++ b/gfx/gl/shaders/billboard.frag
@@ -0,0 +1,28 @@
+#version 460 core
+
+const float tau = 6.28318531;
+
+layout(binding = 0) uniform sampler2DArray billboardDepth;
+layout(binding = 1) uniform sampler2DArray billboardNormal;
+layout(binding = 2) uniform sampler2DArray billboardAlbedo;
+uniform mat4 viewProjection;
+uniform float size;
+
+include(`materialOut.glsl')
+
+flat in ivec3 ModelPos;
+flat in float Yaw;
+flat in float Depth;
+
+void
+main()
+{
+ int viewAngle = int(round(8 * Yaw / tau)) % 8;
+ vec3 texel = vec3(gl_PointCoord * vec2(-1, 1) + vec2(1, 0), viewAngle);
+ gAlbedoSpec = texture(billboardAlbedo, texel);
+ if (gAlbedoSpec.a < 0.5) {
+ discard;
+ }
+ gPosition = ivec4(ModelPos + vec3(0, 0, size * 2 * (1 - gl_PointCoord.y)), 1);
+ gNormal = texture(billboardNormal, texel) * vec4(-1, -1, 1, 1);
+}
diff --git a/gfx/gl/shaders/billboard.vert b/gfx/gl/shaders/billboard.vert
new file mode 100644
index 0000000..2d73084
--- /dev/null
+++ b/gfx/gl/shaders/billboard.vert
@@ -0,0 +1,23 @@
+#version 460 core
+
+uniform mat4 viewProjection;
+uniform ivec4 viewPort;
+uniform ivec3 viewPoint;
+uniform vec3 centre;
+uniform float size;
+layout(location = 0) in ivec3 modelPos;
+layout(location = 1) in float yaw;
+
+flat out ivec3 ModelPos;
+flat out float Yaw;
+flat out float Depth;
+
+void
+main()
+{
+ ModelPos = modelPos;
+ Yaw = yaw;
+ gl_Position = viewProjection * vec4(modelPos - viewPoint + centre, 1);
+ Depth = gl_Position.w;
+ gl_PointSize = (viewPort.w * size * 2) / gl_Position.w;
+}