How to read color from an MTL?

I’m trying to get the colour of the surface on an OBJ with a material set using an MTL. I want to be able to select a position using the mesh geometry and read the color seen at that point.

Is this possible?

I expect the color you read from a screen position to be the result of the material color, the color(s) and position(s) of the illuminating light(s), the angle between the face normal and the viewing direction as well as any atmospheric effects, just to name a few.

So, in short: I don’t believe this is possible with a reasonable degree of precison.

Thank you for the quick reply, i am trying to create a 3D particle solution that can recreate the 3D shape and set the color of the particles based on the object (ideally by using a standard material). I thought I might be able to bake in the colors but I cannot figure out any way of doing it. I saw this method meshsurfaceSampler but it would not return the color, I’m assuming this is because the colors are not set as a buffer attribute.

Hi Chaser_Code, thanks for the reply. I did see this example but this reads directly from the rendered output. I am not rendering the 3D object, I am loading the 3D object from a .obj and then using the mesh to load particles on the surface. This all works. However, I would like to have the particles match the color of the .mtl material, so the location of the particle would match the color from that specific vector.

For reference i am doing something similar to this - Surface Sampling in Three.js | Demo 1 | Codrops

But looking to also add color to my particles based on the 3D shape.

You could load the OBG at a location behind screen camera. Have a second camera look at the object and set the render target to a texture. You can then sample the color from the texture.

See this DEMO. Click on the Lights, Camera, Action Panel. Source code here

It uses render targets. This was loosely based on three.js portal example

If need only texture color, without shadows, lights, ambient, then load texture to 2d canvas ang get uv point of particle

Also good but maybe difficult calculation solution with light or without light is:
get position of particle, get selected triangle of particle, rotate camera or object face to camera, then read pixel. Renderer size can be small.

So i actually found a solution. I can get the martial groups and then pull the colour for each material, then I can select a random position from the index and each material group has a start and end point. So I can use the ranges to determine what material group is being used and then apply the color. It seems to be working but I need to clean up the particle selection.

function sampleRandomPoint() {
  const size = geometry.attributes.position.count;
  const randomPoint = Math.floor((Math.random() * size)) * 3;

  const posAtt = geometry.attributes.position.array;
  //get position
  const pos = new THREE.Vector3( posAtt[randomPoint], posAtt[randomPoint + 1], posAtt[randomPoint + 2] ); 

  //get color
  let color;

  geometry.groups.forEach((group, index) => {
    if(randomPoint >= group.start) {
      color = fullobj.children[0].material[index].color

  if(color.r === undefined) {
    color = new THREE.Color(0xFFFFFF)

  return {

I can confirm this is working, when I have it all working I will upload an example.

If your material is just color then easy.

OK, this is the final version I ended up with.

I still use the MeshSurfaceSampler as it will provide a position that is somewhere on a face as opposed to on the vertex.

function sampleRandomPoint() {
  let position = new THREE.Vector3();
  let color = new THREE.Color();
  // instead of using the .sample method we use sampleFace and calculate the faceIndex ourselves

  const cumulativeTotal = sampler.distribution[ sampler.distribution.length - 1 ];
  let faceIndex = sampler.binarySearch( sampler.randomFunction() * cumulativeTotal );
  sampler.sampleFace( faceIndex, position );

  // convert faces into points for color groups
  faceIndex *= 3;

  geometry.groups.forEach((group, index) => {
    if(faceIndex >= group.start && faceIndex < (group.start + group.count)) {
      color = fullobj.children[0][group.materialIndex].color;

  return { color, position };

OK, Maybe “hate” is too big a word to describe what has happened. I see you are a new user (joined three day ago), so you can’t be aware why I reacted the way I did. Let me explain:

when you click on someone’s avatar, you are shown that person’s “business card”, so to speak. One important piece of information is the number of solutions this person has provided while being a member of this forum. It is a measure of that person’s “social credit”, as this is nowadays called.

If people assign social credits to themselves (like you unknowingly did), they are in effect cheating the system. This is an ongoing nuisance which I raised with @Mugen87 before. So this issue has a history which dates back before your time here started. In that regard you received some “fire” for which you weren’t the intended recipient. I apologise for that.

I think you are skipping a few important steps here:

You presented the forum with a problem, for which you were asking a solution. Several people jumped in, to provide their input. Even if those inputs didn’t solve your problem right away, they still contributed, by way of elimination, to narrow down the space in which to continue the search for a solution. Eventually the space became so narrow, that you were able to find the solution.

You are probably implying, that by having spent time on this you somehow “deserve” that credit.

Just remember, that every single person giving answers here has acquired their knowledge by “having spent many days” struggling to find out how things work.

I see that you have withdrawn the post I’m answering. You successfully got my post cancelled. it is not without a certain piquancy that the only one who could change something here is exactly the one who was able to block my post as well as give your (now deleted) post a “like”.

So it seems we have to leave it at that.

I have to clarify that it is totally fine if users accept their own post as the solution. This is not a problem and it does not need to be fixed in any form.

I have the feeling you are overestimating the meaning of a community member’s sole solution count. Whether or not a developer is valuable for the community depends on much more than how often one of his/her posts gets the solution tag.

To me, the most important thing in this forum is to help users. If you participate in the problem solving process, you will automatically receive credits from the community. Even if you don’t get the “solution” tag.


You shouldn’t see this as a social credit system, there are often many solutions for one problem one just might be marked as it suits the specific conditions of the poster while another was more a general solution (like difference between specific environments like react and vanilla js)

Questions the author figures out themselves and post a direct answer just to mark it are kinda nonsense and could be left without marking it, however while others join the discussion the author might find resources later on or figure out the solution later on so marking it in a longer discussion only helps for showing a solution to the issue, it’s the main purpose of the feature.


This is your personal opinion, and as such not an undisputed one.

Just like Three.js has a mechanism for submitting Problem Reports (or Pull Requests) or however you may call them, I’m sure the supplier of this Plug-in Three.js is using also has a channel to submit change requests.

It’s just that this feedback from your(!) users doesn’t seem to get past your personal preference filter.

Like I said: we can leave it at that.

It is my understanding that you come here to help people with their problems for free, if you feel like.
It is not a social system for earning e-trinkets and nobody owes you anything here.
If you demand payment for your posting efforts and get upset when you don’t get any because you miss a chance to rank up your profile, you probably won’t be very happy.

1 Like

I think there’s value is posting a problem and your own solution, especially if you include all things you tried and eliminated over hours and days. We’re all better off when we share and collaborate.


related Assigning "solution" credit to self