vpenades / SharpGLTF

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

Textures #85

Closed Mikhail1Demianenko closed 3 years ago

Mikhail1Demianenko commented 3 years ago

Hi,

After haveing done some research I cant seem to figure out how to assign a texture to a mesh. Taking a piece of code given here

using SharpGLTF.Scenes;
using SharpGLTF.Geometry;
using SharpGLTF.Geometry.VertexTypes;
using SharpGLTF.Materials;

// Create a mesh with a triangle.
var mesh = new MeshBuilder<VertexPosition>();

var prim = mesh.UsePrimitive(MaterialBuilder.CreateDefault());
prim.AddTriangle
               (
               new VertexPosition(0, -1, 0),
               new VertexPosition(1, 0, 0),
               new VertexPosition(0, 1, 0)
               );

// Create a scene and add the mesh:

var scene = new SceneBuilder();

mesh.UsePrimitive(material);

scene.AddRigidMesh(mesh, Matrix4x4.Identity);

// save it to GLB:

scene.ToGltf2().Save(@"D:\\New folder\\File.gltf");

How can I add an image to this triangle?

I understand that I should use MeshBuilder<VertexPosition, VertexColor1Texture1>(), but what should I modify to insert a texture? MeshBuilder, pimitive, or material?

vpenades commented 3 years ago

I understand that I should use MeshBuilder<VertexPosition, VertexColor1Texture1>()

Yes

but what should I modify to insert a texture? MeshBuilder, pimitive, or material?

Replace MaterialBuilder.CreateDefault() with a material created by you. MaterialBuilder has the APIs to create new materials with images/textures.

Mikhail1Demianenko commented 3 years ago

Thank you for your advice!

I tried in this way:

 var material = new MaterialBuilder()
                .WithDoubleSide(true)
                .WithMetallicRoughnessShader()
                .WithChannelImage(KnownChannel.Normal, "D:\\New folder\\WaterBottle_normal.png")
                .WithChannelImage(KnownChannel.Emissive, "D:\\New folder\\WaterBottle_emissive.png")
                .WithChannelImage(KnownChannel.Occlusion, "D:\\New folder\\WaterBottle_occlusionRoughnessMetallic.png")
                .WithChannelImage(KnownChannel.BaseColor, "D:\\New folder\\WaterBottle_baseColor.png");

var mesh = new MeshBuilder<VertexPosition, VertexColor1Texture1>("Mesh");

var prim = mesh.UsePrimitive(material);
prim.AddTriangle(new VertexPosition(-10, 0, 0), new VertexPosition(10, 0, 0), new VertexPosition(0, 10, 0));
prim.AddTriangle(new VertexPosition(10, 0, 0), new VertexPosition(-10, 0, 0), new VertexPosition(0, -10, 0));

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

var model = scene.ToGltf2();

model.SaveGLTF(@"D:\\New folder\\File.gltf");

But I failed to display the textures, all I'm able to get is a black triangle:

image

Is there a certain API call missing?

vpenades commented 3 years ago

You're missing the UV coordinates of the vertices. You've declared the vertex as <VertexPosition, VertexColor1Texture1> , so you must set color and texture too on every triangle. See all the AddTriangle and VertexBuilder method overloads.

Mikhail1Demianenko commented 3 years ago

Thank you, I finally was able to assign texture

Mikhail1Demianenko commented 3 years ago

Thank you, I finnaly was able to assign a texture. I will leave the code here in case someone needs it

var material = new MaterialBuilder()
                .WithDoubleSide(true)
                .WithMetallicRoughnessShader()
                .WithChannelImage(KnownChannel.BaseColor, "D:\\New folder\\bricks.png");

            var mesh = new MeshBuilder<VertexPosition, VertexTexture1>("Mesh");

            VertexTexture1 cor1 = new VertexTexture1(new Vector2(0f, 0f));
            VertexTexture1 cor2 = new VertexTexture1(new Vector2(0f, 2f));
            VertexTexture1 cor3 = new VertexTexture1(new Vector2(2f, 2f));
            VertexTexture1 cor4 = new VertexTexture1(new Vector2(2f, 0f));

            VertexPosition pos1 = new VertexPosition(0, 0, 0);
            VertexPosition pos2 = new VertexPosition(0, 1, 0);
            VertexPosition pos3 = new VertexPosition(1, 1, 0);
            VertexPosition pos4 = new VertexPosition(1, 0, 0);

            VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty> ver1 = new VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty>(pos1, cor2);
            VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty> ver2 = new VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty>(pos2, cor1);
            VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty> ver3 = new VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty>(pos3, cor4);
            VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty> ver4 = new VertexBuilder<VertexPosition, VertexTexture1, VertexEmpty>(pos4, cor3);

            var prim = mesh.UsePrimitive(material);

            prim.AddTriangle(ver1, ver2, ver3);
            prim.AddTriangle(ver1, ver3, ver4);

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

            var model = scene.ToGltf2();

            model.SaveGLTF(@"D:\\New folder\\File.gltf");