diff --git a/zoneb/bin/data/shaders/particles/draw.frag b/zoneb/bin/data/shaders/particles/draw.frag index 3b8042a..e734ee0 100755 --- a/zoneb/bin/data/shaders/particles/draw.frag +++ b/zoneb/bin/data/shaders/particles/draw.frag @@ -16,5 +16,5 @@ void main() fragColor = vec4(1);//vec4(texture(u_world, texCoordVarying.st).rgb,1); // fragColor = vec4(texCoordVarying.st/100,1.0,1.0);//vec4(texture(u_world, texCoordVarying.st).rgb,1); // fragColor = vec4(texture(u_v4l2cam, texCoordVarying.st).rgb,1); - fragColor = vec4(texture(imageTexture, vec2(vTemperature*1024, 0.5)).xyz,max(0, 1 - vAge)); + fragColor = vec4(texture(imageTexture, vec2(vTemperature*1024, 0.5)).xyz,max(0, 1 - pow(vAge,4))); } diff --git a/zoneb/bin/data/shaders/particles/update.frag b/zoneb/bin/data/shaders/particles/update.frag index 2ca62b6..95fbbf6 100755 --- a/zoneb/bin/data/shaders/particles/update.frag +++ b/zoneb/bin/data/shaders/particles/update.frag @@ -4,6 +4,7 @@ uniform sampler2DRect particles0; uniform sampler2DRect particles1; uniform sampler2DRect particles2; +uniform sampler2DRect particles3; uniform sampler2DRect u_depth; uniform sampler2DRect u_world; @@ -16,11 +17,15 @@ uniform vec3 mouse; uniform float radiusSquared; uniform float elapsed; +uniform vec3 uHottest0; +uniform vec3 uHottest1; + in vec2 texCoordVarying; layout(location = 0) out vec4 posOut; layout(location = 1) out vec4 velOut; layout(location = 2) out vec4 misOut; +layout(location = 3) out vec4 tarOut; vec3 random3(vec3 c) { @@ -98,15 +103,28 @@ float simplex3d_fractal(vec3 m) { +0.0666667*simplex3d(8.0*m); } +vec2 stToV4l2(vec2 v) { + v *= 1.5; + v.s -= 85; + v.t -= 130; + return v; +} + +vec2 v4l2ToSt(vec2 v) { + v.s += 85; + v.t += 130; + v /= 1.5; + return v; +} + void main() { - vec2 v4l2st = texCoordVarying.st; - v4l2st /= 3; - v4l2st -= vec2(0.5); - v4l2st *= 1.65; - v4l2st += vec2(0.5); - v4l2st.s -= 35; - v4l2st.t -= 60; + vec3 pos = texture(particles0, texCoordVarying.st).xyz; + vec3 vel = texture(particles1, texCoordVarying.st).xyz; + vec3 misc = texture(particles2, texCoordVarying.st).xyz; + vec4 target = texture(particles3, texCoordVarying.st).xyzw; + + vec2 v4l2st = stToV4l2(texCoordVarying.st); float thermo = texture2D(u_v4l2cam, v4l2st).r; float depth = texture(u_depth, texCoordVarying.st).x; @@ -114,24 +132,29 @@ void main() float vValid = (depth != 0 && ray.x != 0 && ray.y != 0) ? 1 : 0; - if(depth < 0.012) vValid = 0; - if(depth > 0.04) vValid = 0; + // if(depth < 0.012) vValid = 0; + // if(depth > 0.04) vValid = 0; vec4 posWorld = vec4(1); posWorld.z = -depth * 65535.0; // Remap to float range. posWorld.x = ray.x * posWorld.z; posWorld.y = ray.y * posWorld.z; - vec3 pos = texture(particles0, texCoordVarying.st).xyz; - vec3 vel = texture(particles1, texCoordVarying.st).xyz; - vec3 misc = texture(particles2, texCoordVarying.st).xyz; float age = misc.y; - if(vValid == 1) { + if(age > 1) { + target.w = 0; + if(vValid == 1) { + age = 0; + } + } + + if(vValid == 1 && target.w == 0) { pos = posWorld.xyz; age = 0; + target.xyz = pos; } else { - age += 0.002; + age += 0.02; thermo = misc.x; } @@ -141,17 +164,45 @@ void main() force.x += cos(th) * cos(phi); force.y += sin(th) * cos(phi); force.z += sin(phi); - force *= 50; - // accelerate - vel += elapsed * force; + force *= 100; + + if(age < 0.001) { + target.w = 0; + if(random3(pos).x > length(v4l2st - uHottest0.st)/100) { + vec2 h = v4l2ToSt(uHottest1.st); + vec4 hray = texture(u_world, h); + float hdepth = -depth * 65535.0; + if(hdepth == 0) hdepth = -0.01 * 65535.0; + vec3 H = vec3(hray.xy * hdepth, hdepth); + target.xyz = H; + target.w = 1; + } + else if(random3(pos).x > length(v4l2st - uHottest1.st)/100) { + vec2 h = v4l2ToSt(uHottest0.st); + vec4 hray = texture(u_world, h); + float hdepth = -depth * 65535.0; + if(hdepth == 0) hdepth = -0.01 * 65535.0; + vec3 H = vec3(hray.xy * hdepth, hdepth); + target.xyz = H; + target.w = 1; + } + } + + if(target.w > 0) { + force += (target.xyz - pos) * 0.5; + } // damping vel *= 0.95; + // accelerate + vel += elapsed * force; + // move pos += elapsed * vel; posOut = vec4(pos, 1.0); velOut = vec4(vel, 0.0); misOut = vec4(thermo, age, 0, 0); + tarOut = vec4(target); } \ No newline at end of file diff --git a/zoneb/src/ofApp.cpp b/zoneb/src/ofApp.cpp index c9d401a..fa368e4 100644 --- a/zoneb/src/ofApp.cpp +++ b/zoneb/src/ofApp.cpp @@ -40,7 +40,9 @@ void ofApp::setupThermal() // we use a texture because the ofxV4L2 class has no draw method (yet) // we use GL_LUMINANCE because the ofxV4L2 class supports only grayscale (for now) - v4l2Tex.allocate(camWidth, camHeight, GL_LUMINANCE); + v4l2Tex.allocate(camWidth, camHeight, GL_RGB); + + v4l2Pixels.allocate(camWidth, camHeight, OF_PIXELS_RGB); } void ofApp::setup() @@ -64,7 +66,7 @@ void ofApp::setup() unsigned w = 512; unsigned h = 512; - particles.init(w, h, OF_PRIMITIVE_POINTS, false, 3); + particles.init(w, h, OF_PRIMITIVE_POINTS, false, 4); particles.loadShaders("shaders/particles/update", "shaders/particles/draw"); @@ -81,11 +83,24 @@ void ofApp::setup() } } particles.loadDataTexture(ofxGpuParticles::POSITION, particlePosns); - delete[] particlePosns; // initial velocities particles.zeroDataTexture(ofxGpuParticles::VELOCITY); - particles.zeroDataTexture(ofxGpuParticles::MISC); + for (unsigned y = 0; y < h; ++y) + { + for (unsigned x = 0; x < w; ++x) + { + unsigned idx = y * w + x; + particlePosns[idx * 4] = 0; // + particlePosns[idx * 4 + 1] = ofRandomf(); // age + particlePosns[idx * 4 + 2] = 0.f; // + particlePosns[idx * 4 + 3] = 0.f; // + } + } + particles.loadDataTexture(ofxGpuParticles::MISC, particlePosns); + particles.zeroDataTexture(3); + + delete[] particlePosns; particles.whateverImages.insert({"u_depth", kinectDevice.getDepthTex()}); particles.whateverImages.insert({"u_world", kinectDevice.getDepthToWorldTex()}); @@ -107,11 +122,31 @@ void ofApp::updateThermal() v4l2Cam.grabFrame(); if (v4l2Cam.isNewFrame()) { - ofPixels p; - p.allocate(camWidth, camHeight, OF_PIXELS_RGB); - for (int i = 0; i < camHeight * camWidth; i++) - p.setColor(i, v4l2Cam.getPixels()[i]); - v4l2Tex.allocate(p); + hotspots.clear(); + int count = 0; + for (int i = 0; i < camHeight; i++) + { + for (int j = 0; j < camWidth; j++) + { + int a = v4l2Cam.getPixels()[count / 3]; + v4l2Pixels.setColor(count++, a); + v4l2Pixels.setColor(count++, a); + v4l2Pixels.setColor(count++, a); + if (i % 4 == 0 && j % 4 == 0 && i > 80) + { + hotspots.push_back(ofVec3f(j, i, a)); + } + } + } + v4l2Tex.allocate(v4l2Pixels); + struct + { + bool operator()(ofVec3f a, ofVec3f b) const + { + return a.z > b.z; + } + } compareZThermal; + std::sort(hotspots.begin(), hotspots.end(), compareZThermal); } } @@ -131,6 +166,14 @@ void ofApp::onParticlesUpdate(ofxShader &shader) shader.setUniform2i("uFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); shader.setUniform2i("uDepthFrameSize", kinectDevice.getDepthTex().getWidth(), kinectDevice.getDepthTex().getHeight()); + + shader.setUniform3f("uHottest0", hotspots.at(0)); + for(int i = 1; i < hotspots.size(); i++) { + if(hotspots.at(i).distance(hotspots.at(0)) > 100) { + shader.setUniform3f("uHottest1", hotspots.at(i)); + break; + } + } } void ofApp::onParticlesDraw(ofxShader &shader) @@ -172,7 +215,6 @@ void ofApp::draw() particles.draw(); cam.end(); } - drawDebug(); } diff --git a/zoneb/src/ofApp.h b/zoneb/src/ofApp.h index 407809f..f4e4d37 100644 --- a/zoneb/src/ofApp.h +++ b/zoneb/src/ofApp.h @@ -48,8 +48,11 @@ private: ofxV4L2 v4l2Cam; ofTexture v4l2Tex; + ofPixels v4l2Pixels; ofFloatImage gradient; ofxGpuParticles particles; + + std::vector hotspots; };