# NME Texture UV Planar Projection

**URL:** <https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606>\
**Category:** Questions\
**Created:** [October 2, 2020, 2:55pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606 "2020-10-02T14:55:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [October 2, 2020, 2:55pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/1 "2020-10-02T14:55:17Z")

</div>

Hi,  
I am trying to do a planar projection through NME.  
Have a look at this snippet: [Babylon.js Node Material Editor](https://nme.babylonjs.com/#VSGA00)

If you choose preview Sphere, you will see weird artifacts if you use the texture, but with gradient everything looks fine.  
Do you know, what could cause this issue?

Best regards,  
Martin

![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/d/d49249be50f266b76690cf7d7d3c10db97797e7c.jpeg) ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/d/d7b840fcd332ab97da2d8e8647eb8fa3655f8c4c.png)

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [October 2, 2020, 4:22pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/2 "2020-10-02T16:22:02Z")

</div>

pinging @Evgeni_Popov

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [October 2, 2020, 9:04pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/3 "2020-10-02T21:04:40Z")

</div>

I’m not sure I understand…

The gradient takes a scalar as input, so when linking a vec2, it will only take vec2.x. If you link the y value to the gradient input, you will see the display changing on the sphere.

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [October 5, 2020, 7:15am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/4 "2020-10-05T07:15:13Z")

</div>

Hi,  
thanks for clarifying the gradient input! I am not yet too familiar with programming shaders.  
I have set up another simpler example:  
[https://nme.babylonjs.com/#VSGA00#2](https://nme.babylonjs.com/#VSGA00#2)

HereI used x and z positions as colors green and red and if this is used for the fragment output, they show clear gradients. However, if I use them as uv input for a texture, the texture is distorted on the sphere. For the rotating shader ball it even is kind of flickering. It seems there is a relation of texture to the mesh faces?

![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/b/b251c3b400518e2576c63d12f4737a4b0f5e73c0.jpeg)  
 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/1/1f72e7d0d142a5fb5e21312889590301ad29c24a.jpeg)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [October 5, 2020, 9:50am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/5 "2020-10-05T09:50:16Z")

</div>

It seems to be an artifact of the texture sampling: if you display the x/z directly it is ok.

[https://nme.babylonjs.com/#VSGA00#4](https://nme.babylonjs.com/#VSGA00#4)

![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/7/7b37d2a5e140cecf20c572a585092568f2cc3941.jpeg)

Clamping u and v helps a little:  
 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/c/c6abcec141dab84d54036671bf5d79ef98aa2630.jpeg)

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [October 5, 2020, 12:09pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/6 "2020-10-05T12:09:57Z")

</div>

Hi,  
did you try out other objects besides the sphere, such as view rotating shader ball? It seems those artifacts are sometimes even stronger there and when one looks closely, they seem to be “walking” over the mesh faces. This is all because of the sampling right? If I would have the option of nearest neighbour or linear as within the inspector, the outcome would probably look different?

![shader](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/7/79bbd35c4698f15770f6d701c308e24706ab4584.gif)

Concerning your approach of using the xyz of the mesh position and not the world. It looks better!  
Maybe I should clarify, what a colleague and me would like to achieve. We wanted to project planar (later triplanar) onto multiple meshes, avoiding the mesh uv, but using a texture atlas. Therefore, we need the world position. But those texture artifacts currently distort the material.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [October 5, 2020, 12:34pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/7 "2020-10-05T12:34:08Z")

</div>

That’s “expected”, it’s coming from the geometry that is not tessellated enough.

You can experiment with this PG:

> **[Babylon.js Playground](https://playground.babylonjs.com/#2SN0M8)**

You will see that raising the number of segments help with the artifacts but some others may come from the sampling method (notably at the poles).

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [October 5, 2020, 1:36pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/8 "2020-10-05T13:36:59Z")

</div>

Just realized that the issue is related to Fract. I left it out in this example on the v axis (GREEN) and keep it on u axis (RED):  
[https://playground.babylonjs.com/#2SN0M8#1](https://playground.babylonjs.com/#2SN0M8#1)

We have also tried to use Mod instead of Fract. Same result. Isn’t this weird?  
Normally the uv of texture would get position values like 0, 0.5, 0,99, 1, 1.5, 2 i.e.  
with fract it would just do 0, 0.5, 0.99, 0, 0.5, 0 etc. so the output should be the same?

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/a/a3134003e82a88660f61a31e6153c6a1df277483.jpeg)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [October 5, 2020, 2:08pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/9 "2020-10-05T14:08:12Z")

</div>

It’s not the same because if you use `fract` you do the clamping between 0…1 yourself before the interpolation of the uv done by the GPU.

So, for eg, if the values to interpolate between are 0.4 and 1.2, when you use `fract` the GPU will interpolate between 0.4 and 0.2, whereas without using `fract` it would interpolate between 0.4 and 1.2 (and when going over 1 it would wrap around to 0). So it does not give the same result in the end.

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [October 5, 2020, 2:47pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/10 "2020-10-05T14:47:12Z")

</div>

Now it makes sense to me! Since geometry is stored on the GPU the fract will be calculated precisely on the GPU, I guess. Hope we find a good workaround and that we can share it!

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [October 5, 2020, 5:07pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/11 "2020-10-05T17:07:36Z")

</div>

I would think the workaround is to not use fract?

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [October 6, 2020, 6:38am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/12 "2020-10-06T06:38:09Z")

</div>

I guess, yes 😃

We were trying to do planar mapping with a texture atlas instead of multiple uvs. So instead of having i.e. 3 textures and one material, we would have one texture and one material, but would assign the uv through an index. Probably too much effort for too less effect.

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [December 10, 2020, 8:56am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/13 "2020-12-10T08:56:48Z")

</div>

Hi,  
sorry that I have to dig up this topic again. But I am still surprised about how Babylons node material handles texture sampling.  
I have made comparisons with threejs as well as blender. Both allow me to do planar mapping while using fract/mod/floor to limit the planar uv within bounds of i.e. 0 to 0.5 instead of 0 to 1.  
When I look into the exported shader I guess the most important lines are the following ones:

```auto
#ifdef UVTRANSFORM0
uniform mat4 textureTransform;
//Texture
//VectorMerger
vec2 xy = vec2(u_Float, u_Float1);
//Texture
#ifdef UVTRANSFORM0
transformedUV = vec2(textureTransform * vec4(xy.xy, 1.0, 0.0));
#ifdef UVTRANSFORM0
vec4 tempTextureRead = texture2D(TextureSampler, transformedUV);

```

Maybe it is worth having another look at it.

threejs via [https://dusanbosnjak.com/test/nodes/:](https://dusanbosnjak.com/test/nodes/:)

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/4/40b278a0e005f178015ebd5b990bf0a8c85dfb7e.png)

babylonjs (texture sampling is linear) - snippet id 9WKHVC#1

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/9/9c46abbdd852e85a930f82431e4ae5cb746b6ac2.png)

blender - not webgl

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/9/9a84dccf417772d047e15f72d1fa1dd8acaaeed1.jpeg)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 10, 2020, 11:01am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/14 "2020-12-10T11:01:00Z")

