I'm trying to create a plane to fit four user-specified points. I tried creating the vertices and faces of a geometry manually, but while the geometry is created just fine, the mapped texture is warped at the boundary of the geometry’s faces.
What's the proper way to transform a plane given four coordinates?
Related
I have been trying to figure out a way of adding thickness to lines that can receive shadows and look like solid objects using Three.js but the best result I managed to get so far is just thicker lines that do not look like 3D geometry.
The application is for an online 3D printing platform so I am trying to visualise the sliced geometry that is comprised of lines, similar to how other slicing software handles this, such as cura, as shown in the image below.
Generating mesh geometry from these lines would be most probably problematic as in some cases there are thousands of a lines in a single model so it will be too heavy.
Any suggestions on how to achieve the desired result in either three.js or another javascript library would be greatly appreciated!
So the idea is to render primitive covering your thick line area and in fragment decide if fragment is inside or outside the thick line compute 3D position and normal and render or discard; if not.
The idea is to pass polyline geometry for rendering to OpenGL that would produce just thin lines and use shaders to do the rest.
Vertex shader
will just pass stuff into geometry shader
Geometry shader
will take in 2 vertexes (line) and output 2 triangles (quad) covering line BBOX (line enlarged by line half thickness). This is relatively easy. Simply shift the line endpoints by perpendicular vector to the line of size equal to the half thickness. This must be done in plane parallel with camera screen plane (using basis vectors extracted from direct camera matrix). Do not forget to pass both vertexes in world and camera coordinates.
Fragment shader
simply from world coordinates test if point is inside your thick line:
so simply compute P' and compute distance between P,P'. That is called perpendicular distance between point and line. Its doable exploiting dot product IIRC:
t = dot(P-P0,P1-P0)
P' = P0 + t*(P1-P0)
d = |P'-P0|
from that you just compute the 3D coordinate (depth of the fragment), normal and either render with some directional light or discard;...
Take a look at full example of this technique for 2D cubic curves:
rendering thick 2D Cubics in GLSL
I have a particle system using sprites which is an Object3D similar to the "interactive / points" example from three.js and a basic sphere mesh which follows my cursor.
https://threejs.org/examples/?q=point#webgl_interactive_points
What's the best way to determine when two of these objects intersect? I want to be able to push the particles with the sphere, but first I need an array of the points which are "inside the sphere". Thanks!
To know if a point is inside or outside the sphere, you can cast a ray from the point in a given direction. Then count the ray intesection with the sphere geometry's triangles. If the count is odd, the point is inside, else it's outside.
Some demo showing particles injection into a mesh is available here (same principle) https://github.com/heroncendre/Volpar
I would like to know the equations needed to do this and why it is.
I want to create a 3D shape that can grow, rotate and pan in a 2d shape.
I'm relatively new to Three JS, and currently I've got a working demo of loading a displacement map on a plane, effectively creating a terrain. What I'd like to be able to do is find the intersecting coordinates of a ray and this terrain.
Currently, for the demo, I have it marking the object as red when moused over, however the terrain seems to be behaving as though it has no displacement map when the intersect check is performed.
How do I find the intersection of the plane, after the displacement has affected the mesh?
So I am trying to build a 3D based world consisting of tiles.
I have successfully managed to do this using the plane geometry and height values etc. But now I have come to a point where I possibly have to change everything.
The problem is that I want a tile to have multiple textures (using a shader because I want to blend them). I was able to do this globally (so each tile would have same textures + using some uv mapping).
However I fail to understand how I would be able to specify which tile has which textures (and I have about a 100 textures), since the plane geometry has only 1 shader material. And I am also not sure if it is a good idea to send 100 textures through a shader?
So my questions basically boil down to this:
Is there a decent/performant way to link the tile/vertices to the textures, so I can keep the plane geometry.
- If yes: how?
- if no: Should I create each tile separately (so a plane of 1x1) and merge them somehow together (performance/vertex blending?) so it acts as a single plane (in this case the merged plane consists of many 1x1 planes) and use the shader per tile (a 1x1 plane)?
How are these things generally done?
Edit:
Some extra information because it seems that my question is not really clear:
What I want is that a tile (2 faces) has multiple "materialIndexes" to say so. Currently I need to have 1 tile to have 3 textures, so I can blend them in a shader with a specific algorithm.
For example I want to have a heart shape (red heart/black background) as texture and than based on the colors I want to blend/change the other 2 textures so I can get for example wooden heart and a blue background. Or for example I should be able to blend 4 textures evenly on the square, each take 1/4 of the square. But the point here is not what has to be done with the textures, but how that i can specify such 3, 4, or more textures for my faces/tiles.
I think you have to take a look at what is called a multi material object.
THREE.SceneUtils.createMultiMaterialObject( geometry, materials );
If you google for those you find several examples. Like this answer on a similar question.
Or take a look at THREE.MeshFaceMaterial. You can use it to assign multiple materials for the same geometry.
var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
Where materials is an array of materials and the faces use a materialIndex paramater to get appointed the right material
Similar questions here and here
EDIT:
Here is a fiddle to demonstrate that it is possible. I used the code from one of the links.
If your textures have all the same size, you can do the following:
Create a texture 10x the size of an individual texture (you can do that automatically, create a canvas, draw the texture file on the canvas at the correct coordinates, get the texture from the canvas). This allows for 100 (10x10) textures.
Assign to the tiles a base uv coordinates in the range 0 - 0.1 (since a single texture occupies 1/10th of the global texture),
Add to the previous uv values the offset of the individual texture (for the second texture, offset of 0.1 in u and 0 in v, for the 3rd texture 0.2 and 0; for the 10th 0 and 0.1.