How do I color / texture a 3d object dynamically ?

Started by
4 comments, last by Hodgman 14 years, 1 month ago
I have a 3D model, composed of triangles. What I want to do is, given a point near to the model, I would like to color the model (triangles) to another color, say blue. Right now, I have a bounding sphere about the model, and when the collision occurs, I just want to approximately color the portions of model from where the collision occurred. Also, for now I am using VBOs to render the model (with only vertex position information in there..thus its a wireframe as of now) Can someone please suggest me something that I can use and make this happen ? Thanks
Advertisement
You could go through your vertices on the CPU, measuring distance to the center of this sphere and modifying the colour attribute if distance is less than radius.

If you're using shaders, you could also do this in your vertex or pixel shader -- put the sphere parameters in a uniform variable, calculate the current vertex/pixel position, get the distance, use step to do the "less than" comparison, and then use mix to choose between blue and whatever the default colour is.
Quote:Original post by Hodgman
You could go through your vertices on the CPU, measuring distance to the center of this sphere and modifying the colour attribute if distance is less than radius.


I thought about doing it like this..but then I would have to retrieve the data from VBO, update it and send it back...and when I think this happening again and again in each frame with people shooting each other a lot..I felt its going to be very slow. What do you think ?

Quote:Original post by Hodgman
If you're using shaders, you could also do this in your vertex or pixel shader -- put the sphere parameters in a uniform variable, calculate the current vertex/pixel position, get the distance, use step to do the "less than" comparison, and then use mix to choose between blue and whatever the default colour is.


Given this approach, how would I choose which vertices to color ?
Quote:Original post by brainydexter
I felt its going to be very slow. What do you think ?
Yep, I'd prefer the shader approach ;)
Quote:Given this approach, how would I choose which vertices to color ?
Same as the CPU-driven approach. Measure the distance from the vertex to the sphere. If the distance is less than the radius, you colour it.
If you do this distance-check in the pixel shader (instead of vertex shader), then you'll get a perfect sphere intersection instead of an approximate per-vertex intersection -- but obviously it's more expensive as you're doing a per-pixel operation instead of a per-vertex operation.

[Edited by - Hodgman on February 25, 2010 5:16:07 AM]
Quote:Original post by Hodgman
Same as the CPU-driven approach. Measure the distance from the vertex to the sphere. If the distance is less than the radius, you colour it.
If you do this distance-check in the pixel shader (instead of vertex shader), then you'll get a perfect sphere intersection instead of an approximate per-vertex intersection -- but obviously it's more expensive as you're doing a per-pixel operation instead of a per-vertex operation.


I apologize for my very limited experience with GLSL. I understand what you're saying, but am a bit confused. Let me bring up this scenario to convey my confusion:

A bullet comes and hits the back of a human head. I detect collision when the bounding sphere(BS) of the bullet intersects with the BS of the head.

Now, a significant number of vertices of the head would be within that radius (maybe some that belong to the front of the head as well), and if I were to colour them as per what you said, they would all turn blue. Do you see what I am saying?

My concern is: I dont want a whole lot of accuracy, but at the same time, inaccuracy that gives the illusion of realism, i.e. if the bullet hits at the rear part of the head, I wouldnt want the front part of the head to be painted.

You can add more constraints to your "within the hit area" test to restrict the selected faces further.
In that case, as well as taking the distance to the impact point into account, you may want to look at the direction that the current vertex/pixel is facing and compare it to the direction that the impact point faces.
For example, a vertex/pixel on the back of your head would be facing roughly 180º away from a vertex/pixel on the front of your head.

You can compare the angular difference between two verts/pixels by getting the "dot product" of their normals. A dot of 1.0 means they're facing the same way, 0.0 means 90º apart, and -1.0 means 180º.
e.g.
dist = (impactPos - thisPos).Length();angle = impactNormal.Dot( thisNormal );if( dist < impactRadius && angle > impactAngleTolerance )  MakeItBlue!else  MakeItRed!
or in GLSL
float dist = length( impactPos - IN.position );float angle = dot( impactNormal, IN.normal );float checkDist = step( impactRadius, dist );float checkAngle = step( angle, impactAngleTolerance );vec3 color = mix( vec3(1,0,0), vec3(0,0,1), checkDist*checkAngle );

This topic is closed to new replies.

Advertisement