-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added butterflies on habitable planets
- Loading branch information
1 parent
8bbe567
commit 98e2086
Showing
7 changed files
with
283 additions
and
3 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
precision highp float; | ||
|
||
uniform float time; | ||
|
||
uniform vec3 lightDirection; | ||
|
||
uniform sampler2D butterflyTexture; | ||
|
||
varying vec3 vPosition; | ||
varying vec2 vUV; | ||
|
||
varying mat4 normalMatrix; | ||
varying vec3 vNormal; | ||
|
||
varying vec3 vOriginalWorldPosition; | ||
|
||
// src: https://gist.github.com/mairod/a75e7b44f68110e1576d77419d608786 | ||
vec3 hueShift( vec3 color, float hueAdjust ){ | ||
const vec3 kRGBToYPrime = vec3 (0.299, 0.587, 0.114); | ||
const vec3 kRGBToI = vec3 (0.596, -0.275, -0.321); | ||
const vec3 kRGBToQ = vec3 (0.212, -0.523, 0.311); | ||
|
||
const vec3 kYIQToR = vec3 (1.0, 0.956, 0.621); | ||
const vec3 kYIQToG = vec3 (1.0, -0.272, -0.647); | ||
const vec3 kYIQToB = vec3 (1.0, -1.107, 1.704); | ||
|
||
float YPrime = dot (color, kRGBToYPrime); | ||
float I = dot (color, kRGBToI); | ||
float Q = dot (color, kRGBToQ); | ||
float hue = atan (Q, I); | ||
float chroma = sqrt (I * I + Q * Q); | ||
|
||
hue += hueAdjust; | ||
|
||
Q = chroma * sin (hue); | ||
I = chroma * cos (hue); | ||
|
||
vec3 yIQ = vec3 (YPrime, I, Q); | ||
|
||
return vec3( dot (yIQ, kYIQToR), dot (yIQ, kYIQToG), dot (yIQ, kYIQToB) ); | ||
} | ||
|
||
void main() { | ||
vec4 finalColor = texture(butterflyTexture, vUV); | ||
if(finalColor.a < 0.1) discard; | ||
|
||
finalColor.rgb = hueShift(finalColor.rgb, vOriginalWorldPosition.x * 10.0 + vOriginalWorldPosition.z * 10.0); | ||
|
||
vec3 normalW = normalize((normalMatrix * vec4(vNormal, 0.0)).xyz); | ||
|
||
float ndl1 = max(dot(normalW, lightDirection), 0.0); | ||
float ndl2 = max(dot(-normalW, lightDirection), 0.0); | ||
float ndl = ndl1 + ndl2; | ||
|
||
// ambient lighting | ||
ndl = clamp(ndl + 0.1, 0.0, 1.0); | ||
|
||
gl_FragColor = vec4(finalColor.rgb * ndl, 1.0);// apply color and lighting | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
precision highp float; | ||
|
||
attribute vec3 position; | ||
attribute vec3 normal; | ||
attribute vec2 uv; | ||
|
||
uniform mat4 viewProjection; | ||
|
||
//uniform mat4 world; | ||
|
||
uniform vec3 playerPosition; | ||
|
||
uniform float time; | ||
|
||
varying vec3 vPosition; | ||
varying vec2 vUV; | ||
|
||
varying mat4 normalMatrix; | ||
varying vec3 vNormal; | ||
|
||
varying vec3 vOriginalWorldPosition; | ||
|
||
#include "../utils/rotateAround.glsl"; | ||
|
||
float easeOut(float t, float a) { | ||
return 1.0 - pow(1.0 - t, a); | ||
} | ||
|
||
float easeIn(float t, float alpha) { | ||
return pow(t, alpha); | ||
} | ||
|
||
#include "../utils/remap.glsl"; | ||
|
||
#include<instancesDeclaration> | ||
|
||
void main() { | ||
#include<instancesVertex> | ||
|
||
vec3 objectWorld = vec3(finalWorld[3].x, finalWorld[3].y, finalWorld[3].z); | ||
vOriginalWorldPosition = objectWorld; | ||
|
||
// high frequency movement for wing flap | ||
objectWorld.y += 0.1 * sin(5.0 * time + objectWorld.x * 10.0 + objectWorld.z * 10.0); | ||
// low frequency movement of larger amplitude for general movement | ||
objectWorld.y += 0.5 * sin(0.2 * time + objectWorld.x * 15.0 + objectWorld.z * 15.0); | ||
|
||
vec3 butterflyForward = vec3(1.0, 0.0, 0.0); | ||
|
||
float rotationY = sin(0.5 * time + vOriginalWorldPosition.x * 10.0 + vOriginalWorldPosition.z * 10.0) * 3.14; | ||
vec3 rotatedPosition = rotateAround(position, vec3(0.0, 1.0, 0.0), rotationY); | ||
butterflyForward = rotateAround(butterflyForward, vec3(0.0, 1.0, 0.0), rotationY); | ||
|
||
vec3 flyPosition = rotateAround(rotatedPosition, butterflyForward, sign(position.z) * cos(10.0 * time + objectWorld.x * 10.0 + objectWorld.z * 10.0)); | ||
flyPosition.y += 3.0; | ||
|
||
objectWorld += butterflyForward * 0.5 * sin(0.5 * time + vOriginalWorldPosition.x * 10.0 + vOriginalWorldPosition.z * 10.0); | ||
|
||
// avoid the player | ||
vec3 playerToButterfly = objectWorld - playerPosition; | ||
playerToButterfly.y = 0.0; | ||
float distanceToPlayer = length(playerToButterfly); | ||
if (distanceToPlayer < 2.0) { | ||
objectWorld += normalize(playerToButterfly) * (2.0 - distanceToPlayer); | ||
} | ||
|
||
finalWorld[3].xyz = objectWorld; | ||
|
||
vec4 outPosition = viewProjection * finalWorld * vec4(flyPosition, 1.0); | ||
gl_Position = outPosition; | ||
|
||
vPosition = flyPosition; | ||
vUV = uv; | ||
|
||
normalMatrix = transpose(inverse(finalWorld)); | ||
|
||
vNormal = normal; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; | ||
import { Mesh } from "@babylonjs/core/Meshes/mesh"; | ||
import { Scene } from "@babylonjs/core/scene"; | ||
import { createButterflyMaterial } from "./butterflyMaterial"; | ||
|
||
export function createButterfly(scene: Scene) { | ||
const positions = new Float32Array(6 * 3); | ||
const indices = new Uint32Array(4 * 3); | ||
const uvs = new Float32Array(6 * 2); | ||
|
||
// butter fly is made of 4 triangles (2 squares touching each other) | ||
// 0--1 | ||
// | /| | ||
// |/ | | ||
// 2--3 | ||
positions[0] = 0; | ||
positions[1] = 0; | ||
positions[2] = -1; | ||
|
||
positions[3] = 1; | ||
positions[4] = 0; | ||
positions[5] = -1; | ||
|
||
positions[6] = 0; | ||
positions[7] = 0.0; | ||
positions[8] = 0.0; | ||
|
||
positions[9] = 1; | ||
positions[10] = 0; | ||
positions[11] = 0; | ||
|
||
positions[12] = 0; | ||
positions[13] = 0; | ||
positions[14] = 1; | ||
|
||
positions[15] = 1; | ||
positions[16] = 0; | ||
positions[17] = 1; | ||
|
||
// first square | ||
indices[0] = 0; | ||
indices[1] = 1; | ||
indices[2] = 2; | ||
|
||
indices[3] = 1; | ||
indices[4] = 3; | ||
indices[5] = 2; | ||
|
||
// second square | ||
indices[6] = 2; | ||
indices[7] = 3; | ||
indices[8] = 4; | ||
|
||
indices[9] = 3; | ||
indices[10] = 5; | ||
indices[11] = 4; | ||
|
||
// uvs (0,0) is bottom left, (1,1) is top right | ||
uvs[0] = 0; | ||
uvs[1] = 0; | ||
|
||
uvs[2] = 0; | ||
uvs[3] = 1; | ||
|
||
uvs[4] = 0.5; | ||
uvs[5] = 0; | ||
|
||
uvs[6] = 0.5; | ||
uvs[7] = 1; | ||
|
||
uvs[8] = 1; | ||
uvs[9] = 0; | ||
|
||
uvs[10] = 1; | ||
uvs[11] = 1; | ||
|
||
const vertexData = new VertexData(); | ||
vertexData.positions = positions; | ||
vertexData.indices = indices; | ||
vertexData.uvs = uvs; | ||
|
||
const mesh = new Mesh("butterfly", scene); | ||
vertexData.applyToMesh(mesh); | ||
mesh.createNormals(false); | ||
|
||
mesh.scaling.scaleInPlace(0.2); | ||
mesh.bakeCurrentTransformIntoVertices(); | ||
|
||
mesh.material = createButterflyMaterial(scene); | ||
|
||
return mesh; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Scene } from "@babylonjs/core/scene"; | ||
import { Effect } from "@babylonjs/core/Materials/effect"; | ||
import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial"; | ||
import butterflyFragment from "../../../shaders/butterflyMaterial/butterflyFragment.glsl"; | ||
import butterflyVertex from "../../../shaders/butterflyMaterial/butterflyVertex.glsl"; | ||
|
||
import butterflyTexture from "../../../asset/butterfly.png"; | ||
import { Texture } from "@babylonjs/core/Materials/Textures/texture"; | ||
import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; | ||
import { Vector3 } from "@babylonjs/core/Maths/math.vector"; | ||
import { PointLight } from "@babylonjs/core/Lights/pointLight"; | ||
|
||
export function createButterflyMaterial(scene: Scene, player?: TransformNode) { | ||
const shaderName = "butterflyMaterial"; | ||
Effect.ShadersStore[`${shaderName}FragmentShader`] = butterflyFragment; | ||
Effect.ShadersStore[`${shaderName}VertexShader`] = butterflyVertex; | ||
|
||
const butterflyMaterial = new ShaderMaterial(shaderName, scene, shaderName, { | ||
attributes: ["position", "normal", "uv"], | ||
uniforms: ["world", "worldView", "worldViewProjection", "view", "projection", "viewProjection", "time", "lightDirection", "playerPosition"], | ||
defines: ["#define INSTANCES"], | ||
samplers: ["butterflyTexture"] | ||
}); | ||
|
||
butterflyMaterial.setTexture("butterflyTexture", new Texture(butterflyTexture, scene)); | ||
butterflyMaterial.backFaceCulling = false; | ||
|
||
let elapsedSeconds = 0; | ||
scene.onBeforeRenderObservable.add(() => { | ||
elapsedSeconds += scene.getEngine().getDeltaTime() / 1000; | ||
|
||
if(scene.activeCamera === null) throw new Error("Active camera is null"); | ||
|
||
const star = scene.lights[1]; | ||
if(!(star instanceof PointLight)) throw new Error("Could not find star light"); | ||
|
||
const lightDirection = star.position.subtract(scene.activeCamera.globalPosition).normalize(); | ||
butterflyMaterial.setVector3("lightDirection", lightDirection); | ||
|
||
const playerPosition = player?.position ?? new Vector3(0, 0, 0); | ||
butterflyMaterial.setVector3("playerPosition", playerPosition); | ||
butterflyMaterial.setFloat("time", elapsedSeconds); | ||
}); | ||
|
||
return butterflyMaterial; | ||
} |