Skip to content

Commit

Permalink
Merge pull request #9 from BarthPaleologue/WIP
Browse files Browse the repository at this point in the history
Improved planet surfaces
  • Loading branch information
BarthPaleologue authored Jan 13, 2024
2 parents 4ec3d48 + 98e2086 commit 1223d30
Show file tree
Hide file tree
Showing 28 changed files with 717 additions and 94 deletions.
Binary file added src/asset/butterfly.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/asset/perlin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/asset/tree/Tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/asset/tree/tree.babylon

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions src/shaders/butterflyMaterial/butterflyFragment.glsl
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
}
78 changes: 78 additions & 0 deletions src/shaders/butterflyMaterial/butterflyVertex.glsl
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;
}
32 changes: 32 additions & 0 deletions src/shaders/grassMaterial/grassFragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
precision highp float;

uniform float time;

uniform vec3 lightDirection;

varying vec3 vPosition;

varying mat4 normalMatrix;
varying vec3 vNormal;

void main() {
vec3 baseColor = vec3(0.05, 0.2, 0.01);
vec3 tipColor = vec3(0.5, 0.5, 0.1);

vec3 finalColor = mix(baseColor, tipColor, pow(vPosition.y, 4.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);

float density = 0.2;
float aoForDensity = mix(1.0, 0.25, density);
float ao = mix(aoForDensity, 1.0, pow(vPosition.y, 2.0));

gl_FragColor = vec4(finalColor * ndl * ao, 1.0);// apply color and lighting
}
87 changes: 87 additions & 0 deletions src/shaders/grassMaterial/grassVertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
precision highp float;

attribute vec3 position;
attribute vec3 normal;

uniform mat4 view;
uniform mat4 projection;

uniform vec3 cameraPosition;
uniform vec3 playerPosition;

uniform float time;

uniform sampler2D perlinNoise;

varying vec3 vPosition;

varying mat4 normalMatrix;
varying vec3 vNormal;

#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>

// wind
vec3 objectWorld = world3.xyz;
float windStrength = texture2D(perlinNoise, objectWorld.xz * 0.007 + 0.1 * time).r;
float windDir = texture2D(perlinNoise, objectWorld.xz * 0.005 + 0.05 * time).r * 2.0 * 3.14;

float windLeanAngle = remap(windStrength, 0.0, 1.0, 0.25, 1.0);
windLeanAngle = easeIn(windLeanAngle, 2.0) * 0.75;

// curved grass blade
float leanAmount = 0.3;
float curveAmount = leanAmount * position.y;
float objectDistance = length(objectWorld - playerPosition);

// account for player presence
vec3 playerDirection = (objectWorld - playerPosition) / objectDistance;
float maxDistance = 3.0;
float distance01 = objectDistance / maxDistance;
float influence = 1.0 + 8.0 * smoothstep(0.0, 1.0, 1.0 - distance01);
curveAmount *= influence;
curveAmount += windLeanAngle * smoothstep(0.2, 1.0, distance01);

vec3 leanAxis = rotateAround(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), windDir * smoothstep(0.2, 1.0, distance01));
leanAxis = normalize(mix(cross(vec3(0.0, 1.0, 0.0), playerDirection), leanAxis, smoothstep(0.0, 1.0, 1.0 - distance01)));


vec3 leaningPosition = rotateAround(position, leanAxis, curveAmount);

vec3 leaningNormal = rotateAround(normal, leanAxis, curveAmount);

vec4 worldPosition = finalWorld * vec4(leaningPosition, 1.0);


//vec3 viewDir = normalize(cameraPosition - worldPosition);
//float viewDotNormal = abs(dot(viewDir, leaningNormal));
//float viewSpaceThickenFactor = easeOut(1.0 - viewDotNormal, 4.0);

//viewSpaceThickenFactor *= smoothstep(0.0, 0.2, viewDotNormal);

vec4 viewPosition = view * worldPosition;
//viewPosition.x += viewSpaceThickenFactor * leaningNormal.y;

vec4 outPosition = projection * viewPosition;
gl_Position = outPosition;

vPosition = position;

normalMatrix = transpose(inverse(finalWorld));

