HTMLCanvas to Thin Instances

Hi guys!
So I’m playing around with thin instances and had an idea to convert 2D HTMLCanvasElement to thin instances. Is it good for something? I don’t know, but it is cool :smiley:

EDIT: what about an animated mandelbrot? I think, I’ll give it a try😎

Have a look at the PG, link at the end. You can tinker the

const _3D_PIXEL_SIZE = 1

value at the beginning to have smaller/bigger 3D blocks for each 2D pixel.

Honoring BabylonJS and David I have chosen two images, the BabylonJS logo and David’s photo. Tried to choose the best one :smiley:, however you can provide your own image (beware of CORS issues)

        // your URL here
        const url = "https://babylonjs.nascor.tech/boxes/babylonjs-logo2.png"

        // TRY THIS ONE:
        // const url = "https://babylonjs.nascor.tech/boxes/david-catuhe.png"

The default 3D pixel is a cube:

    createPrefab(scene: BABYLON.Scene) {
        const options = {
            size: _3D_PIXEL_SIZE
        };
        const prefab = BABYLON.MeshBuilder.CreateBox("prefabBox", options, scene)
        scene.onBeforeRenderObservable.addOnce(() => {
            prefab.rotation.y = Math.PI / 4
        })
        return prefab
    }

You can map the 2D position to 3D using this method. This one is just centering the 3D pixels. You can add some calculations to distort the 3D image and/or modify the output color.

    calculatePosition(baseX, baseY, width, height, color) {
        const x = baseX + width / 2
        const y = baseY - height / 2
        const z = 0
        const divider = color.r > 1 ? 255 : 1
        const r = color.r / divider
        const g = color.g / divider
        const b = color.b / divider
        const a = color.a / divider
        return { x, y, z, r, g, b, a }
    }

And finally here is the PG:
https://playground.babylonjs.com/#W3JRUJ#22

Cheers!
R.

7 Likes

You inspired me to make art in the style of encient painters (Pointillism - Wikipedia) :slight_smile:

5 Likes

Cool, looking pretty close😎

5 Likes

How cool is this! :heart:

That detail:

You couldn’t choose a better image! I think, we should remove the blueish light and make a camera fly by near the painting. :sunglasses:

2 Likes

Since we are working with pixels here, all rules for pixel operations should be valid, such as edge detection to give the image a depth impression.

1 Like

Interesting and I’m interested already to try something out :sunglasses:

1 Like

I loved this one ;D

7 Likes

The tweet if you guys want to claim credits (I did not find your profile on Twitter):

Hello! :slight_smile:
Twitter: @RCsibrei
Thank you for sharing my/our work to the public! I’ve created a new PG which animates the camera, so it is obvious at once, that the painting is created from tiny boxes.

https://playground.babylonjs.com/#W3JRUJ#25

EDIT: Without @Necips this demo would never be so cool! So credits goes to him as well of course! Thank you!

EDIT2: And of course to you guys, who made this awesome framework and if I am correctly informed, especially to @Evgeni_Popov, who is the ‘father’ of thin instances stuff in BJS!

This reminds me the demo scene, when we were writing the coolest thank you sinus scrollers with colorfull copper effects we could and we thanked everyone involved directly or indirectly or just being nice and thanked everyone we knew, so the outro thank you part was 5 minutes long ! :smiley:

4 Likes

It was always my favorite part :smiley:

3 Likes

Maybe not so crazy high rez, but this could be used to convert a canvas to an extruded shape.

Like this?

Alright, here’s what I was thinking.

I painted a :pizza: on a canvas and made it 3d with this thin instance technique.

https://playground.babylonjs.com/#4AGZP8#2

Note: For some reason saving the Playground makes it lose the :pizza:, replaces it with “??”. Go to line 51 and replace that with :pizza: for the correct effect.

1 Like

https://playground.babylonjs.com/#4AGZP8#5
Replace the “??” with :earth_americas:

Fixed some vertical positioning, now trying to figure out the cyan strip in the texture. I posted it on the ground just to make sure it’s not always that way.

Hello!
I will check the cyan strips tomorrow. :sunglasses: I don’t have access to my computer now.
R.

Aha, found it.
line 108:

const divider = color.r > 1 ? 255 : 1

The divider is supposed to be 255 always, so when there was no red in the gradient it would divide by 1, setting g and b to 100%.

Final product is:
https://playground.babylonjs.com/#4AGZP8#6

1 Like

Hello! Cool PG and thx for finding the bug!
If you want to avoid this:


set camera.minZ = 0.001 to a very small value.
and adjust camera.maxZ as well.

1 Like