vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
467 stars 75 forks source link

Cant wrap texture on geometries #87

Closed learnerandtrainer closed 3 years ago

learnerandtrainer commented 3 years ago

Hi, I have some triangles and pictures . I want to set textures on the geometries. But when i add triangles to mesh , images doesnt wrap to all geometry as you can see below. Have any opinion what woul be cause of it? Can any one help me?

My Code

 var material = new MaterialBuilder()
.WithDoubleSide(true)
.WithMetallicRoughnessShader()
.WithChannelImage(KnownChannel.BaseColor, tileGeometry.Texture.ImageFullUrl);

var mesh = new MeshBuilder<VertexPosition, VertexTexture1>("mesh");
var prim = mesh.UsePrimitive(material);
 foreach (var geometry in item.Geometries)
{

    var triangle = geometry.ToVectors();
    var normal = geometry.GetNormal();

    //calculate the uv products
    Vector3 u;
    if (normal.X == 0 && normal.Z == 0) u = new Vector3(normal.Y, -normal.X, 0);
    else u = new Vector3(normal.X, -normal.Z, 0);

    Vector3 n = new Vector3(normal.Z, normal.X, normal.Y);
    Vector3 v = Vector3.Cross(n, u);

    //apply the uv texture positions
    VertexTexture1 cor1 = CreateTextureByUvVectore(triangle.Item1, u, v);
    VertexTexture1 cor2 = CreateTextureByUvVectore(triangle.Item2, u, v);
    VertexTexture1 cor3 = CreateTextureByUvVectore(triangle.Item3, u, v);
    //VertexTexture1 cor4 = CreateTextureByUvVectore(triangle.Item1, u, v);

    var vb0 = GetVertexBuilder(triangle.Item1, normal, cor1);
    var vb1 = GetVertexBuilder(triangle.Item2, normal, cor2);
    var vb2 = GetVertexBuilder(triangle.Item3, normal, cor3);
    //var vb3 = GetVertexBuilder(triangle.Item1, normal, cor4);
    prim.AddTriangle(vb0, vb1, vb2);
    //prim.AddTriangle(vb0, vb2, vb3);
}

var scene = new SceneBuilder();
scene.AddRigidMesh(mesh, Matrix4x4.Identity);
var model = scene.ToGltf2();

var bytes = model.WriteGLB().Array;

return bytes;

image

Tringles And Some Vertex

image

image

vpenades commented 3 years ago

I guess what you want to do is to apply a UV texture over a mesh.

SharpGLTF allows you to set the UV coordinates of a vertex, provided you know how to calculate it.

What you want to do is UV Mapping, or UV Unwrapping... you probably need other libraries like UVAtlas or define your own algorythms to calculate the UVs before feeding them to SharpGLTF.

These are huge and complex topics, beyond the scope of SharpGLTF library, which is a 3D format import/export library, not a general geometry library.

learnerandtrainer commented 3 years ago

Hi vpenades, As you said I want apply UV texture over a mesh. Actualy I have mapping cordinates that calculated by CreateTextureByUvVectore function ,and it mapped to triangle but when I looked to geometry completly , the texture repeats itself . I dont know there is any function or parameter , for mesh MetarialBuilder or any object , that to make wrap image to geometry completly There is any soultion like I said , Have you any opinion thanks

vpenades commented 3 years ago

You can try to scale down the final UV by dividing it by 100.

Other than that, there is no "magic" parameter that makes the image to wrap the geometry completely.

The usual procedures to "wrap" a geometry with an image are Planar UV Mapping, Spherical UV Mapping, or more complex algorythms like Least Squares Conformal mapping mixed with UV Atlas, which is what's actually used to "wrapping a geometry with an image"

Your code looks like nothing of these, and in fact, using normals to calculate UVs seems wrong. I believe you think what you want to do is easy to do and there's some cheap trick you can use, but you really don't know how difficult it is.... that's why people use Blender and 3DSMax to do it.

learnerandtrainer commented 3 years ago

Hi vpenades , I know it is so dificult but I thought it have been implemented because I saw below issue https://github.com/vpenades/SharpGLTF/issues/85

vpenades commented 3 years ago

85 is a different topic, where UVs were not being set in the first place.

But you're setting the UVs, because I can see a texture showing up in you screenshot, so the problem is different.

You need to learn more about UV mapping to use the library correctly.