</div>

There are two things:

- the filtering used by the NME for texture samplers is **trilinear** , whereas in your screenshot of Threejs / Blender you are using nearest filtering
- the NME is trying to do as much as possible work in the vertex shader (in opposite to the fragment shader) to improve performances, but in your case it’s not what you want because the `fract * mul` operation should be done in the fragment shader to get the result you seek. To my knowledge there’s currently no way to force the NME to favor the fragment shader over the vertex shader when having a choise. @Deltakosh maybe we should do something about that?

You can do what you want with a PBRCustomMaterial, though:

> **[Babylon.js Playground](https://playground.babylonjs.com/#WCN41G%231)**

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/b/b1b50223a8a5e922a8ff1da05325129d8a5eacc1.jpeg)

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [December 10, 2020, 11:11am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/15 "2020-12-10T11:11:21Z")

</div>

Thanks a lot for the clarification. Now I finally understood. It actually seems to make sense to keep fract in vertex shader for performance reasons. Having the option to use it in fragment shader would be a good addition for the user.

Concering fitlering mode I just realised that I had to reload the nme after setting it to nearest in the inspector.

I will have a look at the PBRCustomMaterial. Would it be even more performant than a node material, if I set it up same way?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 10, 2020, 11:21am UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/16 "2020-12-10T11:21:08Z")

</div>

Performances would be about the same as it is doing the same thing, if using the PBR block in the NME.

However, you need to know GLSL to use the PBRCustomMaterial and you don’t have the same freedom than in the NME because you can inject your code only in certain specific locations.

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [December 10, 2020, 12:34pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/17 "2020-12-10T12:34:25Z")

</div>

Thanks a lot! I will give it a try 🙂

---

<div class="post-metadata">

**Author:** ![dennemark](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/dennemark/32/10745_2.png) [@dennemark](https://forum.babylonjs.com/u/dennemark)\
**Post date:** [December 10, 2020, 3:12pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/18 "2020-12-10T15:12:24Z")

</div>

I tried to work a bit with pbrcustommaterial, but already fail with assigning the correct variables. NME is a much more convenient solution.

It would be very helpful, if there would be an option to use fract for fragment instead of vertex shader!  
Currently I am using around 10 to 15 copies of a node material and am assigning textures for each. I have also tried to place multiple texture nodes into one material, but it does not make a great performance difference. Therefore I am still considering the solution to use one material with a texture atlas. I hope the performance win overweights the loss of moving from vertex to fragment shader.

I hope it is not too much work and worth the investment.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 10, 2020, 5:07pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/19 "2020-12-10T17:07:00Z")

</div>

I will let @Deltakosh answer regarding doing all the computations in the fragment shader, it may not be straightforward to enable such a mode…

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [December 10, 2020, 5:41pm UTC](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606/20 "2020-12-10T17:41:07Z")

</div>

I think we could think of exposing a way to flag a node to fragment only

So far, if you look at mod for instance:  
[Babylon.js/modBlock.ts at 74e37d81733c99ef79c64a36674e8fe9dcc7ee89 · BabylonJS/Babylon.js (github.com)](https://github.com/BabylonJS/Babylon.js/blob/74e37d81733c99ef79c64a36674e8fe9dcc7ee89/src/Materials/Node/Blocks/modBlock.ts#L16)

This means that NodeMaterial will remain in the section (vertex or fragment) and will not force the system to dispatch it

That property can be changed by code:

```auto
node.target = BABYLON.NodeMaterialBlockTargets.Fragment;

```

Other option is to force the shader to dump the operation in the fragment by using a fragment node before (like the DerivativeBlock) and yes this is really hacky 😃

[Next page](https://forum.babylonjs.com/t/nme-texture-uv-planar-projection/14606.md?page=2)
