Wrong rendering using CylinderGeometry and MeshPhongMaterial with vertexColors - three.js

I'm using CylinderGeometry to create a cylinder, and loop over its faces to set each vertex color according to the vertex y coordinate through a rainbow colormap. Then I use a MeshPhongMaterial on it, setting vertexColors to true.
I also have an AmbientLight and a DirectionalLight.
The cylinder renders correctly except on parts receiving directed light:
Please see the code here: https://codepen.io/thatcodepenaccount/pen/YzrgpYp
I looked at examples such as https://threejs.org/examples/#webgl_buffergeometry where using MeshPhongMaterial with some vertex colors seems to work, but I can't find what I'm doing wrong. Is it because I must use BufferGeometry?
edit: reducing light intensity from 10 to 1 as per comment fixed it:

Related

Shader with alpha masking other objects

I'm trying to make a very simple shadow shader which consists of a plane with a shader showing a radial gradient on colors and alpha.
Beneath this shadow lies another plane with the same kind of shader but linear.
And as a background of all this, a linear gradient from dark blue to light blue.
The problem is that when my camera approaches the ground, the plane of the shadow masks the floor.
Why does it happen and what can I do to prevent that?
https://codesandbox.io/s/epic-sun-po9j3
https://po9j3.csb.app/
You'd need to post code to check for sure but it likely happens because three.js sorts the order it draws things based on the center of the objects and their distance from the camera.
You can force a different order by setting Object3D.renderOrder
three.js also generally draws opaque things before transparent things so my guess is your ground plane and your shadow plane are both set to transparent: true but the ground can be set to transparent: false in which case it will be drawn first.
You might find this article useful. It shows a similar example.
As for why there is a hole it's because of the depth buffer. If something in front gets drawn first then the pixels behind are not drawn. So if the shadow happens to be drawn first it ends up looking like a hole because the pixels of plane behind it are not drawn.
See this

Three.js Map Texture to irregular Geometry (UW-Coordinates)

I have a problem with mapping a texture in THREE.js which is possibly related to creating custom UV-Coordinates as extensive search indicates.
The following picture shows a geometry which was created from THREE.BoxGeometry by manipulating the lower vertices of the box. The texture on the side looks stretched (although this is correct I guess).
picture1
Is there a way of "projecting" the texture onto the side, e.g. by creating custom uv-coordinates to look like in the second (photoshopped) picture?
picture2
Thanks for you help!
You will need to remap your vertices manually to perform what is called a "box mapping" or a "triplanar mapping".
Here is an example I threw together: https://codesandbox.io/s/qxk8xvnrvj
It creates a cube with some subdivisions.. perturbs those vertices if they are on top... and then does the iterations through the faces uvs and vertices to remap each faces UVs with a box mapping, by finding the dominant axis the face normal points along... and then using the other 2 axis' as the U and V axis for unwrapping.

How can I light emission per vertex and per vertex lighting in ThreeJS?

I want to see a chart with color specified per vertex and to get little bit of shading too.
But if I use MeshBasicMaterial I only get VertexColor with no dynamic shading.
On the other hand, if I use MeshPhongMaterial I just get shading but without emissiveness from my vertex colors.
As the THREE.JS PhongMaterial supports vertexColors, giving you a nice combination of dynamic lighting and vertex colors, I'm not quite sure I understand your question. Perhaps that is something you should investigate more?
However, as an alternative to writing a custom shader you could try rendering your model in multiple passes.
This will not give you as much control over the way the vertex colors and phong lighting are combined as a shader would, but often a simple add/multiply blend can give pretty decent results.
Algorithm:
- create two meshes for the BufferGeometry, one with the BasicMaterial and one with the PhongMaterial
- for the PhongMaterial, set
depthFunc = THREE.EqualDepth
transparent = true;
blending = THREE.AdditiveBlending(or MultiplyBlending)
- render the first mesh
- render the second mesh at the exact same spot

Obtaining normal of the mesh face using raycaster intersectObjects - Three.js

I tried to obtain the normal of the mesh face using these:
ray = new THREE.Raycaster(x, y);
var intersection = ray.intersectObjects(objectsOptical, true);
var vector = intersection[0].face.normal;
Added intersection[0].point and intersection[0].face.normal (multiplied by constant) as one vertex and intersection[0].point as second vertex of a (gray) line. And I got this (red lines are rays and gray should be normals - but they are not):
Illustrative image
Please help me to obtain NORMALS of the mesh FACE.
Thank you.
The normals that you have plotted with red lines look like they might be correct taking into effect perspective projection.
The raycast test hits a single triangular face from your mesh. The normal you are referring to is the normal for the face object the ray hit, ie. from the original mesh.
In the source code for THREE.Raycaster the intersection calculations can be seen returning the face directly.
Elsewhere it is suggested that Ray.intersectObjects() requires face centroids. However I'm not sure about this since the source code doesn't refer to centroids.
Perhaps the normals in the original geometry weren't correct. Try this function first:
geometry.computeFaceNormals();

Particle draw order

Does anyone have any ideas how to fix the below issue?
The red is just a plane (representing water) with a shader material. I have written a custom shader for the water material, but its very simple (I get it to display red). As you can see from the image below the two particle systems seem to mess up the draw order.
Weirdly - if I use a standard THREE material for the water, like phong or lambert, then the issue doesn't happen. Is there some define / property that I need to change on the shader material to prevent this from happening?
Many
Thanks

Resources