feat: some shit
This commit is contained in:
@ -1,7 +1,10 @@
|
||||
---
|
||||
title: "Argenti"
|
||||
date: 2023-08-21
|
||||
icon: "/projects/argenti.png"
|
||||
draft: true
|
||||
description: "A central database for things I enjoy stored in Markdown/Redis"
|
||||
tags: ["deno", "fresh", "redis"]
|
||||
links:
|
||||
[
|
||||
["live", "https://invoice.app.max-richter.dev"],
|
||||
|
@ -2,6 +2,8 @@
|
||||
title: "Invoice"
|
||||
date: 2023-08-21
|
||||
headerImg: "bg.jpg"
|
||||
icon: "/projects/invoice.svg"
|
||||
tags: ["sveltekit", "unocss", "prisma", "sqlite"]
|
||||
draft: true
|
||||
links:
|
||||
[
|
||||
|
10
src/content/projects/isyncrasy/index.mdx
Normal file
10
src/content/projects/isyncrasy/index.mdx
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
date: 2019-06-10
|
||||
title: "Isyncrasy"
|
||||
draft: false
|
||||
icon: "/projects/isyncrasy/favicon.ico"
|
||||
description: "A small fun virtual OS build with svelte"
|
||||
tags: ["svelte", "web", "os"]
|
||||
---
|
||||
|
||||
# Isyncrasy
|
23
src/content/projects/plantarium/_components/Leaf.frag
Normal file
23
src/content/projects/plantarium/_components/Leaf.frag
Normal file
@ -0,0 +1,23 @@
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
uniform vec3 uBackground;
|
||||
|
||||
varying vec3 vNormal;
|
||||
varying vec2 vUv;
|
||||
varying float fog;
|
||||
|
||||
void main(){
|
||||
|
||||
vec3 normal=normalize(vNormal);
|
||||
|
||||
float lighting=dot(normal,normalize(vec3(-.3,.8,.6)));
|
||||
|
||||
vec3 col = (vec3(.308*vUv.x,.712,.5)+lighting*.5)-.25;
|
||||
/* gl_FragColor.rgb=vec3(vUv.x,vUv.y,vNormal.x); */
|
||||
gl_FragColor.rgb=mix(col, uBackground,fog);
|
||||
|
||||
gl_FragColor.a=1.;
|
||||
|
||||
}
|
||||
|
49
src/content/projects/plantarium/_components/Leaf.vert
Normal file
49
src/content/projects/plantarium/_components/Leaf.vert
Normal file
@ -0,0 +1,49 @@
|
||||
attribute vec2 uv;
|
||||
attribute vec3 position;
|
||||
// Add instanced attributes just like any attribute
|
||||
attribute vec3 offset;
|
||||
attribute vec3 random;
|
||||
attribute vec3 normal;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 normalMatrix;
|
||||
|
||||
uniform float uTime;
|
||||
uniform float uRot;
|
||||
varying vec2 vUv;
|
||||
varying vec3 vNormal;
|
||||
varying float fog;
|
||||
|
||||
void rotate2d(inout vec2 v, float a){
|
||||
mat2 m = mat2(cos(a), -sin(a), sin(a), cos(a));
|
||||
v = m * v;
|
||||
}
|
||||
void main() {
|
||||
vUv = uv;
|
||||
|
||||
vNormal = normal;
|
||||
|
||||
/* vNormal = normalize(normalMatrix * normal); */
|
||||
|
||||
// copy position so that we can modify the instances
|
||||
vec3 pos = position;
|
||||
|
||||
// scale first
|
||||
fog = (offset.z+1.0)/2.0;
|
||||
pos *= 0.4 + (1.0-fog) * 0.6;
|
||||
|
||||
// rotate around y axis
|
||||
rotate2d(pos.xz, random.x * 6.28 + 1.0 * uTime * (random.y - 0.5));
|
||||
|
||||
rotate2d(pos.xy, random.y * 6.28 + 1.0 * uTime * (random.y - 0.5));
|
||||
// rotate around x axis just to add some extra variation
|
||||
rotate2d(pos.zy, random.z * 0.5 * sin(uTime * random.x + random.z * 3.14));
|
||||
|
||||
pos.y += sin(uRot/500.0+random.y*50.0)/5.0+(1.0-fog)*uRot;
|
||||
|
||||
pos += offset;
|
||||
|
||||
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
||||
}
|
44
src/content/projects/plantarium/_components/Leaves.svelte
Normal file
44
src/content/projects/plantarium/_components/Leaves.svelte
Normal file
@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { createLeaves, setRotation } from "./leaves";
|
||||
|
||||
let canvas: HTMLCanvasElement;
|
||||
|
||||
let loaded = false;
|
||||
|
||||
function handleScroll() {
|
||||
setRotation(window.scrollY / window.innerHeight);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
createLeaves({ canvas, num: 20, minZ: 0, maxZ: 1 });
|
||||
setTimeout(() => {
|
||||
loaded = true;
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:window on:scroll={handleScroll} />
|
||||
|
||||
<canvas bind:this={canvas} class:loaded />
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
z-index: 1;
|
||||
}
|
||||
canvas {
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 2s;
|
||||
}
|
||||
|
||||
.loaded {
|
||||
opacity: 0.2;
|
||||
}
|
||||
</style>
|
5
src/content/projects/plantarium/_components/leave.json
Normal file
5
src/content/projects/plantarium/_components/leave.json
Normal file
File diff suppressed because one or more lines are too long
88
src/content/projects/plantarium/_components/leaves.ts
Normal file
88
src/content/projects/plantarium/_components/leaves.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import { Camera, Color, Geometry, GLTFLoader, Mesh, Program, Renderer, Transform } from 'ogl';
|
||||
import { rand, randMinMax } from "./random";
|
||||
|
||||
import fragment from "./Leaf.frag";
|
||||
import vertex from "./Leaf.vert";
|
||||
import { rgbToHex } from '@helpers/colors';
|
||||
|
||||
let rotation = 0;
|
||||
|
||||
export function setRotation(r: number) {
|
||||
rotation = r;
|
||||
}
|
||||
|
||||
export function createLeaves({ canvas, num = 20, alpha = false, minZ = -1, maxZ = 1 }: { canvas: HTMLCanvasElement, num?: number, alpha?: boolean, minZ?: number, maxZ?: number }) {
|
||||
|
||||
|
||||
const renderer = new Renderer({ dpr: 1, canvas, alpha: true });
|
||||
const gl = renderer.gl;
|
||||
|
||||
const background = window.getComputedStyle(document.body);
|
||||
const d = new Color(rgbToHex(background.backgroundColor));
|
||||
|
||||
const camera = new Camera(gl, { fov: 15 });
|
||||
camera.position.z = 5;
|
||||
|
||||
function resize() {
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
camera.perspective({ aspect: gl.canvas.width / gl.canvas.height });
|
||||
}
|
||||
window.addEventListener('resize', resize, false);
|
||||
resize();
|
||||
|
||||
const scene = new Transform();
|
||||
|
||||
const program = new Program(gl, {
|
||||
vertex,
|
||||
fragment,
|
||||
cullFace: gl.NONE,
|
||||
depthTest: true,
|
||||
uniforms: {
|
||||
uTime: { value: 0 },
|
||||
uRot: { value: 0 },
|
||||
uBackground: { value: d },
|
||||
},
|
||||
});
|
||||
|
||||
let mesh: Mesh;
|
||||
loadModel();
|
||||
async function loadModel() {
|
||||
|
||||
const model = await GLTFLoader.load(gl, "/models/leaf.glb");
|
||||
|
||||
const data = model.nodes[0].children[0].geometry.attributes;
|
||||
|
||||
let offset = new Float32Array(num * 3);
|
||||
let random = new Float32Array(num * 3);
|
||||
for (let i = 0; i < num; i++) {
|
||||
offset.set([rand(8), rand(4), randMinMax(minZ, maxZ)], i * 3);
|
||||
|
||||
// unique random values are always handy for instances.
|
||||
// Here they will be used for rotation, scale and movement.
|
||||
random.set([Math.random(), Math.random(), Math.random()], i * 3);
|
||||
}
|
||||
|
||||
const geometry = new Geometry(gl, {
|
||||
...data,
|
||||
|
||||
// simply add the 'instanced' property to flag as an instanced attribute.
|
||||
// set the value as the divisor number
|
||||
offset: { instanced: 1, size: 3, data: offset },
|
||||
random: { instanced: 1, size: 3, data: random },
|
||||
});
|
||||
|
||||
mesh = new Mesh(gl, { geometry, program });
|
||||
mesh.scale.set(0.2, 0.2, 0.2)
|
||||
mesh.setParent(scene);
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
function update(t: number) {
|
||||
requestAnimationFrame(update);
|
||||
|
||||
program.uniforms.uTime.value = t * 0.001;
|
||||
program.uniforms.uRot.value = rotation;
|
||||
renderer.render({ scene, camera });
|
||||
}
|
||||
|
||||
}
|
3
src/content/projects/plantarium/_components/random.ts
Normal file
3
src/content/projects/plantarium/_components/random.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const rand = (r = 1) => (Math.random() * 2 - 1) * r;
|
||||
|
||||
export const randMinMax = (min = 0, max = 1) => min + Math.random() * (max - min)
|
BIN
src/content/projects/plantarium/images/plantarium.png
(Stored with Git LFS)
Normal file
BIN
src/content/projects/plantarium/images/plantarium.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Plantarium"
|
||||
date: 2022-08-31
|
||||
headerImg: "/projects/plantarium/plantarium.png"
|
||||
headerImg: "images/plantarium.png"
|
||||
featured: true
|
||||
links: [["website", "https://plant.max-richter.com"], ["git", "https://github.com/jim-fx/plantarium"]]
|
||||
draft: true
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Plantarium"
|
||||
date: 2022-08-31T20:46:26+02:00
|
||||
headerImg: "/projects/plantarium/plantarium.png"
|
||||
headerImg: "images/plantarium.png"
|
||||
featured: true
|
||||
links: [["website", "https://plant.max-richter.dev"], ["git", "https://github.com/jim-fx/plantarium"]]
|
||||
tags: ["Web", "3D", "Svelte", "Node-Systeme"]
|
||||
@ -14,14 +14,31 @@ Plantarium ist wohl das Hobby Projekt, mit dem ich am meisten Zeit verbracht hab
|
||||
|
||||
Plantarium ist eine WebApp mit der Nutzer 3D Model von Pflanzen generieren können. Der erste Prototyp war innerhalb von zwei Wochen intensiver Arbeit fertig und sah ungefähr so aus:
|
||||
|
||||
<svelte component="image-slider" title="Prototype Design">
|
||||
<img src="./images/page01-0.jpg" alt="Stem Page"/>
|
||||
<img src="./images/page01-1.jpg" alt="Branches page"/>
|
||||
<img src="./images/page01-2.jpg" alt="Leaves page"/>
|
||||
<img src="./images/page01-3.jpg" alt="Import/Export page"/>
|
||||
<img src="./images/page01-5.jpg" alt="Design of UI Components"/>
|
||||
<img src="./images/page01-6.jpg" alt="Data flow inside app"/>
|
||||
</svelte>
|
||||
import ImageSlider from "@components/ImageSlider.svelte"
|
||||
import Leaves from "./_components/Leaves.svelte"
|
||||
import Image from "@components/Image.astro"
|
||||
import page01_0 from "./images/page01-0.jpg"
|
||||
import page01_1 from "./images/page01-1.jpg"
|
||||
import page01_2 from "./images/page01-2.jpg"
|
||||
import page01_3 from "./images/page01-3.jpg"
|
||||
import page01_5 from "./images/page01-5.jpg"
|
||||
import page01_6 from "./images/page01-6.jpg"
|
||||
import screenshot_geometry_nodes from "./images/screenshot-geometry-nodes.jpg"
|
||||
import screenshot_houdini from "./images/screenshot-houdini.jpg"
|
||||
import screenshot_unreal from "./images/screenshot-unreal.jpg"
|
||||
import screenshot_davinci from "./images/screenshot-davinci.jpg"
|
||||
|
||||
<Leaves client:load/>
|
||||
|
||||
<ImageSlider title="Erster Prototyp" client:load>
|
||||
<Image src={page01_0} alt="Stem Page"/>
|
||||
<Image src={page01_1} alt="Branches page"/>
|
||||
<Image src={page01_2} alt="Leaves page"/>
|
||||
<Image src={page01_3} alt="Import/Export page"/>
|
||||
<Image src={page01_5} alt="Design of UI Components"/>
|
||||
<Image src={page01_6} alt="Data flow inside app"/>
|
||||
</ImageSlider>
|
||||
|
||||
|
||||
Schon gar nicht schlecht, aber wie das mit Prototypen so ist gab es noch einiges zu verbessern. Also eine Kurze Historie der größten Änderungen bis heute:
|
||||
|
||||
@ -56,13 +73,13 @@ In der Beispielgrafik haben wir zwei `input-color` nodes die jeweils eine Farbe
|
||||
Das coole ist das man dieses System sehr generisch gestalten kann und zum beispiel eine `generate-stem`, `generate-branches` oder eine `add-leaves` node programmieren kann. Aufgrund der
|
||||
|
||||
<img src="/projects/plantarium/screenshot-plantarium.png" alt="Plantariums uses nodes to create plants"/>
|
||||
|
||||
<svelte component="image-slider" title="Beispiele von Node Systemen">
|
||||
<img src="images/screenshot-geometry-nodes.jpg" alt="Blenders uses nodes to create geometry"/>
|
||||
<img src="images/screenshot-houdini.jpg" alt="Houdini uses nodes for vfx/simulations"/>
|
||||
<img src="images/screenshot-unreal.jpg" alt="Unreal uses nodes for game logic"/>
|
||||
<img src="images/screenshot-davinci.jpg" alt="Davinvi uses nodes for vfx"/>
|
||||
</svelte>
|
||||
|
||||
<ImageSlider title="Beispiele von Node Systemen" client:load>
|
||||
<Image src={screenshot_geometry_nodes} alt="Blenders uses nodes to create geometry"/>
|
||||
<Image src={screenshot_houdini} alt="Houdini uses nodes for vfx/simulations"/>
|
||||
<Image src={screenshot_unreal} alt="Unreal uses nodes for game logic"/>
|
||||
<Image src={screenshot_davinci} alt="Davinvi uses nodes for vfx"/>
|
||||
</ImageSlider>
|
||||
|
||||
### Svelte-Kit Rewrite
|
||||
|
||||
|
Reference in New Issue
Block a user