Projection mapping

Hi everyone,

I’ve been trying to do this for a long time, have been going through the forum for weeks but still can’t wrap my head around doing projection mapping in Babylon

I’d like to project an albedoTexture onto several objects from the camera (or ideally just a transformNode) point of view. In this case, projecting this pre rendered image
image
on to this babylon scene

I have pre rendered something in 3dsmax and would like to project that render on to my Babylon scene in order to create a parralax effect when moving around with a camera. Something similar to this but with a texture2d instead of a cubemap Cubemap SKYBOX_MODE projection origin - Questions & Answers - HTML5 Game Devs Forum

My understanding is that I should create either a PBRcustommaterial or a shadermaterial to do this but my knowledge of shader writing is almost 0.

I loaded my 3d scene and the rendered texture in a playground. I’d like for my texture to be mapped on the objects from the camera view point the same way it would be if I was to use the texture has a layer without objects in the scene. The camera is imported too so is at the same location as in the render.
https://playground.babylonjs.com/#YIU90M#266

My questions are:
-Do you see any reason for this to not be possible?
-Has anyone done this or something similar in the past?
-If not, do you have good tutorials/docs on writing custom shaders? I looked this up (Introduction to Shaders | Babylon.js Documentation) but I don’t think this gives me quite enough info yet to build what I need and am happy to learn how to write shaders but if anyone of you has pointers on the logic that would save me quite a lot of time.

Thanks in advance for your help!

Chris

Maybe you can use the projection texture from the spot light to achieve what you want to do:

Thanks so much for linking this post. I had seen it many times late last year but I guess it was before all the new posts from December and on.

I think I mostly got what I needed to work and just need to figure out a few more settings. I’ll post my playground here when I’m done in case anyone is interested too.

Chris

I finally got time to work on this again since day to day production got in my way.

So I got it more or less working and I think it’s looking good. The one weird thing that I can’t seem to solve is that it’s slightly offset.
I can correct it by tweaking my directional vector that matches the spotlight direction to the camera but I don’t like that since I eyeball it and would much prefer to figure out the math behind this problem.

I made a playground. I have the base vector in there and the corrected vector (commented) so you see the difference.
https://playground.babylonjs.com/#YIU90M#302

I also enabled edge rendering in order to easily see where the 3d boxes are in the scene.

Looking forward to see what you guys think.

Chris

It seems it’s your objects that are slightly miss-placed. For box2, for eg, if you set the position to (1.49, -0.057, -0.036) it fits better:

https://playground.babylonjs.com/#YIU90M#303

1 Like

Thanks!

I actually figured out what the problem was, I was trying to rotate the light after creating it and I believe it was not registering the rotation. If I set up the rotation in the light constructor then I get a perfect match which is great!
https://playground.babylonjs.com/#YIU90M#311

Now I will need to update the light location and the parralax, how would I go about this? I tried to move it doesn’t seem to register the new location/rotation. I saw your post about using spotLight.position = spotLight.position; but I don’t understand what it does.
I created a playground where I’m switching both the map and camera location after 3 seconds. The spotlight position/rotation also moves to match the camera but the map is not projected properly (I believe it doesn’t actually change it from the previous location).
https://playground.babylonjs.com/#YIU90M#333
Do you have an idea of how to solve this?

Lastly, I’d like to be able to fade this light from 0 to 1 instead of on and off. I’m currently mapping a cubemap through the reflection map on objects and would like this light to seamlessly replace the cubemap I have in the reflection map, is that possible?
I can easily switch from one to another (see settimeout in playground below) but I’d like to fade from one to the other, any idea?
https://playground.babylonjs.com/#YIU90M#332

Thanks again for your help, really appreciated!

Chris

You need to set the spotlight position and direction according to the new camera when you switch:

https://playground.babylonjs.com/#YIU90M#335

Regarding your last point, you can do something like that:

https://playground.babylonjs.com/#YIU90M#339

I updated the code in the light fragment (line 94+) to compute a final color corresponding to the projection texture, and at the end of the shader I mix this color and the color computed with the reflection texture (line 39).

Thanks so much this is awesome.

Looking back at my code, my first question was really dumb, not sure how I missed this but clearly I wasn’t doing anything to move the location or rotation of the spotlight on that playground… I may have shared the wrong playground by mistake but regardless whatever I was doing was not working so thanks!

For the second one, there was no way I would have written that shader by myself and it’s doing exactly what I need it so this is great! I have tried a few times to learn how to write my own shaders but I haven’t been able to learn it through the Babylonjs doc as I found that it was not really going into specifics and wasn’t exposing all the functions/parameters available (Introduction to Shaders | Babylon.js Documentation). Did I miss anything or are there any resources you would recommend to get a better understanding of shader writing?

Chris

It’s not really in the scope of Babylon to teach on writing shaders. The page you linked explains how to use your own shaders into Babylon.js but you should know how to write them in the first place. I can’t recommend resources as I don’t have bookmarked links about this subject but you should find plenty of resources on the net / in books. Also, I think there had been a number of threads about that in this forum. Also, others may have some good links for you.

Writing custom shader code in Babylon.js that modifies an existing behaviour requires to know the language (GLSL) as well as the engine source code itself (or at least the part you need to interface with), as it is an advanced use of the engine.

Got it,
Thanks again for your help!

Chris

Hi everyone,

I have one more use case that I am hoping you could help with.

I’d like to be able to switch from one projection map to another with a fade, very similar to what @Evgeni_Popov did from the cubemap to the light projection mapping but with 2 lights projection mapping.

The idea would be that spotlight would project its texture and slowly fade to spotlight2, ideally without the 2 lights adding to each other which would create a much brighter look mid way through the fade.

I tried to mix together the shader @Evgeni_Popov did for the cubemap fade and the non fade one but didn’t get far since I don’t know how to point to specific lights in the lightfragment.
https://playground.babylonjs.com/#YIU90M#344

When working with the lightfragment, are we working with the full scene lighting? is there a way to “isolate” in a variable specific lights from specific spotlights in order to create the fade?

I also looked this up (Switch Material with Fade Effect) which fades 2 textures but I believe with the projection mapping the lightfragment are not textures but lighting?

Thanks!

Chris

The technic used here can be reused:

https://playground.babylonjs.com/#YIU90M#351

Sorry I realized that I never replied and then was on paternity leave for a month so i was pretty busy :slight_smile:
Thanks for your help it’s exactly what I needed!

Chris

1 Like

Hi everyone,

I’ve implemented the code on my page and everything works great on chrome but I’m getting some shader errors in Safari (both on Mac and Iphone). The weird thing is that the playground does work on Safari so I’m hoping that I’m just missing a CDN import or something like that.

I would create a playground to debug but that would defeat the purpose :slight_smile: so see a version available here:
https://normli.digital/RD/chris/babylonjs/parralax/

See below the errors I’m getting if you don’t have Safari

Thanks!

Chris

You are using the version 4.2 where you should be using the preview CDN * https://preview.babylonjs.com/babylon.js

1 Like

I knew it was gonna be something simple :slight_smile:
Thanks!

Hey guys, me again!

I just came across something that I can’t quite make sense of…
If I create a plane and either assign it either no material or a different material, then the projection mapping crashes…
https://playground.babylonjs.com/#YIU90M#369 (see line 34 where the plane is created and line 39 where I exclude it from getting the custom material)

Any idea what I need to do to bypass this?

Thanks!

Chris

I’m going to answer my own question:
Just need to make sure that the mesh is excluded from the projecting light…
https://playground.babylonjs.com/#YIU90M#370

2 Likes