NME needs support for PI and TAU

Greetings! I’m brand new to the forums so pardon if I’m putting this in the wrong place or format!

I was working in the NME on a skybox shader for mapping equirectangular images to UV spheres and I ran into a big roadblock. To make it work I need to be able to use the actual value of PI and TAU (2*PI) in my calculations. Unfortunately since I can only replace them with a 4 point precision float I end up with a horrible jagged seam where the image ends meets. The rest appears flawless and as expected.

I originally wrote my shader in Unity’s Shadergraph and it works absolutely fine there. Was hoping since math.pi is already a thing we could get that integrated as input options into the NME sooner than later <3

Otherwise thank you guys for making such a wonderful interface for WebXR shaders. It’s been the one thing really keeping me from moving operations mostly over to WebXR from Unity and thanks to the NME (and now the NGE weeeee!) I can bring my special effects to the masses :slight_smile:

1 Like

Just to follow up on this. I did try making a simple custom block that outputs only PI up to 50 decimal places hoping that would help but I’m still getting the jagged seam. Perhaps the engine itself is truncating decimal precision to 4 regardless? I’ve used three separate mathematical formulas to get my image wrapped and every one is producing the exact same issue.

I’ve just tested a Color4 input.

Even if the screen only shows 3 digits, if you type more, they’ll be stored in your material.

GUI:
image

JSON file:

      "convertToLinearSpace": false,
      "valueType": "BABYLON.Color4",
      "value": [
        0.800123456,
        0.8,
        0.8,
        1
      ]

No, that shouldn’t be the case. Could you provide us with a repro so we can take a look?

You could also try using Spector.js and looking at the shader code, that might help you find the problem.

1 Like

Well that’s interesting about display versus storage. Hmm, maybe PI isn’t my actual issue here then. Either way PI should be a default input block.

In that case I’m not sure what is happening here but this math works fine in Unity Shadergraph. I’m doing all of this in the NME GUI so here’s my several various route attempts all mashed into one for you.

Babylon.js Node Material Editor (use the sphere preview for best results)

The group it’s currently connected to, if you unclamp the texture’s UVs and use the inspector’s rotate slider you can also see that it’s not the image’s seam causing this since it will rotate and the glitchy seam remains static in place.

Could it be that the artifacts is not visible in Unity because the sphere is more tessellated?

In any case, the shaders as viewed in Spector seem ok:

Vertex shader (only important bits):

void viewDirectionToUV(vec3 viewDir, out vec2 uv) {
    float phi = acos(-viewDir.y);
    float theta = atan(viewDir.z, viewDir.x) + 3.14159265359;
    uv.x = theta / (2.0 * 3.14159265359);
    uv.y = phi / 3.14159265359;
}
void main(void) {
    vec4 output1 = u_World * vec4(position, 1.0);
    vec4 output0 = u_ViewProjection * output1;
    gl_Position = output0;
    vec3 output3 = normalize(u_cameraPosition - output1.xyz);
    vec3 output2 = normalize(output3);
    vec2 uv1;
    viewDirectionToUV(output2, uv1);
    vMainuv1 = uv1.xy;
}

Fragment shader:

void main(void) {
    vec4 tempTextureRead1 = texture(TextureSampler, vMainuv1);
    vec4 rgba = tempTextureRead1.rgba;
    glFragColor = rgba;
}

So I think it would help if we could see a Unity repro somewhere to look at how it is done.

2 Likes

Sure why not. You will probably not gain any new information from this but this is a proper demonstration of the same exact math but in Unity Shadergraph:

Tessellation really has nothing to do with it, mesh shape shouldn’t affect anything except the overall silhouette. This effect is entirely dependent on view direction alone (well and the wrap/clamping on the texture file). I made a sample scene with 3 different shapes so you can see what I mean. It’s like looking out of a window in all directions basically. Infinite distance and seamless. I’ve never seen artifacts like this in Unity, the worse I get there is mipmap aliasing on the seam which can be fixed by disabling mipmaps on the panorama texture file.

I wrote this Unity shader years ago and it’s always worked flawlessly. I’ve combined it with other effects too with no problems. So I thought why shouldn’t the most basic math of it work in Babylon right? Yet, it isn’t. And subsequent attempts through different mathematics still produced an identical seam, even across multiple Babylon and custom mesh types, which to me now seems it could be a deeper Babylon issue in view direction calculations but that’s just speculation of course.

However I’ve been working to bring some of my Unity shaders over to the NME for some Frame projects and there’s a few other strange Babylon vs. Unity calculation issues I’ve found that I plan to post about soon as well but I want to keep this topic focused for now :slight_smile:

Well in that case NME generates a pure shader. So either it is a glsl difference with Unity shader or there is a shader difference all up

1 Like

The problem is that Babylon.js tries to generate code in the vertex shader by default, when possible, to save performance.

In your case, the uv calculation is done in the vertex shader, which is why there are some artifacts.

You can force some blocks to execute in the fragment shader by setting their target property to Fragment. That’s what I did for the VectorMerger block in the node material below, which is enough to make all the calculation happen in the fragment shader:

I also set the filtering of the texture to “linear” instead of “linear & mip linear”, else you get a one pixel line artifact.

4 Likes

Ah! I would not have thought of that, brilliant thank you!

Yeah I originally had it on just linear but was frantically playing around with every setting and likely forgot to put it back before saving it. Similar to Unity mips are just not the way.

This is a great tip to know going forward too, it might help explain some of the other oddness I’ve found. Now that I know about this I’ll experiment further before posting.

I actually opened the example before reading what you did, and had a nice long stare between them scrutinizing each connection going “what changed?!” then I came back and read what you did and it all made sense. Thought it was funny though :stuck_out_tongue:

So to sum up this thread, I guess PI and TAU are not really needed as default inputs after all. If the system remembers more than it displays they can just be pasted floats screw it. But hey look at this lovely new knowledge coming from it all!

Thank you again :grin:

2 Likes