Why is it when an object is created with THREE.Mesh, the scale property acts completely different than when THREE.Sprite is used? A sprite with its scale property's set to 1 is not able to be seen.
Related
I have an instance using Drei library with a plane geometry.
According to a state, I would like to display different materials for each instance:
state is false: display a standard material with a simple color
state is true: apply a different texture (an image)
Each instance has its own state (for example 20% can be true and 80% can be false, or another ratio)
What would be the best way to do that?
Retained solution: Instanced Attributes
As mentionned by #Bhushan Wagh, the idea is to store the texture state inside a geometry attribute. Then, you can access this data in the shaders in order to apply a custom logic. You can follow his codesandbox for the R3F solution, or this one for the drei instance solution.
Investigated solutions
Having 2 distinct instances (one for the colored material, one for the image texture):
it's ok when we have only 2 states, but what if we have like 10 possible states? (What would be the best solution in this case?)
Represent a plane with a boxGeometry and display the proper face according to the state
It's also only working when we only have 2 states and are in 2D
I don't think you need to change the material if you just wanna toggle between plain color and texture. You can do this doing some changes in shader of material where you pass the vec4 to gl_fragColor in fragment shader based on the state, you can pass the state as attribute to the mesh, since you using instanced mes you can use the instancedAttribute. I had the codesandbox for solution for using different textures on each object of instanced mesh so I made a changes in that code to solve your problem ( or at least what I think is solution) https://codesandbox.io/s/toggle-texture-of-instanced-mesh-ptcvbb You can toggle state of each plane by clicking on it. and I think this should work even with more than 2 states, you can represent the states with number and based on number you can select particular texture from texture array passed as uniform.
I have many textured meshes so they must have different materials. It seems like there are only two ways to clip: globally, and per-material.
However, I want some visualizers to not be clipped (e.g. the plane I'm manipulating to define the clip planes), but all of the rest of the meshes are to be clipped. So I want to use global clipping, but to exempt the parts of the 3D UI (specific objects) from clipping. Is this possible?
I'm fairly certain that I can address this at the application level by separating the scenes so that i can issue the render of items i need clipped by using globally clipped functionality, and then clear out the clip planes and render a second scene containing UI elements prior to clearing the renderbuffers.
Hello i am new to ThreeJS and texture mapping,
Let's say I have a 3D-Plane with the size of (1000x1000x1). When I apply a texture to it, it will be repeated or it will be scaled, to atleast filling the full plane.
What I try to achieve is, to change the scaling of the picture on the plane at runtime. I want the Image to get smaller and stop fitting the full plane.
I know there is a way to map each face to a part of a picture, but is it also possible to map it to a negative number in the picture, so it will be transparent?
My question is:
I UV-Mapped a Model in Blender and imported it with the UV-Coords into my ThreeJS-Code. Now i need to scale the texture down, like described before. Do I have to remap the UV-Cords or do i have to manipulate the image and add an transparent edge?
Further, will I be able on the same way to move the image on the picture?
I already achieved this kind of usage in java3d by manipulating bufferedImages and drawing them onto transparent ones. I am not sure this will be possible using javascript, so i want to know if it is possible by texture-mapping.
Thank you for your time and your suggestions!
This can be done using mapping the 3d -plane to a canvas ,where the image is drawn (fabric.js can be used for canvas drawings).Inshort set the canvas as texture for the 3d model
yourmodel.material.map = document.getElementById("yourCanvas");
Hope it helps :)
Yes. In THREE, there are some controls on the texture object..
texture.repeat, and texture.offset .. they are both Vector2()s.
To repeat the texture twice you can do texture.repeat.set(2,2);
Now if you just want to scale but NOT repeat, there is also the "wrapping mode" for the texture.
texture.wrapS (U axis) and texture.wrapT (V axis) and these can be set to:
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
This will make the edge pixels of the texture extend off to infinity when sampling, so you can position a single small texture, anywhere on the surface of your uv mapped object.
https://threejs.org/docs/#api/textures/Texture
Between those two options (including texture.rotation) you can position/repeat a texture pretty flexibly.
If you need something even more complex.. like warping the texture or changing it's colors, you may want to change the UV's in your modeller, or draw your texture image into a canvas, modify the canvas, and use the canvas as your texture image, as described in ArUns answer. Then you can modify it at runtime as well.
When i put an object to scene, re-size him by morph targets like in this example:
https://threejsdoc.appspot.com/doc/three.js/examples/webgl_morphtargets.html
when i move camera out of the original size of object, but still looking on re-sized parts, object is disappear.
That means, when i stretch box 100 times, i still need to look on his original center, when i look only on his re-sized part, it becomes invisible.
Do you have any experience with this behavior?
How can i set the object to be visible of full length?
Meshes are frustum-culled based on their "un-morphed" geometry.
You can prevent a mesh from being frustum-culled by setting:
mesh.frustumCulled = false;
three.js r.68
I want to create a SpotLight such that the shadow map covers a specific orthographic area, or a PlaneGeometry. The default settings however appear to create a shadow area based on the frustrum of the light. Given that the frustrum is rotated and scaled compared to the plane, it is not possible to simply alter that frustrum. I'd have to make it very large to cover the intended area, and then the resolution is low.
Is there some way to create a light for which the shadow is calculated on a specific recipient area (either a plane or an orthographic region)?
You should create a second spotlight which is child of the first spotlight and position set to 0,0,0. And you should set the target to the plane. And onlyShadow set to true.
That way you can have the second spotlight pretending to be the first spotlight but with a detailed shadowmap.
EDIT OLD ANSWER (misinformed):
It is possible to use a directional light to create an orthograpic
shadow.
https://github.com/mrdoob/three.js/blob/master/src/extras/renderers/plugins/ShadowMapPlugin.js#L169
This directional Light can be set to be onlyshadow.
https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLight.js#L16
The expected frame can be set with the shadowCamera.
https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLight.js#L20-L26
And the angle can be set with setting the position to the calculated
normal of the plane.