DJMaesen Encode the normal components back to 0-1 range after blending because that's what NORMAL_MAP is expecting to get. Currently the NormalBlend_Linear() function decodes them before blending, but I don't see the result being encoded back.

    DJMaesen NormalBlend_Linear() decodes its arguments by multiplying by 2.0 and subtracting 1.0. Do the inverse of that to the return value: add 1.0 and divide by 2.0:

    return .5*(normalize(n1+n2) + 1.0);

    Or as cool kids do it:

    return fma(normalize(n1+n2), .5, .5);

    the base normal gets discarded that way somehow

    • xyz replied to this.

      xyz weird thing is when i use my old code on a vertex color terrainshader
      the blending is just fine. so i dont think the detail normal is too strong
      however trying to do the same thing on a uv mapped mesh doesnt seem to work

      • xyz replied to this.

        DJMaesen The problem is that you're mixing two normal maps in 50-50 ratio. The detail map is much smoother so it will scale down the other one by 50%.

        Best to use weighted blend, give smaller weight to the detail map and increase NORMAL_MAP_DEPTH until it all looks as desired. Here's weighted blending function:

        vec3 NormalBlend_Linear(vec3 n1, vec3 n2, float bias){
        	n1 = n1*2.0 - 1.0;
        	n2 = n2*2.0 - 1.0;
        	return fma(normalize(mix(n1, n2, bias)), vec3(.5), vec3(.5));    
        }

        With bias .5 it should behave like your old function, mixing two normals in a half-half ratio. Smaller bias values will put greater weight on n1, while larger values (up to 1.0) will weight the n2 more.

          xyz is there a way to combine 2 normal maps without the mix 50/50? so both normals get applied like u would apply 1?

          • xyz replied to this.

            DJMaesen There are various ways you can blend normals. None of them is perfect. The one you used is the simplest. A good one but still simple is:

            vec3 n = normalize(vec3(n1.xy + n2.xy, n1.z));

            See how that works. Don't forget to decode/encode before/after doing this as this works with proper normals, not with values read from normal maps. So:

            n1 = fma(n1, vec3(2.0), vec3(-1.0));
            n2 = fma(n2, vec3(2.0), vec3(-1.0));
            vec3 n = normalize(vec3(n1.xy + n2.xy, n1.z));
            n = fma(n, vec3(.5), vec3(.5));

              xyz
              i tried it
              sadly ....
              no good results, i give up for now, im waisting time

              • xyz replied to this.

                DJMaesen Maybe your normal maps should be adjusted for better results. Can you replicate the look you want in Blender?
                Here is a breakdown of various methods with some example shader code. Maybe you can find something adequate. At least try Reorient Blending, the last one presented. It's the most complex one and probably most performance heavy (not by much though) but it's supposed to give best results for detail maps.

                  xyz there was a discussion in github about this topic. Godot only uses the R and G channels of normal map and calculates the B channel. so maybe that's why it doesn't work?
                  currently godot uses a simple lerp to combine normal maps values. It gives good enough results for me.

                  • xyz replied to this.

                    Jesusemora there was a discussion in github about this topic. Godot only uses the R and G channels of normal map and calculates the B channel. so maybe that's why it doesn't work?

                    This shouldn't matter if maps are properly encoded (either DX or OGL style). However if maps are made specifically for Godot and are lacking the blue channel then this may indeed be the cause of poor results. It's easily fixed though by adding a line of code that calculates the third component when decoding.

                    Jesusemora currently godot uses a simple lerp to combine normal maps values. It gives good enough results for me.

                    It kinda depends on the detail frequency in the maps. Simple linear mixing may work well for some combinations. The problem is more pronounced when combining a low frequency base map with a high frequency detail map.

                    xyz i tried every technique allready from this example>
                    https://www.shadertoy.com/view/4t2SzR
                    strange thing is that when u use a standard material shader and ad a normal map to a model(UV1) and then a detail normal (UV2 with triplanar mapping on) in the shader,it also looks bad.
                    so i think @Jesusemora might be right

                    • xyz replied to this.

                      i would really like to get this to work to texture large objects in the 3d world

                      DJMaesen it also looks bad

                      What are you comparing it against?

                      It should be doable in general, regardless of how Godot interprets normal maps.

                        xyz wait a minute ill take some screenshots with the 3 options available:
                        1 no detail normal on triplanar(standard), 2 the shader im trying to get to work(customshader) , 3 standard shader with detail normal on triplanar(standardwithdetail)

                        xyz
                        as u can see
                        all non standard normal blending messes up the base normal map

                        • xyz replied to this.