Buat deformasi medan dinamis menggunakan React Three Fiber – Beragampengetahuan
Dalam tutorial ini kita akan menjelajah Cara mengubah bentuk medan secara dinamisfitur yang banyak digunakan dalam game modern. Beberapa waktu lalu kami melakukan perjalanan nostalgia melalui grafis retro dengan mempelajari cara membuat dither shader PS1. Peralihan dari nuansa vintage ke teknologi mutakhir membuat saya bersemangat, dan saya senang melihat begitu banyak minat terhadap tema-tema ini.
Tutorial ini akan dibagi menjadi dua bagian. Pada bagian pertama ini, kita akan fokus pada deformasi medan dinamis, mengeksplorasi cara membuat dan memanipulasi medan secara interaktif. Di bagian kedua, kita akan melangkah lebih jauh dan membuat Area berjalan kaki tanpa batas Gunakan fragmen yang dihasilkan sambil mempertahankan kinerja optimal.
Contents
Pembangunan deformasi medan interaktif selangkah demi selangkah
Setelah adegan diatur, kita akan membuat planeGeometry Dan aplikasikan tekstur salju yang diperoleh dari AmbientCG. Untuk meningkatkan realisme, kami akan menambahkan displacementScale nilai, menciptakan lingkungan salju yang lebih dinamis dan realistis. Kita akan mendalami CHUNK nanti di tutorial ini.
const [colorMap, normalMap, roughnessMap, aoMap, displacementMap] =
useTexture([
"/textures/snow/snow-color.jpg",
"/textures/snow/snow-normal-gl.jpg",
"/textures/snow/snow-roughness.jpg",
"/textures/snow/snow-ambientocclusion.jpg",
"/textures/snow/snow-displacement.jpg",
]);
return <mesh
rotation=[-Math.PI / 2, 0, 0] // Rotate to make it horizontal
position=[chunk.x * CHUNK_SIZE, 0, chunk.z * CHUNK_SIZE]
>
<planeGeometry
args=[
CHUNK_SIZE + CHUNK_OVERLAP * 2,
CHUNK_SIZE + CHUNK_OVERLAP * 2,
GRID_RESOLUTION,
GRID_RESOLUTION,
]
/>
<meshStandardMaterial
map=colorMap
normalMap=normalMap
roughnessMap=roughnessMap
aoMap=aoMap
displacementMap=displacementMap
displacementScale=2
/>
</mesh>
))}
Setelah penciptaan planeGeometrykita akan menjelajah deformMesh Fungsi – inti dari demo ini.
const deformMesh = useCallback(
(mesh, point) =>
if (!mesh) return;
// Retrieve neighboring chunks around the point of deformation.
const neighboringChunks = getNeighboringChunks(point, chunksRef);
// Temporary vector to hold vertex positions during calculations
const tempVertex = new THREE.Vector3();
// Array to keep track of geometries that require normal recomputation
const geometriesToUpdate = [];
// Iterate through each neighboring chunk to apply deformations
neighboringChunks.forEach((chunk) => !geometry.attributes );
// After processing all neighboring chunks, recompute the vertex normals
// for each affected geometry. This ensures that lighting and shading
// accurately reflect the new geometry after deformation.
if (geometriesToUpdate.length > 0)
geometriesToUpdate.forEach((geometry) => geometry.computeVertexNormals());
,
[
getNeighboringChunks,
chunksRef,
saveChunkDeformation,
]
);
saya menambahkan “Tambahkan efek gelombang halus untuk variasi visual” Bagian dari fitur ini adalah untuk mengatasi masalah yang membatasi tampilan alami salju saat lintasan terbentuk. Tepi salju perlu sedikit dinaikkan. Ini tampilannya sebelum saya menambahkannya:

Setelah penciptaan deformMesh fungsinya, kita akan menentukan di mana menggunakannya untuk mencapai deformasi medan dinamis. Secara khusus, kami akan mengintegrasikannya ke dalam useFramepilih tulang kaki kiri dan kanan dalam animasi karakter dan ekstrak posisinya dari tulang tersebut matrixWorld.
useFrame((state, delta) =>
// Other codes...
// Get the bones representing the character's left and right feet
const leftFootBone = characterRef.current.getObjectByName("mixamorigLeftFoot");
const rightFootBone = characterRef.current.getObjectByName("mixamorigRightFoot");
if (leftFootBone)
// Get the world position of the left foot bone
tempVector.setFromMatrixPosition(leftFootBone.matrixWorld);
// Apply terrain deformation at the position of the left foot
deformMesh(activeChunk, tempVector);
if (rightFootBone)
// Get the world position of the right foot bone
tempVector.setFromMatrixPosition(rightFootBone.matrixWorld);
// Apply terrain deformation at the position of the right foot
deformMesh(activeChunk, tempVector);
// Other codes...
);
Itu dia: deformasi yang halus dan dinamis!


