I am working on implementation of a custom external renderer and would like to update vertex colors according to present lighting (Gouraud method will be fine for the start) and save this information to file. Is it possible to fetch the color info from existing shader (material) and bake it to vertex colors somehow ?
In three.js, lighting is computed in the shader on the GPU at render time. The material doesnāt store āfinal colorsā per vertex anywhere you can just read back on the CPU, so you canāt simply fetch baked Gouraud colors from an existing material.
If you want vertex colors that include lighting, you have a couple of options:
Recompute on the CPU
You can mimic the lighting calculations yourself in JavaScript. Loop through the geometry vertices, evaluate your lights (directional, point, etc.), normals, and material properties, then write the result into a color attribute. This is basically doing Gouraud shading manually on the CPU.
Custom shader + readback
Modify or replace the material with a custom shader that outputs the lighting result per vertex (passed to fragment). Then render to a render target and read pixels back. The tricky part is mapping pixels back to vertices cleanly, so this is not as straightforward as it sounds.
GPU baking approach
Render the mesh in a way where each vertex maps to a known pixel (for example using a special UV or ID encoding), output the computed lighting, and read that back. This is more advanced but closer to an actual ābakeā.
If your goal is just Gouraud-style vertex colors, the CPU route is usually the simplest starting point. You already have access to geometry attributes and light data in three.js, so you can approximate what the built-in shaders are doing without fighting the GPU readback limitations.
Thanks so much for your suggestions, I thought about all these approaches before writing the post, but they will take too much time and effort. Maybe I will choose a shader-based way if do not find a workaround.
Itās no longer part of three.js, but you could start with MeshGouraudMaterial, which was removed here:
The Gouraud materials implements per-vertex Lambertian shading. You would still need to add a way to read back the per-vertex data, perhaps with Transform Feedback.
Thanks for this idea. Iāve seen it before, but did not consider it in the context of this task - I need to explore it in detail, probably this is a solution. I will get back to this question in a few days after completing the present, less challenged project ).