(Fortsetzung von oben) Tabletop-Spiele werden normalerweise mit einer Kernphysik-Engine erstellt. Um ein weiches Objekt in der 3D-Welt zu simulieren, ist daher ein vollständiger Physiksimulator und die Etablierung eines glaubwürdigen Verhaltens erforderlich.
WebGL und JavaScript sind noch nicht luxuriös genug, um einen vollwertigen Physiksimulator auszuführen. In diesem Spiel müssen wir also einen Weg finden, den Windeffekt zu erzeugen.
Wir betten für jedes Objekt Informationen zur „Windempfindlichkeit“ in das 3D-Modell ein. Jeder Scheitelpunkt des 3D-Modells verfügt über ein „Windattribut“, das angibt, wie stark der Scheitelpunkt von der Windgeschwindigkeit beeinflusst werden soll. Dies gibt also die Windempfindlichkeit des 3D-Objekts an. Dann müssen wir den „Wind“ selbst erzeugen.
Dazu erstellen wir ein Bild, das Perlin-Rauschen enthält. Dieses Bild soll den Wind über einen definierten Bereich abdecken. Eine gute Möglichkeit, darüber nachzudenken, besteht darin, sich Wolken vorzustellen, die einen Rahmen wie Rauschen in einem bestimmten rechteckigen Bereich einer 3D-Szene bedecken. Der Grauwert jedes Pixels in diesem Bild gibt an, wie stark die Windstärke im 3D-Bereich zu einem bestimmten Zeitpunkt ist.
Um den Effekt des Windes zu erzeugen, bewegt sich das Bild mit konstanter Geschwindigkeit und in eine bestimmte Richtung, die Richtung des Windes. Und um sicherzustellen, dass der „Windbereich“ nichts in der Szene beeinflusst, wickeln wir das Windbild um die Grenze und beschränken es auf den Wirkungsbereich.
Ein einfaches 3D-Tutorial zum Thema Wind
Lassen Sie uns nun mit Three.js einen Windeffekt in einer einfachen 3D-Szene erstellen.
Wir werden den Wind in einem einfachen „prozeduralen Gras“ erzeugen.
Zuerst erstellen wir die Szene. Wir werden einen einfachen, flachen, strukturierten Boden haben. Jeder Grashalm wird dann einfach als umgekehrter Kegel dargestellt.
Mit Gras bedeckter Boden
So erstellen Sie diese einfache Szene mit CoffeeScript in Thress.js.
Zuerst müssen wir Three.js einrichten und es mit der Kamera, der Maus und einigen Lichtern kombinieren:
<br>
constructor: -> @clock = new THREE.Clock() @container = document.createElement( 'p' ); document.body.appendChild( @container ); @renderer = new THREE.WebGLRenderer(); @renderer.setSize( window.innerWidth, window.innerHeight ); @renderer.setClearColorHex( 0x808080, 1 ) @container.appendChild(@renderer.domElement); @camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 5000 ); @camera.position.x = 5; @camera.position.y = 10; @camera.position.z = 40; @controls = new THREE.OrbitControls( @camera, @renderer.domElement ); @controls.enabled = true @scene = new THREE.Scene(); @scene.add( new THREE.AmbientLight 0xFFFFFF ) directional = new THREE.DirectionalLight 0xFFFFFF directional.position.set( 10,10,10) @scene.add( directional ) # Demo data @grassTex = THREE.ImageUtils.loadTexture("textures/grass.png"); @initGrass() @initTerrain() # Stats @stats = new Stats(); @stats.domElement.style.position = 'absolute'; @stats.domElement.style.top = '0px'; @container.appendChild( @stats.domElement ); window.addEventListener( 'resize', @onWindowResize, false ); @animate()
Die Funktionen initGrass und initTerrain werden jeweils mit Xiaocao aufgerufen . Und Bodenfüllszene:
<br/>
initGrass:-> mat = new THREE.MeshPhongMaterial( { map: @grassTex } ) NUM = 15 for i in [0..NUM] by 1 for j in [0..NUM] by 1 x = ((i/NUM) - 0.5) * 50 + THREE.Math.randFloat(-1,1) y = ((j/NUM) - 0.5) * 50 + THREE.Math.randFloat(-1,1) @scene.add( @instanceGrass( x, 2.5, y, 5.0, mat ) ) instanceGrass:(x,y,z,height,mat)-> geometry = new THREE.CylinderGeometry( 0.9, 0.0, height, 3, 5 ) mesh = new THREE.Mesh( geometry, mat ) mesh.position.set( x, y, z ) return mesh
Hier erstellen wir ein Gitter aus 15*15 Gras. Wir haben der Position jedes Grashalms eine Zufallszahl hinzugefügt, damit sie nicht seltsam aussehen, weil sie zu ordentlich angeordnet sind.
Dieses Gelände ist nur eine horizontale Ebene, die an den Wurzeln dieser Gräser liegt (Y = 2,5).
<br/>
initTerrain:-> @plane = new THREE.Mesh( new THREE.PlaneGeometry(60, 60, 2, 2), new THREE.MeshPhongMaterial({ map: @grassTex })) @plane.rotation.x = -Math.PI/2 @scene.add( @plane )
Was wir also bisher gemacht haben, ist einfach eine Three.js-Szene erstellt und etwas Gras hinzugefügt, ein prozedural generierter umgekehrter Kegel erstellt und ein einfacher Boden.
Bisher nichts Besonderes.
<br/>
Jetzt ist es an der Zeit, den Wind hinzuzufügen. Zunächst möchten wir Informationen zur Windempfindlichkeit in das 3D-Modell des Grases einbetten.
Wir müssen diese Informationen als benutzerdefiniertes Attribut in jeden Scheitelpunkt des Xiaocao-3D-Modells einbetten. Die Regel, die wir verwenden werden, lautet: Die Unterseite jedes Grasmodells (die Oberseite des Kegels) hat eine Windempfindlichkeit von 0, da es am Boden klebt. Die Spitze des Grasmodells (die Basis des Kegels) weist die größte Windempfindlichkeit auf, da sie weiter vom Boden entfernt ist.
Im Folgenden erfahren Sie, wie Sie die Funktion „instanceGrass“ neu schreiben, um die Windempfindlichkeit als benutzerdefinierten Parameter zum 3D-Grasmodell hinzuzufügen.
<br/>
instanceGrass:(x,y,z,height)-> geometry = new THREE.CylinderGeometry( 0.9, 0.0, height, 3, 5 ) for i in [0..geometry.vertices.length-1] by 1 v = geometry.vertices[i] r = (v.y / height) + 0.5 @windMaterial.attributes.windFactor.value[i] = r * r * r # Create mesh mesh = new THREE.Mesh( geometry, @windMaterial ) mesh.position.set( x, y, z ) return mesh
<br>
Das obige ist der detaillierte Inhalt vonSo entwickeln Sie hervorragende HTML5-Spiele – Ausführliche Erklärung der Disney-Spieltechnologie „Finding Road to Oz' (2). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!