Berjalan tanpa batas dengan CHUNK
Dalam kode yang telah kita jelajahi sejauh ini, Anda mungkin menyadarinya CHUNK bagian. Sederhananya, kami membuat balok salju yang disusun dalam kotak 3×3. Untuk memastikan bahwa karakter selalu berada di tengah, kami menghapus yang sebelumnya CHUNKs dan menghasilkan yang baru berdasarkan arah pergerakan karakter CHUNKs Menuju ke arah yang sama. Anda dapat melihat proses ini beraksi di GIF di bawah. Namun, pendekatan ini menimbulkan beberapa tantangan.

pertanyaan:
- Kesenjangan muncul pada jahitan di antara CHUNK
- Perhitungan simpul rusak pada sambungan
- Saat berpindah ke CHUNK baru, track di CHUNK sebelumnya akan langsung hilang
Larutan:
1. Dapatkan ChunkKey
// Generates a unique key for a chunk based on its current position.
// Uses globally accessible CHUNK_SIZE for calculations.
// Purpose: Ensures each chunk can be uniquely identified and managed in a Map.
const deformedChunksMapRef = useRef(new Map());
const getChunkKey = () =>
`$Math.round(currentChunk.position.x / CHUNK_SIZE),$Math.round(currentChunk.position.z / CHUNK_SIZE)`;
2.Simpan Deformasi Potongan
// Saves the deformation state of the current chunk by storing its vertex positions.
// Purpose: Preserves the deformation of a chunk for later retrieval.
const saveChunkDeformation = () =>
if (!currentChunk) return;
// Generate the unique key for this chunk
const chunkKey = getChunkKey();
// Save the current vertex positions into the deformation map
const position = currentChunk.geometry.attributes.position;
deformedChunksMapRef.current.set(
chunkKey,
new Float32Array(position.array)
);
;
3. Deformasi bongkahan beban
// Restores the deformation state of the current chunk, if previously saved.
// Purpose: Ensures that deformed chunks retain their state when repositioned.
const loadChunkDeformation = () =>
if (!currentChunk) return false;
// Retrieve the unique key for this chunk
const chunkKey = getChunkKey();
// Get the saved deformation data for this chunk
const savedDeformation = deformedChunksMapRef.current.get(chunkKey);
if (savedDeformation)
const position = currentChunk.geometry.attributes.position;
// Restore the saved vertex positions
position.array.set(savedDeformation);
position.needsUpdate = true;
currentChunk.geometry.computeVertexNormals();
return true;
return false;
;
4. Dapatkan Potongan Tetangga
// Finds chunks that are close to the current position.
// Purpose: Limits deformation operations to only relevant chunks, improving performance.
const getNeighboringChunks = () =>
return chunksRef.current.filter((chunk) =>
// Calculate the distance between the chunk and the current position
const distance = new THREE.Vector2(
chunk.position.x - currentPosition.x,
chunk.position.z - currentPosition.z
).length();
// Include chunks within the deformation radius
return distance < CHUNK_SIZE + DEFORM_RADIUS;
);
;
5. Daur Ulang Potongan Jauh
// Recycles chunks that are too far from the character by resetting their deformation state.
// Purpose: Prepares distant chunks for reuse, maintaining efficient resource usage.
const recycleDistantChunks = () =>
chunksRef.current.forEach((chunk) =>
// Calculate the distance between the chunk and the character
const distance = new THREE.Vector2(
chunk.position.x - characterPosition.x,
chunk.position.z - characterPosition.z
).length();
// If the chunk is beyond the unload distance, reset its deformation
if (distance > CHUNK_UNLOAD_DISTANCE)
const geometry = chunk.geometry;
const originalPosition = geometry.userData.originalPosition;
if (originalPosition)
// Reset vertex positions to their original state
geometry.attributes.position.array.set(originalPosition);
geometry.attributes.position.needsUpdate = true;
// Recompute normals for correct lighting
geometry.computeVertexNormals();
// Remove the deformation data for this chunk
const chunkKey = getChunkKey(chunk.position.x, chunk.position.z);
deformedChunksMapRef.current.delete(chunkKey);
);
;
Melalui fungsi-fungsi ini, kami memecahkan masalah CHUNK dan mendapatkan tampilan yang kami inginkan.
sebagai kesimpulan
Dalam tutorial ini kita membahas dasar-dasar pembuatan Deformasi medan dinamis Gunakan Tri-Fiber Reaktif. Dari mencapai deformasi salju yang realistis hingga pengelolaan bagian Untuk Infinite Walk Zone, kami mengeksplorasi beberapa teknologi inti dan mengatasi tantangan umum selama prosesnya.
Meskipun proyek ini berfokus pada dasar-dasarnya, proyek ini memberikan titik awal yang kuat untuk membangun fitur yang lebih kompleks seperti kontrol karakter tingkat lanjut atau lingkungan dinamis. Konsep manipulasi titik dan manajemen blok bersifat umum dan dapat diterapkan pada banyak proyek kreatif lainnya.
Terima kasih telah membaca, saya harap tutorial ini menginspirasi Anda untuk menciptakan pengalaman 3D interaktif Anda sendiri! Jika Anda memiliki pertanyaan atau masukan, jangan ragu untuk menghubungi saya. Selamat membuat kode! 🎉
staf produksi
rencana pengembangan website
metode pengembangan website
jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website
#Buat #deformasi #medan #dinamis #menggunakan #React #Fiber