The prompt that made it
as published# GENERATIVE MOUNTAIN SCENE — COMPONENT INTEGRATION
YOU ARE GIVEN A TASK TO INTEGRATE AN EXISTING REACT COMPONENT IN THE CODEBASE
THE CODEBASE SHOULD SUPPORT:
- SHADCN PROJECT STRUCTURE
- TAILWIND CSS
- TYPESCRIPT
IF IT DOESN'T, PROVIDE INSTRUCTIONS ON HOW TO SETUP PROJECT VIA SHADCN CLI, INSTALL TAILWIND OR TYPESCRIPT.
DETERMINE THE DEFAULT PATH FOR COMPONENTS AND STYLES.
IF DEFAULT PATH FOR COMPONENTS IS NOT /COMPONENTS/UI, PROVIDE INSTRUCTIONS ON WHY IT'S IMPORTANT TO CREATE THIS FOLDER
COPY-PASTE THIS COMPONENT TO /COMPONENTS/UI FOLDER:
```tsx
mountain-scene.tsx
import React, { useRef, useEffect } from "react";
import * as THREE from "three";
/**
* GenerativeMountainScene
* * Renders a solid, undulating mountain landscape.
* * "No gaps" (wireframe: false) implementation.
*/
export function GenerativeMountainScene() {
const mountRef = useRef(null);
const lightRef = useRef(null);
useEffect(() => {
const currentMount = mountRef.current;
// SCENE SETUP
const scene = new THREE.Scene();
// Camera setup
const camera = new THREE.PerspectiveCamera(
75,
currentMount.clientWidth / currentMount.clientHeight,
0.1,
100
);
camera.position.set(0, 1.5, 3);
camera.rotation.x = -0.3;
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(currentMount.clientWidth, currentMount.clientHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
currentMount.appendChild(renderer.domElement);
// GEOMETRY
const geometry = new THREE.PlaneGeometry(12, 8, 128, 128);
// SHADER MATERIAL
const material = new THREE.ShaderMaterial({
side: THREE.DoubleSide,
wireframe: false, // Changed to false to remove gaps (make solid)
uniforms: {
time: { value: 0 },
pointLightPosition: { value: new THREE.Vector3(0, 0, 5) },
color: { value: new THREE.Color("#7dd3fc") },
},
vertexShader: `
uniform float time;
varying vec3 vNormal;
varying vec3 vPosition;
// --- PERLIN NOISE FUNCTIONS ---
vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }
vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
float snoise(vec3 v) {
const vec2 C = vec2(1.0/6.0, 1.0/3.0);
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
vec3 i = floor(v + dot(v, C.yyy));
vec3 x0 = v - i + dot(i, C.xxx);
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min(g.xyz, l.zxy);
vec3 i2 = max(g.xyz, l.zxy);
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy;
vec3 x3 = x0 - D.yyy;
i = mod289(i);
vec4 p = permute(permute(permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0));
float n_ = 0.142857142857;
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z);
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_);
vec4 x = x_ * ns.x + ns.yyyy;
vec4 y = y_ * ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4(x.xy, y.xy);
vec4 b1 = vec4(x.zw, y.zw);
vec4 s0 = floor(b0) * 2.0 + 1.0;
vec4 s1 = floor(b1) * 2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
vec3 p0 = vec3(a0.xy, h.x);
vec3 p1 = vec3(a0.zw, h.y);
vec3 p2 = vec3(a1.xy, h.z);
vec3 p3 = vec3(a1.zw, h.w);
vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w;
vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
m = m * m;
return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}
void main() {
vNormal = normal;
vPosition = position;
float noiseFreq = 0.8;
float noiseAmp = 0.6;
// Layer 1: Base shape
float displacement = snoise(vec3(position.x * noiseFreq, position.y * noiseFreq - time * 0.2, 0.0)) * noiseAmp;
// Layer 2: Detail
displacement += snoise(vec3(position.x * noiseFreq * 2.0, position.y * noiseFreq * 2.0 - time * 0.2, 0.0)) * (noiseAmp * 0.5);
vec3 newPosition = position + normal * displacement;
gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
}
`,
fragmentShader: `
uniform vec3 color;
uniform vec3 pointLightPosition;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vec3 normal = normalize(vNormal);
vec3 lightDir = normalize(pointLightPosition - vPosition);
float diffuse = max(dot(normal, lightDir), 0.0);
float fresnel = 1.0 - dot(normal, vec3(0.0, 0.0, 1.0));
fresnel = pow(fresnel, 2.0);
vec3 finalColor = color * diffuse + color * fresnel * 0.5;
gl_FragColor = vec4(finalColor, 1.0);
}
`,
transparent: true,
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x = -Math.PI / 2;
scene.add(mesh);
const pointLight = new THREE.PointLight(0xffffff, 1, 100);
pointLight.position.set(0, 0, 5);
lightRef.current = pointLight;
scene.add(pointLight);
let frameId;
const animate = (t) => {
material.uniforms.time.value = t * 0.0003;
renderer.render(scene, camera);
frameId = requestAnimationFrame(animate);
};
animate(0);
const handleResize = () => {
if (!currentMount) return;
camera.aspect = currentMount.clientWidth / currentMount.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(currentMount.clientWidth, currentMount.clientHeight);
};
const handleMouseMove = (e) => {
const x = (e.clientX / window.innerWidth) * 2 - 1;
const y = -(e.clientY / window.innerHeight) * 2 + 1;
const lightX = x * 5;
const lightY = y * 5;
const pos = new THREE.Vector3(lightX, 2, 2 - y * 2);
lightRef.current.position.copy(pos);
if (material.uniforms.pointLightPosition) {
material.uniforms.pointLightPosition.value = pos;
}
};
window.addEventListener("resize", handleResize);
window.addEventListener("mousemove", handleMouseMove);
return () => {
cancelAnimationFrame(frameId);
window.removeEventListener("resize", handleResize);
window.removeEventListener("mousemove", handleMouseMove);
if (currentMount) currentMount.removeChild(renderer.domElement);
geometry.dispose();
material.dispose();
};
}, []);
return <div ref={mountRef} className="absolute inset-0 w-full h-full z-0" />;
}
export default GenerativeMountainScene;
demo.tsx
import React, { Suspense } from "react";
import GenerativeMountainScene from "@/components/ui/mountain-scene";
export default function DemoOne() {
return (
<main className="relative w-full h-screen bg-[#0f172a] overflow-hidden text-slate-100">
<Suspense fallback={<div className="w-full h-full bg-[#0f172a]" />}>
<GenerativeMountainScene />
</Suspense>
</main>
);
}
```
INSTALL NPM DEPENDENCIES:
```bash
three
```
## IMPLEMENTATION GUIDELINES
1. ANALYZE THE COMPONENT STRUCTURE AND IDENTIFY ALL REQUIRED DEPENDENCIES
2. REVIEW THE COMPONENT'S ARGUMENS AND STATE
3. IDENTIFY ANY REQUIRED CONTEXT PROVIDERS OR HOOKS AND INSTALL THEM
4. QUESTIONS TO ASK
- WHAT DATA/PROPS WILL BE PASSED TO THIS COMPONENT?
- ARE THERE ANY SPECIFIC STATE MANAGEMENT REQUIREMENTS?
- ARE THERE ANY REQUIRED ASSETS (IMAGES, ICONS, ETC.)?
- WHAT IS THE EXPECTED RESPONSIVE BEHAVIOR?
- WHAT IS THE BEST PLACE TO USE THIS COMPONENT IN THE APP?
## STEPS TO INTEGRATE
0. COPY PASTE ALL THE CODE ABOVE IN THE CORRECT DIRECTORIES
1. INSTALL EXTERNAL DEPENDENCIES
2. FILL IMAGE ASSETS WITH UNSPLASH STOCK IMAGES YOU KNOW EXIST
3. USE LUCIDE-REACT ICONS FOR SVGS OR LOGOS IF COMPONENT REQUIRES THEMAdds a render step. Works best with the HyperFrames or Remotion skills installed. Free, no sign-up.
Prompt by @pulkitxm. Prompts belong to their creators.