Why am I getting weird deviation of reflection near the edge of mesh?

Hi Community,

I am facing a strange problem; I am getting the reflection refracted off by 45 degrees near edge of extruded geometry mesh as you can see in the following image. So, if I want to place two such block end to end it looks un-natural. I am looking for a solution for this.

The function that creates the mesh with texture is the following one.

    function testBar() {
        const crossSectionPoints = [
            new THREE.Vector2(-0.5, -0.2), new THREE.Vector2(0.5, -0.2),
            new THREE.Vector2(0.5, 0.2), new THREE.Vector2(-0.5, 0.2)
        ];

        const length = 5;
        const steps = 60;
        const vertsPerSection = crossSectionPoints.length;

        let vertices = [];
        let indices = [];

        // Place all section vertices along the path
        for (let i = 0; i <= steps; i++) {
            let t = i / steps;
            let pt = new THREE.Vector3(0, 0, t * length);
            for (let j = 0; j < vertsPerSection; j++) {
                vertices.push(
                    pt.x + crossSectionPoints[j].x,
                    pt.y + crossSectionPoints[j].y,
                    pt.z
                );
            }
        }

        // Side faces (split quads into triangles)
        for (let i = 0; i < steps; i++) {
            for (let j = 0; j < vertsPerSection; j++) {
                let a = i * vertsPerSection + j;
                let b = (i + 1) * vertsPerSection + j;
                let a1 = i * vertsPerSection + ((j + 1) % vertsPerSection);
                let b1 = (i + 1) * vertsPerSection + ((j + 1) % vertsPerSection);
                indices.push(a, b, b1, a, b1, a1);
            }
        }

        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
        geometry.setIndex(indices);
        geometry.computeVertexNormals();

        const material = new THREE.MeshStandardMaterial({
            color: 0xb8b8b8, metalness: 0.96, roughness: 0.13, side: THREE.DoubleSide
        });

        return new THREE.Mesh(geometry, material);
    }

The normal calculation doesn’t have a way of knowing if those edges are supposed to be sharp or smooth, so it defaults to smooth.

The edgesplitmodifier takes an angle threshold and recomputes normals…
Try applying it after extrusion:

You have a rectangular cross-section defined by four vertices.
If you do a

computeVertexNormals()

you will get four normals, one for each vertex. Each vertex can only have one normal.
However, you are expecting shared vertices to have different normals, depending on which face they belong to.
If you want to have sharp edges/corners, you’ll need to duplicate vertices, having the same position but allowing different normals.

I tried but it could not make any difference.

I am not looking for sharp edges instead want to make these arrow pointed reflection aligned with the rest. Sorry I have misunderstood you and you are saying same thing.

Not a good solution, but would it work for you if you copy the normals from the inner area onto the edge area right after you recompute the vertex normals?

geometry.computeVertexNormals();

var nor = geometry.getAttribute( 'normal' ),
    n = nor.count,
    v = new THREE.Vector3();

for( var i=0; i<4; i++ )
{
	v.fromBufferAttribute( nor, i+4 );
	nor.setXYZ( i, ...v)
	v.fromBufferAttribute( nor, n-1-i-4 );
	nor.setXYZ( n-1-i, ...v)
}
1 Like

Well Pavel, this is quick and dirty solution, thanks for this. It works for this case, but problem is this is not the best for general purpose. I have mentioned here a simple 2d geometry for extrusion, but you know in practice I am going to use more complex 2d geometry for that it will work or not I am not sure. Can you please suggest some general-purpose solution?

I don’t know your general case.

Absolutely. Calculate the edge normals in your code, instead of relying on a general computation. Thus you will have a full control.

Have you tried the original extrusion along a path? Does it also generate strange normals?

It should work if the extrusion is along a straight line and if the you replace 4 with the number of edge vertices. Like this:

2 Likes

My extrusion will be following straight as well as curve path. So I want to make sure it will work along the curve.

Sorry for late reply, I was trying to do some experiments based on your reply. I am happy to confirm that it worked. Thank you.

1 Like