feat: add counter-rotating wireframe shells

Layer E draws two concentric wireframe shells of the sphere with
additive blending: an outer blue shell breathing with bass and an
inner magenta shell pulsing with kick, spinning opposite ways.
This commit is contained in:
L'électron rare
2026-05-18 19:13:11 +02:00
parent 914e52deaf
commit d8aa727887
5 changed files with 47 additions and 4 deletions
+5 -3
View File
@@ -3,7 +3,8 @@
uniform sampler2D spectroTex; // width = time, height = freq, R32F [0,1]
uniform float scrollOffset;
uniform int colormapId;
uniform int renderMode; // 0 = skin, 1 = points
uniform int renderMode; // 0 = skin, 1 = points, 2 = wireframe
uniform vec4 shellTint; // rgb tint + alpha for wireframe / shells
in vec2 vSphereUV;
in vec3 vViewPos;
@@ -47,8 +48,9 @@ void main() {
}
if (renderMode == 2) {
// wireframe: bright unlit colormap lines
fragColor = vec4(col * 1.4 + vec3(0.06), 1.0);
// wireframe / concentric shells: bright lines, tinted per draw
vec3 wc = (col * 1.4 + vec3(0.06)) * shellTint.rgb;
fragColor = vec4(wc, shellTint.a);
return;
}
+32 -1
View File
@@ -99,10 +99,41 @@ void SphereViz::drawPoints() {
shader_.end();
}
void SphereViz::drawWireframe() {
void SphereViz::drawWireMesh(const ofFloatColor& tint) {
shader_.begin();
bindUniforms();
shader_.setUniform1i("renderMode", 2);
shader_.setUniform4f("shellTint", tint.r, tint.g, tint.b, tint.a);
mesh_.drawWireframe();
shader_.end();
}
void SphereViz::drawWireframe() {
drawWireMesh(ofFloatColor(1.0f, 1.0f, 1.0f, 1.0f));
}
void SphereViz::drawShells(float t, float bass, float kick) {
ofDisableDepthTest();
ofEnableBlendMode(OF_BLENDMODE_ADD);
// outer shell: larger, counter-spinning, blue, breathes with bass
ofPushMatrix();
ofRotateYDeg(-t * 23.0f);
ofRotateXDeg( t * 14.0f);
const float so = 1.40f + bass * 0.25f;
ofScale(so, so, so);
drawWireMesh(ofFloatColor(0.28f, 0.62f, 1.00f, 0.55f));
ofPopMatrix();
// inner shell: smaller, opposite spin, magenta, pulses with kick
ofPushMatrix();
ofRotateYDeg( t * 34.0f);
ofRotateXDeg(-t * 23.0f);
const float si = 0.62f + kick * 0.30f;
ofScale(si, si, si);
drawWireMesh(ofFloatColor(1.00f, 0.42f, 0.80f, 0.60f));
ofPopMatrix();
ofDisableBlendMode();
ofEnableDepthTest();
}
+2
View File
@@ -20,10 +20,12 @@ public:
void drawSkin();
void drawPoints();
void drawWireframe();
void drawShells(float time, float bass, float kick);
void setColormap(int id) { colormapId_ = id; }
private:
void bindUniforms();
void drawWireMesh(const ofFloatColor& tint);
std::unique_ptr<oscope::SpectrogramBuffer> spectro_;
ofVboMesh mesh_;
+5
View File
@@ -56,6 +56,8 @@ void ofApp::update() {
if (!ofGetMousePressed())
spin_ += (8.0f + 80.0f * energy) * dt;
pulse_ += (1.0f + 0.20f * kick - pulse_) * 0.25f;
bass_ = 0.5f * (b1.bass + b2.bass);
kick_ = kick;
sphere_.setColormap(colormap_);
sphere_.pushSpectrogramColumn(analyzerCh1_.magDown(),
@@ -74,6 +76,7 @@ void ofApp::draw() {
if (layerA_) sphere_.drawSkin();
if (layerD_) sphere_.drawWireframe();
if (layerC_) sphere_.drawPoints();
if (layerE_) sphere_.drawShells(t, bass_, kick_);
if (layerB_) rings_.draw();
ofPopMatrix();
cam_.end();
@@ -88,6 +91,7 @@ void ofApp::drawHud() {
hud += std::string("[2] rings ") + (layerB_ ? "on" : "off") + "\n";
hud += std::string("[3] points ") + (layerC_ ? "on" : "off") + "\n";
hud += std::string("[4] wire ") + (layerD_ ? "on" : "off") + "\n";
hud += std::string("[5] shells ") + (layerE_ ? "on" : "off") + "\n";
hud += std::string("[c] colormap [space] ") +
(frozen_ ? "frozen" : "live");
ofDrawBitmapString(hud, 16, 24);
@@ -100,6 +104,7 @@ void ofApp::keyPressed(int key) {
case '2': layerB_ = !layerB_; break;
case '3': layerC_ = !layerC_; break;
case '4': layerD_ = !layerD_; break;
case '5': layerE_ = !layerE_; break;
case 'c':
case 'C': colormap_ = (colormap_ + 1) % 2; break;
case ' ': frozen_ = !frozen_; break;
+3
View File
@@ -36,9 +36,12 @@ private:
bool layerB_ = true;
bool layerC_ = true;
bool layerD_ = true;
bool layerE_ = true;
int colormap_ = 0;
float scopeSr_ = 16.0e6f;
float spin_ = 0.0f;
float pulse_ = 1.0f;
float bass_ = 0.0f;
float kick_ = 0.0f;
std::string statusText_;
};