Praneet Dixit
Praneet Dixit

Reputation: 1425

Background image in p5.js 3D sketch

I have a p5.js 3D sketch. I have to set its background image. I know that we can easily implement it with same background() function in a 2D sketch, but it is not possible in a 3D sketch.

I googled for some hacks and found that I can have a plane with the dimensions of the canvas at the back and then use texture() to set its background image like the below example.

var img;
function preload() {
  img = loadImage("img.png");
}

function setup() { 
  createCanvas(600, 600, WEBGL);
} 

function draw() { 
  background(220);
  
  push();
  texture(img);
  plane(600, 600);
  pop();
}

But the issue is - I have to use orbitControl() in my sketch. Due to this, the background (plane) also moves when I drag around. I want my background to be static (it should not move when I move other objects).

Finally, I resorted to css background-image property to set the background image of the canvas and remove background(255) in the draw() function. But due to this, the background (previous frames) were not overlapped when I dragged objects and were also visible.

How can I implement background image in this case?

My sketch is available at https://editor.p5js.org/praneetdixit1234/sketches/9pN4lA8KB

Upvotes: 4

Views: 1563

Answers (2)

Alex T
Alex T

Reputation: 11

You should render your background and 3d objects to different image surfaces, and then combine them on the canvas.

Here's an example: https://editor.p5js.org/space-haze/sketches/alWGuuXXe

var w = window.innerWidth;
var h = window.innerHeight;
function setup() {

  // create the primary drawing surface
  createCanvas(w, h);
  
  // create a 3d off-screen surface
  img3d = createGraphics(w,h,WEBGL);       
  
}

function draw() {
  // draw our background color/image to canvas
  background(color('purple'));
  
  // render our 3d objects to off-screen surface
  let x = w/3;
  img3d.fill(color('yellow'));
  img3d.stroke(color('black'));
  img3d.strokeWeight(2);
  img3d.camera(x*2,x*2,x*2,0,0,0,0,1,0);
  img3d.box(x);

  // draw our off-screen surface to canvas
  image(img3d,0,0);
}

Upvotes: 0

Helder Sepulveda
Helder Sepulveda

Reputation: 17594

I think your CSS approach is good, just not sure why use cover on the size ...
Your image is 1365px wide but your canvas is only 600px, with cover most of it will be hidden, and the text will not be fully seen, but in the future if you change the image using cover might be fine.

Here is what I used

canvas {
  display: block;
  background-image: url("https://static.vecteezy.com/system/resources/previews/000/118/983/original/free-vector-cityscape.jpg");
  background-size: contain;
  background-repeat: no-repeat;
}

...and don't remove background, set the alpha background(0,0,0,0);
Here is the working sample:
https://editor.p5js.org/heldersepu/sketches/ll8txfcs0


I also added smooth() on my sample:

The difference is noticeable, read more about it here:
https://p5js.org/reference/#/p5/smooth

Upvotes: 3

Related Questions