vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
454 stars 72 forks source link

Automaticaly Generate Normals #221

Closed jlemus88 closed 2 months ago

jlemus88 commented 4 months ago

Hi, Im new to SharpGltf, I have a list of triangles without normals information, im generating a proper gltf model but i need to generate the normals before exporting the gltf.

I have been checking up the unit test and samples bit havent found wath i need.

hope you can help me.

I found:

public static IReadOnlyDictionary<Vector3, Vector3> CalculateSmoothNormals(this IMeshBuilder srcMesh)

but not sure how to use it.

`

using VERTEX = SharpGLTF.Geometry.VertexTypes.VertexPosition;

public static void GenerarGlb(this Cono cono, Stream s,
    float yaw = 0, float pitch = 0, float roll = 0)
{
    // create two materials

    var material1 = new MaterialBuilder()
        .WithMetallicRoughness(0.8f,0.3f)
        .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA,
            new Vector4(239f / 255, 184f / 255, 16f / 255, 1));

    // create a mesh with two primitives, one for each material

    var mesh = new MeshBuilder<VERTEX>("mesh");
    var prim = mesh.UsePrimitive(material1);

    foreach (var plano in cono.Planos)
    {
        var vertices = plano.Vertices.Distinct(
            VerticeEqualityComparer.Default).ToArray();

        if (vertices.Length >= 3)
        {
            var a = vertices[0].AsVERTEX();
            var b = vertices[1].AsVERTEX();
            var c = vertices[2].AsVERTEX();

            if (vertices.Length >= 4)
            {
                var d = vertices[3].AsVERTEX();
                prim.AddQuadrangle(d, c, b, a);

            }
            else
            {
                prim.AddTriangle(c, b, a);
            }
        }
    }

    // create a scene

    var scene = new SharpGLTF.Scenes.SceneBuilder();
    scene.AddRigidMesh(mesh, Matrix4x4.Identity);

    // save the model in different formats

    var model = scene.ToGltf2();
    var node = model.LogicalNodes[0].WithLocalRotation(
        Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll));
    model.WriteGLB(s);
}`

this is a fragment of the code i'm using

thanks in advance for any help

vpenades commented 4 months ago

These calculated normal methods you see in the library are internal and not intended to be used to create meshes, but to be used as fallback when loading a glTF with missing normals.

if you're creating a model, the library expects you to feed the normals you have calculated on your own or you have imported from somewhere else.

Keep in mind there's many ways of calculating the normals, depending on what you want to do. For example, if you would be able to use the "CalculateSmoothNormals" method on a "Cone" mesh, the base of the cone would be smoothed with the cone section, and it would look terrible. So you need to implement your own normals generation (you can copy the implemetnation of CalculateSmoothNormals) but you will also need some way to control normals splitting, like smooth groups or max smooth angle.