This commit is contained in:
2025-01-05 21:32:44 +01:00
parent 667dc0da8a
commit a4f1cda387
+121 -27
View File
@@ -5,7 +5,9 @@ const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerH
const renderer = new THREE.WebGLRenderer({ alpha: true }) const renderer = new THREE.WebGLRenderer({ alpha: true })
if (!renderer) { if (!renderer) {
alert("Renderer failed to load") alert("Renderer failed to load, using static images instead.")
// TODO: add image logic
throw new Error("Renderer initialization failed.")
} }
renderer.setSize(window.innerWidth, window.innerHeight) renderer.setSize(window.innerWidth, window.innerHeight)
@@ -40,9 +42,11 @@ const mesh = new THREE.Mesh(geometry, material)
//scene.add(mesh) //scene.add(mesh)
camera.position.z = 5 /* camera.position.z = 5
camera.position.y = 2 camera.position.y = 2 */
camera.position.y = 5
camera.lookAt(0, 0, 0)
function hillCurve(x, width) { function hillCurve(x, width) {
return (Math.sin(Math.PI * (x + 1)) + 1) ** width return (Math.sin(Math.PI * (x + 1)) + 1) ** width
@@ -50,51 +54,141 @@ function hillCurve(x, width) {
function generateHill(width, length, segments, maxHeight, posOffsetZ = 0, prevHillVerts = []) { function generateHill(width, length, segments, maxHeight, posOffsetZ = 0, prevHillVerts = []) {
let hillVerts = []
let hillIndices = [] let hillIndices = []
let startPos = -width / 2 let startPos = -width / 2
let triCount = segments + 1 let triCount = segments + 1
let prevHillHeights = prevHillVerts.filter((_, index) => (index - 1) % 3 === 0) let prevHillHeights = prevHillVerts.filter((_, index) => (index - 1) % 3 === 0)
for (i = 0; i < triCount; i++) { let hillData = generateHillVerts(
let height = randomFloat(0, maxHeight) * hillCurve(i / triCount, 1.2) triCount,
maxHeight,
width,
startPos,
prevHillHeights,
segments,
length,
posOffsetZ
)
let hillVerts = hillData.verts
let hillUVs = hillData.uvs
hillVerts.push(i / (triCount - 1) * width + startPos) for (i = 0; i < segments; i++) {
hillIndices.push(i * 2, i * 2 + 2, i * 2 + 1)
if (prevHillHeights.length / 2 != segments + 1) { hillIndices.push(i * 2 + 1, i * 2 + 2, i * 2 + 3)
hillVerts.push(0)
}
else {
hillVerts.push(prevHillHeights[i * 2 + 1])
}
hillVerts.push(length / 2 + posOffsetZ)
hillVerts.push(i / (triCount - 1) * width + startPos)
hillVerts.push(height)
hillVerts.push(-length / 2 + posOffsetZ)
}
for (let i = 0; i < hillVerts.length / 2 - (segments + 3); i++) {
hillIndices.push(i)
hillIndices.push(i + 1)
hillIndices.push(i + 2)
} }
const geometry = new THREE.BufferGeometry() const geometry = new THREE.BufferGeometry()
geometry.setAttribute("position", new THREE.BufferAttribute(new Float32Array(hillVerts), 3)) geometry.setAttribute("position", new THREE.BufferAttribute(new Float32Array(hillVerts), 3))
geometry.setAttribute("uv", new THREE.BufferAttribute(new Float32Array(hillUVs), 2))
geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(hillIndices), 1)) geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(hillIndices), 1))
geometry.computeVertexNormals() geometry.computeVertexNormals()
const material = new THREE.MeshBasicMaterial({ color: 0x00FF00, wireframe: true, side: THREE.DoubleSide }) const material = generateHillMat(segments, width, length)
const newMesh = new THREE.Mesh(geometry, material) const newMesh = new THREE.Mesh(geometry, material)
return {mesh: newMesh, verts: hillVerts, indices: hillIndices} return {mesh: newMesh, verts: hillVerts, indices: hillIndices}
} }
function generateHillVerts(
triCount,
maxHeight,
width,
startPos,
prevHillHeights,
segments,
length,
posOffsetZ
) {
let hillVerts = []
let hillUVs = []
for (i = 0; i < triCount; i++) {
let height = randomFloat(0, maxHeight) * hillCurve(i / triCount, 1.2)
hillVerts.push(i / (triCount - 1) * width + startPos)
if (prevHillHeights.length / 2 != segments + 1) { hillVerts.push(0) }
else { hillVerts.push(prevHillHeights[i * 2 + 1]) }
hillVerts.push(length / 2 + posOffsetZ)
hillUVs.push(i / (triCount - 1), 0)
hillVerts.push(
i / (triCount - 1) * width + startPos,
height,
-length / 2 + posOffsetZ
)
hillUVs.push(i / (triCount - 1), 1)
}
return {verts: hillVerts, uvs: hillUVs}
}
function generateHillMat(segments, width, length) {
//return new THREE.MeshBasicMaterial({ color: 0x00FF00, wireframe: false })
const vertexShader = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`
const fragmentShader = `
varying vec2 vUv;
uniform vec3 edgeColor;
uniform vec3 centerColor;
uniform int segmentCount;
uniform float aspectRatio;
void main() {
vec2 uv = vUv;
uv.x = fract(uv.x * float(segmentCount));
// Define the edge threshold
float edgeThreshold = 0.1;
// Check for the top, bottom, and sides (not including corners as edges)
float isEdge = 0.0;
// Check top and bottom edges
if (uv.y < edgeThreshold || uv.y > (1.0 - edgeThreshold)) {
isEdge = 1.0;
}
// Check side edges, but exclude corners
if (uv.x < edgeThreshold || uv.x > (1.0 - edgeThreshold)) {
isEdge = 1.0;
}
// Mix the colors based on whether it's an edge
vec3 color = mix(centerColor, edgeColor, isEdge);
gl_FragColor = vec4(color, 1.0);
}
`
const material = new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
uniforms: {
edgeColor: { value: new THREE.Color(0x00b4f0) },
centerColor: { value: new THREE.Color(0x323232) },
segmentCount: { value: segments },
aspectRatio: { value: (width / segments) / length }
}
})
return material
}
function animate() { function animate() {
requestAnimationFrame(animate) requestAnimationFrame(animate)