A Pen by Dilum Sanjaya on CodePen.
Created
October 12, 2024 07:40
-
-
Save JoshOohAhhAi/1eb4eef5e86cd9ff9ea233aece44b913 to your computer and use it in GitHub Desktop.
Unity π
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
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/postprocessing/EffectComposer.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/postprocessing/RenderPass.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/postprocessing/ShaderPass.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/shaders/CopyShader.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/shaders/LuminosityHighPassShader.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/postprocessing/UnrealBloomPass.js"></script> | |
<script type="x-shader/x-vertex" id="vertex-shader"> | |
uniform float time; | |
attribute vec3 customColor; | |
varying vec3 vColor; | |
// Simplex 4D Noise | |
// by Ian McEwan, Ashima Arts | |
// | |
vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} | |
float permute(float x){return floor(mod(((x*34.0)+1.0)*x, 289.0));} | |
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} | |
float taylorInvSqrt(float r){return 1.79284291400159 - 0.85373472095314 * r;} | |
vec4 grad4(float j, vec4 ip){ | |
const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); | |
vec4 p,s; | |
p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; | |
p.w = 1.5 - dot(abs(p.xyz), ones.xyz); | |
s = vec4(lessThan(p, vec4(0.0))); | |
p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; | |
return p; | |
} | |
float snoise(vec4 v){ | |
const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 | |
0.309016994374947451); // (sqrt(5) - 1)/4 F4 | |
// First corner | |
vec4 i = floor(v + dot(v, C.yyyy) ); | |
vec4 x0 = v - i + dot(i, C.xxxx); | |
// Other corners | |
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) | |
vec4 i0; | |
vec3 isX = step( x0.yzw, x0.xxx ); | |
vec3 isYZ = step( x0.zww, x0.yyz ); | |
// i0.x = dot( isX, vec3( 1.0 ) ); | |
i0.x = isX.x + isX.y + isX.z; | |
i0.yzw = 1.0 - isX; | |
// i0.y += dot( isYZ.xy, vec2( 1.0 ) ); | |
i0.y += isYZ.x + isYZ.y; | |
i0.zw += 1.0 - isYZ.xy; | |
i0.z += isYZ.z; | |
i0.w += 1.0 - isYZ.z; | |
// i0 now contains the unique values 0,1,2,3 in each channel | |
vec4 i3 = clamp( i0, 0.0, 1.0 ); | |
vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); | |
vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); | |
// x0 = x0 - 0.0 + 0.0 * C | |
vec4 x1 = x0 - i1 + 1.0 * C.xxxx; | |
vec4 x2 = x0 - i2 + 2.0 * C.xxxx; | |
vec4 x3 = x0 - i3 + 3.0 * C.xxxx; | |
vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx; | |
// Permutations | |
i = mod(i, 289.0); | |
float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); | |
vec4 j1 = permute( permute( permute( permute ( | |
i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) | |
+ i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) | |
+ i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) | |
+ i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); | |
// Gradients | |
// ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.) | |
// 7*7*6 = 294, which is close to the ring size 17*17 = 289. | |
vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; | |
vec4 p0 = grad4(j0, ip); | |
vec4 p1 = grad4(j1.x, ip); | |
vec4 p2 = grad4(j1.y, ip); | |
vec4 p3 = grad4(j1.z, ip); | |
vec4 p4 = grad4(j1.w, ip); | |
// Normalise gradients | |
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; | |
p4 *= taylorInvSqrt(dot(p4,p4)); | |
// Mix contributions from the five corners | |
vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); | |
vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); | |
m0 = m0 * m0; | |
m1 = m1 * m1; | |
return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) | |
+ dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; | |
} | |
void main() { | |
vColor = customColor; | |
vec3 p = position; | |
float r = snoise(vec4(p*0.015, time*0.0005)); | |
p.y += p.y*r*0.1; | |
p.x += p.x*r*0.1; | |
p.z += p.z*r*0.1; | |
vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 ); | |
gl_PointSize = 10. * (100.0/-mvPosition.z); | |
gl_Position = projectionMatrix * mvPosition; | |
} | |
</script> | |
<script type="x-shader/x-fragment" id="fragment-shader"> | |
varying vec3 vColor; | |
void main() { | |
gl_FragColor = vec4(vColor, 0.1); | |
} | |
</script> |
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
const params = { | |
exposure: 1, | |
bloomStrength: 0.87, | |
bloomThreshold: 0, | |
bloomRadius: 0.26 | |
}; | |
const { min, PI, sqrt, cos, sin, pow, floor } = Math; | |
const range = (n) => | |
Array(n) | |
.fill(0) | |
.map((i, j) => i + j); | |
const sum = (arr) => arr.reduce((acc, cur) => acc + cur, 0); | |
const slicedSum = (arr, i) => sum(arr.slice(0, i)); | |
const pointsOnSphere = (n) => { | |
const pts = []; | |
const inc = PI * (3 - sqrt(5)); | |
const off = 2 / n; | |
range(n).forEach((i) => { | |
const y = i * off - 1 + off / 2; | |
const r = sqrt(1 - y * y); | |
const phi = i * inc; | |
const x = cos(phi) * r; | |
const z = sin(phi) * r; | |
pts.push([x, y, z]); | |
}); | |
return pts; | |
}; | |
const numMap = (value, sMin, sMax, dMin, dMax) => { | |
return dMin + ((value - sMin) / (sMax - sMin)) * (dMax - dMin); | |
}; | |
const colArray = [0xed2225, 0xf99621, 0xf1eb1b, 0x0c9b49, 0x3954a5, 0x93298e]; | |
colArray.reverse(); | |
let camera, controls, scene, renderer, cloud, composer, bloomPass, meshPlanet; | |
const uniforms = { | |
time: { type: "f", value: 1.0 } | |
}; | |
let { innerWidth, innerHeight } = window; | |
let canvasSize = min(innerWidth, innerHeight); | |
init(); | |
animate(); | |
function init() { | |
scene = new THREE.Scene(); | |
renderer = new THREE.WebGLRenderer({ antialias: true }); | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.setSize(canvasSize, canvasSize); | |
document.body.appendChild(renderer.domElement); | |
camera = new THREE.PerspectiveCamera(60, 1, 1, 1000); | |
camera.position.set(128, 90, 474); | |
controls = new THREE.OrbitControls(camera, renderer.domElement); | |
const ambientLight = new THREE.AmbientLight(0x666666); | |
scene.add(ambientLight); | |
const renderScene = new THREE.RenderPass(scene, camera); | |
bloomPass = new THREE.UnrealBloomPass( | |
new THREE.Vector2(window.innerWidth, window.innerHeight), | |
1.5, | |
0.4, | |
0.85 | |
); | |
bloomPass.threshold = params.bloomThreshold; | |
bloomPass.strength = params.bloomStrength; | |
bloomPass.radius = params.bloomRadius; | |
composer = new THREE.EffectComposer(renderer); | |
composer.addPass(renderScene); | |
composer.addPass(bloomPass); | |
createObjects(); | |
createGlobe(); | |
window.addEventListener("resize", onWindowResize, false); | |
} | |
function onWindowResize() { | |
camera.aspect = 1; | |
camera.updateProjectionMatrix(); | |
innerWidth = window.innerWidth; | |
innerHeight = window.innerHeight; | |
canvasSize = min(innerWidth, innerHeight); | |
composer.setSize(canvasSize, canvasSize); | |
} | |
function animate(time) { | |
uniforms.time.value = time; | |
meshPlanet.rotation.y -= 0.006; | |
requestAnimationFrame(animate); | |
render(); | |
} | |
function render() { | |
composer.render(); | |
} | |
function createObjects() { | |
const layers = range(6).map((i) => canvasSize * pow(2, i + 1)); | |
layers.reverse(); | |
const amount = sum(layers); | |
const positions = new Float32Array(amount * 3); | |
const colors = new Float32Array(amount * 3); | |
const vertex = new THREE.Vector3(); | |
layers.forEach((layer, layerIndex) => { | |
const points = pointsOnSphere(layer); | |
points.forEach(([x, y, z], pointIndex) => { | |
const index = slicedSum(layers, layerIndex) + pointIndex; | |
const color = new THREE.Color( | |
colArray[floor(numMap(pointIndex, 0, layer, 0, colArray.length))] | |
); | |
const radius = 140 + numMap(layerIndex, 0, layers.length, 0, 120); | |
vertex.x = radius * x; | |
vertex.y = radius * y; | |
vertex.z = radius * z; | |
vertex.toArray(positions, index * 3); | |
color.toArray(colors, index * 3); | |
}); | |
}); | |
const geometry = new THREE.BufferGeometry(); | |
geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3)); | |
geometry.setAttribute("customColor", new THREE.BufferAttribute(colors, 3)); | |
const material = new THREE.ShaderMaterial({ | |
uniforms, | |
vertexShader: document.querySelector("#vertex-shader").textContent, | |
fragmentShader: document.querySelector("#fragment-shader").textContent, | |
blending: THREE.AdditiveBlending, | |
depthTest: false, | |
transparent: true | |
}); | |
cloud = new THREE.Points(geometry, material); | |
scene.add(cloud); | |
} | |
function createGlobe() { | |
const textureLoader = new THREE.TextureLoader(); | |
const radius = 100; | |
const tilt = 0.409105177; | |
const materialNormalMap = new THREE.MeshPhongMaterial({ | |
specular: 0x333333, | |
shininess: 1, | |
map: textureLoader.load("https://assets.codepen.io/3685267/earth.jpg"), | |
normalScale: new THREE.Vector2(0.85, -0.85) | |
}); | |
const geometry = new THREE.SphereBufferGeometry(radius, 100, 50); | |
meshPlanet = new THREE.Mesh(geometry, materialNormalMap); | |
meshPlanet.rotation.y = 0; | |
meshPlanet.rotation.z = tilt; | |
scene.add(meshPlanet); | |
} |
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
body { | |
margin: 0; | |
padding: 0; | |
height: 100vh; | |
overflow: hidden; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
background: #000; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment