#mesh instancing with a 3D model

78 messages · Page 1 of 1 (latest)

brave orbit
#

I'm trying to implement mesh instancing with a 3D glTF model. I've re-used the example code and managed to draw the models, but they appear white. I discovered that glTF models use their own shaders to draw materials, and I'm unsure how to combine my instancing shader with the model's shader without overwriting it.

I also came across an extension named "mesh_gpu_instancing" for glTF that can add mesh instancing support to the model's original shader. However, I'm not sure if I can pass the necessary data to this extension using the raylib DrawMeshInstanced() function.

I would appreciate any help on how to properly implement mesh instancing with glTF models in raylib. Specifically, I need help with the following:

How can I combine my instancing shader with the glTF model's shader to achieve the desired rendering while preserving the model's materials?

If it's not possible maybe I could use the "mesh_gpu_instancing" extension in glTF model with raylib's DrawMeshInstanced() function? If so, how can I pass the required data to the extension?
random relic
#

Once it’s loaded it’s no longer a gltf, a model is just a list of meshes, you can instance the meshes

#

Just call the is instance function on each mesh in the model

brave orbit
brave orbit
random relic
#

DrawMeshInstanced

#

one sec

brave orbit
# random relic you can use the materials from the model too, it's just a structure

How can I do that, I only have a vertex shader:

#version 330

// Input vertex attributes
in vec3 vertexPosition;
in vec4 vertexColor;

in mat4 instanceTransform;

// Input uniform values
uniform mat4 mvp;
uniform mat4 matNormal;

// Output vertex attributes (to fragment shader) NOT USED
out vec4 fragColor;

void main()
{
    // Compute MVP for current instance
    mat4 mvpi = mvp*instanceTransform;

    fragColor = vertexColor;

    // Calculate final vertex position
    gl_Position = mvpi*vec4(vertexPosition, 1.0);
}```
random relic
#

just assign the shader to the materials in the model,

#
void DrawModelInstanced(Model* model, Matrix* matrixArray, int count)
{
    for (int i = 0; i < model->meshCount; i++)
    {
        DrawMeshInstanced(model->meshes[i], model->materials[model->meshMaterial[i]], matrixArray, count);
    }
}

void SetupModel(Model* model)
{
    Shader shader = LoadShader("instance_vertex_shader.vs", NULL);
    for (int i = 0; i < model->materialCount; i++)
        model->materials[i].shader = shader;
}

#

something like that

brave orbit
# random relic just assign the shader to the materials in the model,

That's what I am doing:

Shader shader = LoadShader("gui/resources/shaders/tile_instancing.vs", NULL);

    // Get shader locations
    shader.locs[SHADER_LOC_MATRIX_MVP] = GetShaderLocation(shader, "mvp");
    shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocationAttrib(shader, "instanceTransform");

    Model model = LoadModel("grass.glb");
    model.materials[0].shader = shader;
    model.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = WHITE; // Even if I remove this line it still is white
random relic
#

you are only setting the first material

#

a model has N materials

#

you should not have to mess with locs

#

or the maps

#

is a texture being loaded?

brave orbit
random relic
#

is the model supposed to be textured or is it all vertex colors?

brave orbit
random relic
#

ok, so yeah that's the texture then

#

yeah, you should just have to go change the shader on the materials

#

nothing else

#

and then just draw each of the meshes

#

let me see if I can build a small test

brave orbit
#

Do you want the model ?

random relic
#

sure

#

once LoadModel is done, all models become the same thing, the fact that it was a GLTF or obj is long gone

brave orbit
#

You need to have a folder at the same level of the model named Textures that contain the colormap

random relic
#

the color map is baked into the model

#

glb conains textures

#

I am familar with how kenney models work 😉

brave orbit
#

ah my bad, the model came in 3 different format that's why

random relic
#

yeah I know

#

I own the same asset pack

brave orbit
#

nice

random relic
#

I think I know why it's not working

#

but Im testing

#

you got rid of the texture coordinates in the shader

#

fragTexCoord = vertexTexCoord;

brave orbit
#

Thank you 👍

#

I was stuck on that for hours

random relic
#

without that the fragment shader can't get the colors

brave orbit
#

Do you know what could be the best way to add a black outline to each tile so that I can better see each one of them ? I did it with blender but the number of triangle doubled

random relic
#

use an outline shader

#

look up "sobel edge detection"

brave orbit
#

will look into that! Also is there optimization that I can make on the pipeline or shader because I only get 35 fps with 1 million tiles

random relic
#

that's a lot of triangles

#

merge the tiles into a big mesh

#

and get rid of hidden faces

#

and don't draw things that are off screen

brave orbit
random relic
#

raylib is not

#

the GPU is

#

if you have two tiles next to each other, none of the shared faces will ever be vissible

#

even with backface/front face

brave orbit
#

true

random relic
#

backface culling is on a triangle level

#

it doesn't know what's around it

#

you'd have to build a custom mesh

brave orbit
#

Is it possible to remove faces with raylib or should I just have another model that I modified by hand with blender ?

random relic
#

you can't really edit a mesh strucutre in raylib

#

you can build new meshes in code

#

but raylib is not a modeling library

#

it doesn't have functions to manipulate geometry

#

there we go

brave orbit
#

Thanks for the help, you saved me a lot of trouble

brave orbit
random relic
#

that's an example voxel mesher

#

it builds up a big mesh for a voxel chunk

#

what you are doing is similar, just with hexes instead of cubes

#

the concept is the same, build one big mesh

brave orbit
#

👍