3D-Partikeleffekt-Ingenieur für WebGL-Übergangssystem
Von Wikiprompt, der freien Prompt-Enzyklopädie
3D-Partikeleffekt-Ingenieur für WebGL-Übergangssystem Ein Prompt für eine KI, die als 3D-Partikeleffekt-Ingenieur agiert und ein WebGL-Übergangssystem mit Mesh-zu-Partikel-Morphing, FBO, GPGPU und Noise-Turbulenz entwirft.
Prompt-InhaltSpeichern
🌐
Konzeptionelle Shader-Logik und Kern-JavaScript-Implementierung mit Three.js:
**1. Vertex-Shader (Particle-Update via GPGPU):**
```glsl
// Vertex-Shader für FBO-Update (Ping-Pong-Texturen)
uniform sampler2D uPositionTexture; // Aktuelle Positionen
uniform sampler2D uVelocityTexture; // Aktuelle Geschwindigkeiten
uniform sampler2D uTargetTexture; // Ziel-Ankerpunkte (aus Mesh)
uniform float uTime;
uniform float uTransitionProgress; // 0 = Start, 1 = Ziel
uniform float uNoiseScale;
uniform float uForceStrength;
varying vec2 vUv;
// 3D Simplex-Noise (vereinfachte Implementierung)
float noise(vec3 p) {
// ... (Standard-Simplex-Noise-Code hier einfügen)
}
void main() {
vec2 uv = gl_FragCoord.xy / uResolution;
vec3 position = texture2D(uPositionTexture, uv).xyz;
vec3 velocity = texture2D(uVelocityTexture, uv).xyz;
vec3 target = texture2D(uTargetTexture, uv).xyz;
// 1. Anziehungskraft zum Ziel
vec3 toTarget = target - position;
float dist = length(toTarget);
vec3 attraction = normalize(toTarget) * uForceStrength * (1.0 - uTransitionProgress);
// 2. Abstoßung zwischen Partikeln (vereinfacht - in echtem GPGPU mit Nachbarschaftssuche)
// Hier: Pseudo-Abstoßung durch Noise-Feld
vec3 noiseForce = noise(position * uNoiseScale + uTime * 0.5) * 0.5;
// 3. Turbulenz-Feld (organische Bewegung)
vec3 turbulence = noise(position * 0.8 + uTime * 0.3) * (1.0 - uTransitionProgress);
// 4. Geschwindigkeits-Update
velocity += (attraction + noiseForce + turbulence) * 0.01;
velocity *= 0.98; // Dämpfung
// 5. Positions-Update
position += velocity;
// 6. Übergangs-Mischung (für sanfte Morphing-Phase)
position = mix(position, target, uTransitionProgress * 0.05);
gl_FragColor = vec4(position, 1.0);
}
```
**2. Fragment-Shader (Particle-Rendering):**
```glsl
// Fragment-Shader für Partikel-Darstellung
uniform sampler2D uPositionTexture;
uniform float uPointSize;
uniform float uTime;
varying vec2 vUv;
void main() {
vec3 pos = texture2D(uPositionTexture, vUv).xyz;
// Dynamischer Farbverlauf basierend auf Geschwindigkeit/Distanz
float speed = length(pos - texture2D(uPositionTexture, vUv + 0.001).xyz);
float distFromCenter = length(pos);
vec3 color1 = vec3(0.2, 0.6, 1.0); // Blau
vec3 color2 = vec3(1.0, 0.4, 0.2); // Orange
vec3 color = mix(color1, color2, speed * 5.0 + distFromCenter * 0.1);
// Runde Partikelform
vec2 center = gl_PointCoord - 0.5;
float alpha = 1.0 - smoothstep(0.0, 0.5, length(center));
gl_FragColor = vec4(color, alpha);
}
```
**3. Kern-JavaScript (Three.js):**
```javascript
class ParticleMorphSystem {
constructor(scene, renderer) {
this.scene = scene;
this.renderer = renderer;
this.particleCount = 50000;
// FBO-Texturen für GPGPU
this.initFBO();
this.initParticles();
this.initTargetMeshes();
}
initFBO() {
// Position-Texturen (Ping-Pong)
this.posTexA = this.createTexture();
this.posTexB = this.createTexture();
this.velTex = this.createTexture();
this.targetTex = this.createTexture();
// FBO-Objekte
this.fboA = new THREE.WebGLRenderTarget(256, 256, {
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
format: THREE.RGBAFormat,
type: THREE.FloatType
});
this.fboB = this.fboA.clone();
}
createTexture() {
const data = new Float32Array(this.particleCount * 4);
// Initialisiere mit zufälligen Positionen in einer Kugel
for (let i = 0; i < this.particleCount; i++) {
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos(2 * Math.random() - 1);
const r = 2 + Math.random() * 3;
data[i * 4] = r * Math.sin(phi) * Math.cos(theta);
data[i * 4 + 1] = r * Math.sin(phi) * Math.sin(theta);
data[i * 4 + 2] = r * Math.cos(phi);
data[i * 4 + 3] = 1.0;
}
const texture = new THREE.DataTexture(data, 256, 256, THREE.RGBAFormat, THREE.FloatType);
texture.needsUpdate = true;
return texture;
}
initParticles() {
// Partikel-Geometrie
const geometry = new THREE.BufferGeometry();
const positions = new Float32Array(this.particleCount * 3);
const uvs = new Float32Array(this.particleCount * 2);
for (let i = 0; i < this.particleCount; i++) {
positions[i * 3] = 0;
positions[i * 3 + 1] = 0;
positions[i * 3 + 2] = 0;
uvs[i * 2] = (i % 256) / 256;
uvs[i * 2 + 1] = Math.floor(i / 256) / 256;
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));
// Partikel-Material
const material = new THREE.ShaderMaterial({
uniforms: {
uPositionTexture: { value: this.posTexA },
uPointSize: { value: 2.0 },
uTime: { value: 0 }
},
vertexShader: this.particleVertexShader,
fragmentShader: this.particleFragmentShader,
transparent: true,
depthWrite: false,
blending: THREE.AdditiveBlending
});
this.particles = new THREE.Points(geometry, material);
this.scene.add(this.particles);
}
initTargetMeshes() {
// Beispiel: Torus als Ziel-Mesh
const torusGeometry = new THREE.TorusGeometry(2, 0.8, 32, 64);
this.extractMeshVertices(torusGeometry);
// Oder: GLTF-Modell laden
// const loader = new THREE.GLTFLoader();
// loader.load('model.gltf', (gltf) => {
// this.extractMeshVertices(gltf.scene.children[0].geometry);
// });
}
extractMeshVertices(geometry) {
// Extrahiere Vertex-Daten in Ziel-Textur
const vertices = geometry.attributes.position.array;
const targetData = new Float32Array(this.particleCount * 4);
// Sample Vertices (bei mehr Partikeln als Vertices: Interpolation)
for (let i = 0; i < this.particleCount; i++) {
const idx = Math.floor(Math.random() * (vertices.length / 3)) * 3;
targetData[i * 4] = vertices[idx];
targetData[i * 4 + 1] = vertices[idx + 1];
targetData[i * 4 + 2] = vertices[idx + 2];
targetData[i * 4 + 3] = 1.0;
}
const targetTexture = new THREE.DataTexture(targetData, 256, 256, THREE.RGBAFormat, THREE.FloatType);
targetTexture.needsUpdate = true;
this.targetTex = targetTexture;
}
update(deltaTime) {
// GPGPU-Update durchführen
this.renderer.setRenderTarget(this.fboA);
this.updateMaterial.uniforms.uPositionTexture.value = this.posTexA;
this.updateMaterial.uniforms.uVelocityTexture.value = this.velTex;
this.updateMaterial.uniforms.uTargetTexture.value = this.targetTex;
this.renderer.render(this.updateScene, this.updateCamera);
// Ping-Pong: Texturen tauschen
const temp = this.posTexA;
this.posTexA = this.posTexB;
this.posTexB = temp;
// Partikel-Material aktualisieren
this.particles.material.uniforms.uPositionTexture.value = this.posTexA;
this.particles.material.uniforms.uTime.value += deltaTime;
}
// Übergang starten
morphTo(targetMesh) {
this.extractMeshVertices(targetMesh);
// Übergangs-Progress animieren (0 -> 1)
// Implementierung mit Tween oder manuell
}
}
```
**4. Wichtige Konzepte:**
- **FBO-Ping-Pong**: Zwei Render-Targets werden abwechselnd als Input/Output verwendet, um Daten auf der GPU zu aktualisieren.
- **Vertex-Mapping**: Jeder Partikel erhält eine UV-Koordinate, die auf die Ziel-Textur zeigt. Die Vertex-Positionen des 3D-Modells werden in eine Textur geschrieben.
- **Kraftberechnung**: Anziehung (zum Ziel), Abstoßung (durch Noise), und Turbulenz (Perlin/Simplex) werden kombiniert.
- **Performance**: 50.000+ Partikel laufen vollständig auf der GPU, ohne CPU-Bottleneck.
**5. Erweiterungen:**
- Nachbarschaftssuche für echte Partikel-Kollisionen (via Sortierung oder Spatial Hashing)
- Mehrere Ziel-Meshes für komplexe Morphing-Sequenzen
- Interaktive Steuerung (Maus-Position als zusätzliche Kraftquelle)
- Shader-basierte Größen- und Opazitäts-Animation
Melde dich an, um den vollständigen Prompt zu sehen
Weiter mit:
Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz
Verwendung
Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.
Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.
Diskussion
0 Kommentare