Why is a part of the mesh obscured when rendering a large area. I have encountered this situation twice, the first being using BasicMaterial to render a large amount of raindrops; The second one is to use shaderMaterial to render the heatMap.
some of the code
const position1 = [0, 0, 100];
const area = 1000;
function createRainGeometry() {
const geometry = new THREE.BufferGeometry();
const vertices = [];
const normals = [];
const uvs = [];
const indices = [];
for (let i = 0; i < 10000; i += 1) {
const pos = new THREE.Vector3();
pos.x =
position1[0] +
Math.random() * area -
area / 2;
pos.y =
position1[1] +
Math.random() * area -
area / 2;
pos.z = Math.random() * position1[2];
const height = 8;
const width = 1;
vertices.push(
pos.x + width,
pos.y,
pos.z + height / 2,
pos.x - width,
pos.y,
pos.z + height / 2,
pos.x - width,
pos.y,
pos.z - height / 2,
pos.x + width,
pos.y,
pos.z - height / 2
);
normals.push(
pos.x,
pos.y,
pos.z,
pos.x,
pos.y,
pos.z,
pos.x,
pos.y,
pos.z,
pos.x,
pos.y,
pos.z
);
uvs.push(1, 1, 0, 1, 0, 0, 1, 0);
indices.push(
i * 4 + 0,
i * 4 + 1,
i * 4 + 2,
i * 4 + 0,
i * 4 + 2,
i * 4 + 3
);
}
geometry.setAttribute(
"position",
new THREE.BufferAttribute(new Float32Array(vertices), 3)
);
geometry.setAttribute(
"normal",
new THREE.BufferAttribute(new Float32Array(normals), 3)
);
geometry.setAttribute(
"uv",
new THREE.BufferAttribute(new Float32Array(uvs), 2)
);
geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indices), 1));
return geometry;
}
function createRainMaterial() {
const material = new THREE.MeshBasicMaterial({
transparent: true,
opacity: 0.8,
map: new THREE.TextureLoader().load(rain),
depthWrite: true,
depthTest: true,
blending: THREE.AdditiveBlending,
side: THREE.DoubleSide,
});
material.format = THREE.RGBAFormat;
material.onBeforeCompile = (shader) => {
const getFoot = `
precision highp float;
uniform float top;
uniform float bottom;
uniform float time;
varying vec3 pp;
#include <common>
float angle(float x, float y){
return atan(y, x);
}
vec2 getFoot(vec2 camera,vec2 normal,vec2 pos){
vec2 position;
float distanceLen = distance(pos, normal);
float a = angle(camera.x - normal.x, camera.y - normal.y);
if(pos.x > normal.x){
a -= 0.785;
}
else{
a += 0.785;
}
position.x = cos(a) * distanceLen;
position.y = sin(a) * distanceLen;
return position + normal;
}
`;
const beginVertex = `
vec2 foot = vec2(0.0, 0.0);
float height = top-bottom;
float y = normal.z - bottom - height*time;
if(y < 0.0) y += height;
float ratio = (1.0 - y /height) * (1.0 - y /height);
y = height * (1.0 - ratio);
y += bottom;
y += position.z - normal.z;
vec3 transform1 = vec3( foot.x,foot.x, foot.x);
// vec3 transformed = vec3( foot.x, foot.y, y);
vec3 transformed = vec3( position.x, position.y, y );
pp = transform1;
`;
shader.vertexShader = shader.vertexShader.replace(
"#include <common>",
getFoot
);
shader.vertexShader = shader.vertexShader.replace(
"#include <begin_vertex>",
beginVertex
);
shader.uniforms.cameraPosition = {
value: new THREE.Vector3(0, 0, 200),
};
shader.uniforms.top = {
value: position1[2],
};
shader.uniforms.bottom = {
value: 0,
};
shader.uniforms.time = {
value: 0,
};
material.uniforms = shader.uniforms;
};
return material;
}
function addRain() {
const rainGeometry = createRainGeometry();
const material = createRainMaterial();
const mesh = new THREE.Mesh(rainGeometry, material);
scene.add(mesh);
}
addRain()