raysan5 / raylib

A simple and easy-to-use library to enjoy videogames programming
http://www.raylib.com
zlib License
20.87k stars 2.14k forks source link

[models] GLTF/IQM Import vertex color support #1746

Closed GithubPrankster closed 3 years ago

GithubPrankster commented 3 years ago

Request for Enhancement

Following from a discussion.

Without support for extracting vertex colors in the GLTF or IQM format importers, I'm unable to use them for shading 3d models which is a part of my and others' process for retro-stylized games/software.

There is already support for creating them for Models, however this is a different scenario.

Example Screenshot

A model entirely shaded using vertex colors, as shown in the tool Blender 2.92.

image

Code Example

GLTF might be able to access this data though cgltf_attribute_type_color, and IQM through IQM_COLOR.

chriscamacho commented 3 years ago

as previously stated you can get exactly this effect without needing vertex colouring, simply load any OBJ mesh without texture, the material uses just the diffuse colour for that material - you can even take existing textured low poly models strip the textures and re-material them...

https://kenney.nl/content/3-assets/9-blaster-kit/preview-kenney.png https://kenney.nl/content/3-assets/23-car-kit/preview-kenney.png

kenny.nl uses this technique extensively and even someone as skill-less as me with blender can manage some decent low poly effects using the same technique.

oh and you can add shaders to the models just fine, for example for cell / toon shading

GithubPrankster commented 3 years ago

as previously stated you can get exactly this effect without needing vertex colouring, simply load any OBJ mesh without texture, the material uses just the diffuse colour for that material - you can even take existing textured low poly models strip the textures and re-material them...

This is different from using basic coloring, what I require is having color information, like say, "baked shadows" be included in the vertices to be interpolated from one to another and to then be mixed with a texture sample and/or other things like colors in the Fragment part of the shader.

Here's an example from the game Sonic R on the Sega Saturn. It mixes vertex colors with the textures to create interesting lighting.

image

image source: Sonic R Bughunting: Gouraud Shading

chriscamacho commented 3 years ago

just use proper point and spot lighting (not all your lights need be white) as an where needed, pre-baking yes is cheap, but that often how it looks...

On Mon, 3 May 2021 at 15:30, Uneven Prankster @.***> wrote:

as previously stated you can get exactly this effect without needing vertex colouring, simply load any OBJ mesh without texture, the material uses just the diffuse colour for that material - you can even take existing textured low poly models strip the textures and re-material them...

This is different from using basic coloring, what I require is having color information, like say, "baked shadows" be included in the vertices to be interpolated from one to another and to then be mixed with a texture sample and/or other things like colors in the Fragment part of the shader.

Here's an example from the game Sonic R on the Sega Saturn. It mixes vertex colors with the textures to create interesting lighting.

[image: image] https://user-images.githubusercontent.com/33995085/116888646-18bec680-ac02-11eb-83c0-c5dd6d49cca3.png

image source: Sonic R Bughunting: Gouraud Shading https://invisibleup.neocities.org/articles/24/

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/raysan5/raylib/issues/1746#issuecomment-831297663, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFO4SIFUIAHCT43YQE4IJTTL2XO5ANCNFSM44A2TK7A .

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk Free source code and tutorials!

Disclaimer: By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make such financial profit, political mileage, or good joke as it lends itself to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that may be included on your message.

GithubPrankster commented 3 years ago

This is not only about lighting but just more niche ways of doing coloring and shading that just point lights and prebaking cannot replace.

jmickle66666666 commented 3 years ago

vertex colors are useful for much more than just lighting or texturing effects. it is possible to use workarounds recreate specific effects without them but it is completely unnecessary when they could just be loaded from formats that include them

creutzerb commented 3 years ago

Hi,

You can get your vertex colors using glb with the following code: in src/models.c, after the line 4303

                   else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color)
                    {
                        cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
                        model.meshes[primitiveIndex].colors = RL_MALLOC(acc->count*4*sizeof(unsigned char));

                        if (acc->component_type == cgltf_component_type_r_8u)
                        {
                            for (int a = 0; a < acc->count; a++)
                            {
                                GLTFReadValue(acc, a, model.meshes[primitiveIndex].colors + (a*4), 4, sizeof(unsigned char));
                            }
                        }
                        if (acc->component_type == cgltf_component_type_r_16u)
                        {
                            TRACELOG(LOG_WARNING, "MODEL: [%s] converting glTF colors to unsigned char", fileName);
                            for (int a = 0; a < acc->count; a++)
                            {
                                unsigned short readValue[4];
                                for (int a = 0; a < acc->count; a++)
                                {
                                    GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned short));
                                    // 257 = 65535/255
                                    model.meshes[primitiveIndex].colors[(a*4) + 0] = (unsigned char)(readValue[0] / 257);
                                    model.meshes[primitiveIndex].colors[(a*4) + 1] = (unsigned char)(readValue[1] / 257);
                                    model.meshes[primitiveIndex].colors[(a*4) + 2] = (unsigned char)(readValue[2] / 257);
                                    model.meshes[primitiveIndex].colors[(a*4) + 3] = (unsigned char)(readValue[3] / 257);
                                }
                            }
                        }
                        else
                        {
                            TRACELOG(LOG_WARNING, "MODEL: [%s] glTF colors must be uchar or ushort", fileName);
                        }
                    }

Feel free to make a pull request if that works for you ;)