vNormal = leaningNormal;
}
18 changes: 11 additions & 7 deletions src/shaders/telluricPlanetMaterial/fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void main() {
vec2 uv = toUV(vUnitSamplePoint);
// trick from https://www.shadertoy.com/view/3dVSzm to avoid Greenwich artifacts
vec2 df = fwidth(uv);
if(df.x > 0.5) df.x = 0.0;
if (df.x > 0.5) df.x = 0.0;
vec4 lutResult = textureLod(lut, uv, log2(max(df.x, df.y) * 1024.0));

// moisture
Expand Down Expand Up @@ -169,15 +169,11 @@ void main() {
);
beachFactor = smoothSharpener(beachFactor, 2.0);

float steepFactor = slope;//smoothSharpener(slope, steepSharpness);
steepFactor = smoothstep(0.3, 0.7, steepFactor);
steepFactor = smoothSharpener(steepFactor, steepSharpness);

plainFactor = 1.0 - steepFactor;
plainFactor = 1.0;//- steepFactor;

// apply beach factor
plainFactor *= 1.0 - beachFactor;
beachFactor *= 1.0 - steepFactor;
//beachFactor *= 1.0 - steepFactor;

// blend with desert factor when above water
desertFactor = smoothstep(0.5, 0.3, moisture01);
Expand All @@ -192,6 +188,14 @@ void main() {
beachFactor *= 1.0 - snowFactor;
desertFactor *= 1.0 - snowFactor;

float steepFactor = slope;
steepFactor = smoothstep(0.05, 0.3, steepFactor);
steepFactor = smoothSharpener(steepFactor, steepSharpness);
snowFactor *= 1.0 - steepFactor;
plainFactor *= 1.0 - steepFactor;
beachFactor *= 1.0 - steepFactor;
desertFactor *= 1.0 - steepFactor;

// blend with bottom factor when under water
bottomFactor = smoothstep(waterLevel01, waterLevel01 - 1e-2, elevation01);
bottomFactor = smoothSharpener(bottomFactor, 2.0);
Expand Down
43 changes: 35 additions & 8 deletions src/ts/assets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import "@babylonjs/loaders/glTF/2.0";
import "@babylonjs/loaders";
import "@babylonjs/core/Loading/Plugins/babylonFileLoader";
import "@babylonjs/core/Loading/loadingScreen";
import "@babylonjs/core/Animations/animatable";

Expand All @@ -19,13 +20,15 @@ import plumeParticle from "../asset/textures/plume.png";
import atmosphereLUT from "../shaders/textures/atmosphereLUT.glsl";

import spaceship from "../asset/spaceship/spaceship2.glb";
//import spacestation from "../asset/spacestation/spacestation.glb";
import shipCarrier from "../asset/spacestation/shipcarrier.glb";
import banana from "../asset/banana/banana.glb";
import endeavorSpaceship from "../asset/spaceship/endeavour.glb";
import character from "../asset/character.glb";
import rock from "../asset/rock.glb";

import tree from "../asset/tree/tree.babylon";
import treeTexturePath from "../asset/tree/Tree.png";

import ouchSound from "../asset/sound/ouch.mp3";
import engineRunningSound from "../asset/sound/engineRunning.mp3";

Expand Down Expand Up @@ -70,8 +73,9 @@ export class Assets {
private static Spacestation: Mesh;
private static Banana: Mesh;
private static Character: Mesh;
static Rock: Mesh;

public static Rock: Mesh;
public static Tree: Mesh;
public static ScatterCube: Mesh;

public static OuchSound: Sound;
Expand Down Expand Up @@ -164,16 +168,39 @@ export class Assets {

const rockTask = Assets.manager.addMeshTask("rockTask", "", "", rock);
rockTask.onSuccess = function (task: MeshAssetTask) {
Assets.Rock = task.loadedMeshes[0] as Mesh;
Assets.Rock = task.loadedMeshes[0].getChildMeshes()[0] as Mesh;
Assets.Rock.position.y = 0.1;
Assets.Rock.scaling.scaleInPlace(0.2);
Assets.Rock.bakeCurrentTransformIntoVertices();
Assets.Rock.isVisible = false;

for (const mesh of Assets.Rock.getChildMeshes()) {
mesh.isVisible = false;
}

console.log("Rock loaded");
};

const treeTask = Assets.manager.addMeshTask("treeTask", "", "", tree);
treeTask.onSuccess = function (task: MeshAssetTask) {
Assets.Tree = task.loadedMeshes[0] as Mesh;
Assets.Tree.position.y = -1;
Assets.Tree.scaling.scaleInPlace(3);
Assets.Tree.bakeCurrentTransformIntoVertices();
Assets.Tree.isVisible = false;

const treeMaterial = new StandardMaterial("treeMaterial", scene);

treeMaterial.opacityTexture = null;
treeMaterial.backFaceCulling = false;

const treeTexture = new Texture(treeTexturePath, scene);
treeTexture.hasAlpha = true;

treeMaterial.diffuseTexture = treeTexture;
treeMaterial.specularColor.set(0, 0, 0);

Assets.Tree.material = treeMaterial;

console.log("Tree loaded");
}

const ouchSoundTask = Assets.manager.addBinaryFileTask("ouchSoundTask", ouchSound);
ouchSoundTask.onSuccess = function (task) {
Assets.OuchSound = new Sound("OuchSound", task.data, scene);
Expand Down
Loading

0 comments on commit 1223d30

Please sign in to comment.