# 3D image transform question

**URL:** https://discourse.processing.org/t/3d-image-transform-question/33252
**Category:** Coding Questions
**Created:** [November 2, 2021, 8:56am UTC](https://discourse.processing.org/t/3d-image-transform-question/33252 "2021-11-02T08:56:24Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![zlaccu](https://avatars.discourse-cdn.com/v4/letter/z/278dde/32.png) [@zlaccu](https://discourse.processing.org/u/zlaccu)
#### Post date: [November 2, 2021, 8:56am UTC](https://discourse.processing.org/t/3d-image-transform-question/33252/1 "2021-11-02T08:56:24Z")

</div>

hi there! im recreating this effect : [Login • Instagram](https://www.instagram.com/p/BWzmk7CjiQU/?utm_source=ig_web_copy_link)  
but my looks not very good.  
this is my looks like:

 ![Snipaste_2021-11-02_16-55-40](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/d9036349bb5e3d32e8161adbdc10ef054a7bf95e.jpeg)  
I think that in the original video, where the gray value is high, It’s not that the height of boxes change, but more boxes are generated, how can i made that? Then I used sin() to control the switch of two pictures, but it’s not good, is there any other good choice?

---

<div class="post-metadata">

### Author: ![zlaccu](https://avatars.discourse-cdn.com/v4/letter/z/278dde/32.png) [@zlaccu](https://discourse.processing.org/u/zlaccu)
#### Post date: [November 2, 2021, 8:57am UTC](https://discourse.processing.org/t/3d-image-transform-question/33252/2 "2021-11-02T08:57:17Z")

</div>

My code:  
\<

```auto
PImage source1, source2;
PImage destination;
float t = 1;

void setup() {
  size(1000, 1000, P3D);
  source1 = loadImage("11.jpg");
  source2 = loadImage("22.jpg");
  destination = createImage(width, height, RGB);
}

void draw() {
  background(0);
  float tiles = 500;
  float tileSize = width/tiles;

  directionalLight(126, 126, 126, 1, -1, 0);
   directionalLight(126, 126, 126, 1, -1, 0);
  ambientLight(100, 100, 100);

  source1.loadPixels();
  source2.loadPixels();
  destination.loadPixels();
  t += 0.2;
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      int loc = x + y * width;
      color c1 = source1.pixels[loc];
      color c2 = source2.pixels[loc];

      float d1 = brightness(c1);
      float d2 = brightness(c2);
      float d = map(cos(t), 0, 1, d1, d2);

      destination.pixels[loc] = color(d);
    }
  }
  //destination.updatePixels();

  push();
  translate(width/2, height/2);
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(map(mouseY, 0, height, PI, -PI));

  for (int x = 0; x < tiles; x++) {
    for (int y = 0; y < tiles; y++) {
      color c = destination.get(int(x * tileSize), int(y * tileSize));
      float b = map(brightness(c), 0, 255, 1, 0);
      float z = map(b, 0, 1, 100, -100);
      float wave = map(cos(radians(frameCount + z + z )), -1, 1, -2, 2);
      push();
      fill(255);
      translate(x * tileSize - width/2, y * tileSize - height/2, z * wave - 300);
      noStroke();
      box(tileSize * b, tileSize * b, tileSize * b * 10 );
      pop();
    }
  }
  pop();
}

```

---

<div class="post-metadata">

### Author: ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)
#### Post date: [November 2, 2021, 6:41pm UTC](https://discourse.processing.org/t/3d-image-transform-question/33252/3 "2021-11-02T18:41:34Z")

</div>

hi! welcome to the forum!

please format your code with \</\> button so it’s easier to see and copy/paste. also if you can provide example images, that would be better.

what I see in Tim’s video is that when greyscale value is high (or low, I don’t know), the z position of the boxes change - plus, the sizes change at certain threshold. regarding your question with `sin()` as well, I think they are using easing functions to make smooth change. There are libraries like Ani but I found they are confusing so I adapted easing functions from [processing-penner-easing/src at master · jesusgollonet/processing-penner-easing · GitHub](https://github.com/jesusgollonet/processing-penner-easing/tree/master/src)

```auto
// adapted from https://github.com/jesusgollonet/processing-penner-easing/tree/master/src
float easeInOutLinear (float t) {
  float b = 0, c = 1, d = 1;
  return c*t/d + b;
}

float easeInOutQuad(float t) {
  float b = 0, c = 1, d = 1;
  if ((t/=d/2) < 1) return c/2*t*t + b;
  return -c/2 * ((--t)*(t-2) - 1) + b;
}

float easeInOutCubic (float t) {
  float b = 0, c = 1, d = 1;
  if ((t/=d/2) < 1) return c/2*t*t*t + b;
  return c/2*((t-=2)*t*t + 2) + b;
}

float easeInOutQuart(float t) {
  float b = 0, c = 1, d = 1;
  if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
  return -c/2 * ((t-=2)*t*t*t - 2) + b;
}

float easeInOutQuint (float t) {
  float b = 0, c = 1, d = 1;
  if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
  return c/2*((t-=2)*t*t*t*t + 2) + b;
}

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

void draw() {
  background(0);
  float T = millis() * 0.001;
  float t = (T / 2) % 2;
  if (t > 1) t = 2 - t; // back and forth
  float ystep = height / 10;
  float r = 100;
  push();
  {
    translate(0, ystep);
    float x = easeInOutLinear(t);
    ellipse(x * width, 0, r, r);
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    float x = easeInOutQuad(t);
    ellipse(x * width, 0, r, r);
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    float x = easeInOutCubic(t);
    ellipse(x * width, 0, r, r);
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    float x = easeInOutQuart(t);
    ellipse(x * width, 0, r, r);
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    float x = easeInOutQuint(t);
    ellipse(x * width, 0, r, r);
    translate(0, ystep);
  }
  pop();

  push();
  translate(width / 2, 0);
  rectMode(CENTER);
  {
    translate(0, ystep);
    push();
    float x = easeInOutLinear(t);
    rotate(x * PI * 2);
    rect(0, 0, r, r);
    pop();
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    push();
    float x = easeInOutQuad(t);
    rotate(x * PI * 2);
    rect(0, 0, r, r);
    pop();
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    push();
    float x = easeInOutCubic(t);
    rotate(x * PI * 2);
    rect(0, 0, r, r);
    pop();
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    push();
    float x = easeInOutQuart(t);
    rotate(x * PI * 2);
    rect(0, 0, r, r);
    pop();
    translate(0, ystep);
  }
  {
    translate(0, ystep);
    push();
    float x = easeInOutQuint(t);
    rotate(x * PI * 2);
    rect(0, 0, r, r);
    pop();
    translate(0, ystep);
  }
  pop();
}

```

you can see that the lower ones’ movements are more crisp and human like… note that you have to clamp the input values of `easeInOut*` always between 0 to 1.

---

<div class="post-metadata">

### Author: ![zlaccu](https://avatars.discourse-cdn.com/v4/letter/z/278dde/32.png) [@zlaccu](https://discourse.processing.org/u/zlaccu)
#### Post date: [November 3, 2021, 9:02am UTC](https://discourse.processing.org/t/3d-image-transform-question/33252/4 "2021-11-03T09:02:44Z")

</div>

Thank you very much for your answer! I will try your suggestions ! 😉

---

<div class="post-metadata">

### Author: ![zlaccu](https://avatars.discourse-cdn.com/v4/letter/z/278dde/32.png) [@zlaccu](https://discourse.processing.org/u/zlaccu)
#### Post date: [November 3, 2021, 2:12pm UTC](https://discourse.processing.org/t/3d-image-transform-question/33252/6 "2021-11-03T14:12:39Z")

</div>

![Hnet.com-image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/175f020dbf60802ade022622d2cc59d551f26034.gif)  
I’m so excited to share my results to u!  
Finally I made this, not perfect but I think it’s enough cool, I can’t do it without your help! Much appreciated! 🥰
