Displaying Image on top of 3D

Hi there,

I have the following sketch where I'm trying to display a changing image on top of my 3D object. This image (logo) gets fed into a function which returns it with a gradient overlay.

Unfortunately, when the image gets fed through this function it won't show, but it works when I deactivate P3D. Similarly, if I do: image(logo, 0,0) then it works.

What's going on?!

Thanks in advance, Charles

void setup() {
  size(800, 500, P3D);
}

void draw() {
  background(gradient);

  camera(camera.x, camera.y, camera.z, 0, 0, 50, 0, 0, -1);


  // 3D STUFF

  hint(DISABLE_DEPTH_TEST);
  camera();
  fill(0);
  image(gradient(logo), width*0.82, height*0.87);
  text("HELLO", width/2, height/2);
  hint(ENABLE_DEPTH_TEST);
}

PImage gradient(PImage pin) {

  PImage pout = createImage(pin.width, pin.height, HSB);
  logo.loadPixels();

  for (int x = 0; x < pin.width; x++) {

    for (int y = 0; y < pin.height; y++) {

      int loc = x + (y*pin.width);

      if ( alpha(pin.pixels[loc]) != alpha(255)) {

        float alpha = alpha(logo.pixels[loc]);
        pout.pixels[loc] = color(colour((cc-x/4)), 255, 255, alpha);
      }
    }
  }
  pout.updatePixels();

  if (frameCount % 3 == 0)cc+=1;
  return pout;
}

Answers

  • edited June 2016

    Dunno much about P3D. I mostly stick w/ JAVA2D or FX2D only. 8-|
    Anyways, I've tweaked your gradient() function. Got no idea whether it's correct though: :-\"

    // forum.Processing.org/two/discussion/17314/
    // displaying-image-on-top-of-3d#Item_1
    
    // GoToLoop (2016/Jun/26)
    
    PImage logo, grad;
    color cc;
    
    void setup() {
      size(800, 500, P3D);
      smooth(4);
      fill(#FFFF00);
    
      grad = ( logo = loadImage("logo.png") ).get();
    }
    
    void draw() {
      clear();
    
      hint(DISABLE_DEPTH_TEST);
      image(gradient(logo, grad, cc), width*.01, height*.01);
      text("HELLO", width>>1, height>>1);
      hint(ENABLE_DEPTH_TEST);
    
      if ((frameCount & 3) == 0)  ++cc;
    }
    
    static final PImage gradient(PImage src, PImage out, color c) {
      src.loadPixels();
      color[] s = src.pixels, o = out.pixels;
      int len = s.length, w = src.width;
    
      for (int i = 0; i < len; ++i) {
        color a = s[i]>>>030;
        color r = min(0xFF, c - (i%w >> 2));
        o[i] = a<<030 | r<<020 | 0xFFFF;
      }
    
      out.updatePixels();
      return out;
    }
    
  • edited June 2016

    I like the that you've used bitshifting but I'm still trying to get my head around it. What is the PImage out and Color c you've added as inputs?

    See in the image below what I'm trying to achieve; it cycles from 0 to 180 in the hue, from left to right. Hence the increment (cc+=1) every 3ms from the code I initially posted.

    Screen Shot 2016-06-26 at 22.39.26

  • edited June 2016

    Here's the "lookup" function I've made so I get a continuous gradient:

    int colour(int in) {
    
      if ((in / 180) % 2 == 0) return (in%180);
      else return  180-(in%180);
    }
    

    PS: Your method work but doesn't do what I'm looking for

  • edited June 2016

    What is the PImage out and color c you've added as inputs?

    Given your original code access a variable called cc, which I dunno where it comes from, I had to invent 1 on my own, assuming its datatype is color.

    Thus that's a very important tip when posting code for others to "decipher".
    Post the sections where the variables are declared and also where they're initialized as well.

    Back to the subject, I thought it was clear that parameter c represented your mysterious global cc.
    I even invoked gradient() like this: gradient(logo, grad, cc).

    Global variable grad is a clone of logo. I've used method get() in order to clone it btW:
    https://Processing.org/reference/PImage_get_.html
    The aim was merely to avoid createImage() all the time when invoking gradient(). :P

    Therefore parameter src represents global logo.
    out, which is your former pout, represents the logo's clone grad.
    And parameter c is your global cc.

  • edited June 2016

    See in the image below what I'm trying to achieve; it cycles from 0 to 180 in the hue,

    So you're relying on colorMode() set to HUE. Again I haven't spotted that in your posted code!
    Problem is that pixels[] is always aRGB. Then we need to rely on function color().
    Something I was trying to avoid, HEHEH.

  • edited June 2016

    I've managed to get it working by tweaking your method, if you have any ideas on how to convert any of it to bit shifting, please share :)

    int cc = 0;
    PImage logo;
    
    void setup() {
      size(800, 500, P3D);
      colorMode(HSB);
       logo = loadImage("logo.png");
    }
    
    void draw() {
      background(gradient);
    
      camera(camera.x, camera.y, camera.z, 0, 0, 50, 0, 0, -1);
    
    
      // 3D STUFF
    
      hint(DISABLE_DEPTH_TEST);
      camera();
      fill(0);
      image(gradient(logo), width*0.82, height*0.87);
      text("HELLO", width/2, height/2);
      hint(ENABLE_DEPTH_TEST);
    }
    
    PImage gradient2(PImage src) {
      src.loadPixels();
      PImage out = src;
      color[] s = src.pixels;
      int w = src.width;
    
      for (int x = 0; x < w; ++x) {
        for (int y = 0; y < src.height; ++y) {
    
          int i = x + (y*w);
    
          int a = (s[i] >> 24) & 0xFF;
    
          if (a > 0) {
            s[i] = color(colour(cc-x/4), 255, 255, a);
          }
        }
      }
    
      if (frameCount % 3 == 0)cc+=1; 
    
      out.updatePixels(); 
      return out;
    }
    
    int colour(int in) {
      if ((in / 180) % 2 == 0) return in%180;
      else return  180-(in%180);
    }
    

    Here's the picture I'm loading as logo in which I know that if the alpha is not 255 then I need to change the colour.

Sign In or Register to comment.