-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f3afd56
commit db53aee
Showing
7 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
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,4 @@ | ||
<ul> | ||
<li><a href="webgl/">WebGL</a></li> | ||
<li><a href="webgpu/">WebGPU</a></li> | ||
</ul> |
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,87 @@ | ||
<script> | ||
import { WebGlFragmentShader } from "$lib/index.js"; | ||
import shaderCode from "./shader.frag?raw"; | ||
import logo from "../logoDark.png"; | ||
</script> | ||
|
||
<!-- Import 'Kanit' font from Google Fonts --> | ||
<svelte:head> | ||
<link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" /> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,100;0,400;1,800&display=swap" | ||
rel="stylesheet" | ||
/> | ||
</svelte:head> | ||
|
||
<main> | ||
<div class="canvas-container"> | ||
<WebGlFragmentShader | ||
code={shaderCode} | ||
parameters={[ | ||
{ | ||
name: "u_resolution", | ||
data: "resolution", | ||
}, | ||
{ | ||
name: "u_offset", | ||
data: "offset", | ||
}, | ||
{ | ||
name: "u_scale", | ||
data: "scale", | ||
}, | ||
]} | ||
></WebGlFragmentShader> | ||
</div> | ||
|
||
<div class="text"> | ||
<img src={logo} alt="S" /> | ||
<h1>SVADER</h1> | ||
</div> | ||
</main> | ||
|
||
<style> | ||
main { | ||
position: relative; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
width: 1280px; | ||
height: 640px; | ||
} | ||
.canvas-container { | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
z-index: -1; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
.text { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
color: white; | ||
font-family: "Kanit"; | ||
} | ||
img { | ||
height: 200px; | ||
width: 200px; | ||
margin: -40px -50px; | ||
} | ||
h1 { | ||
margin: 0; | ||
font-size: 80px; | ||
font-style: italic; | ||
} | ||
</style> |
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,82 @@ | ||
#version 300 es | ||
|
||
precision mediump float; | ||
out vec4 fragColor; | ||
|
||
uniform vec2 u_resolution; | ||
uniform vec2 u_offset; | ||
uniform float u_scale; | ||
|
||
|
||
const float pi = 3.14159265359; | ||
|
||
|
||
// Pick a pseudo-random number for the given `pos`. | ||
float random(vec2 pos) { | ||
vec2 st = pos / u_resolution; | ||
return fract(sin(dot(st, vec2(12.9898, 78.233))) * 43758.5453); | ||
} | ||
|
||
|
||
// Create a 2-dimensional vector with a length of 1 and a pseudo-random angle. | ||
vec2 random_gradient(vec2 pos) { | ||
float angle = random(pos) * pi * 2.0; | ||
return vec2(cos(angle), sin(angle)); | ||
} | ||
|
||
|
||
// Interpolate the value of `x` between 0 and 1 by using a cubic function. | ||
// When drawn on a graph, this creates an S-shaped curve between 0 and 1. | ||
float cubic_s(float x) { | ||
return x * x * (3.0 - x * 2.0); | ||
} | ||
|
||
|
||
// Create Perline noise: https://en.wikipedia.org/wiki/Perlin_noise | ||
float perlin_noise(vec2 pos) { | ||
float cell_size = 100.0 * u_scale; | ||
|
||
vec2 grid_st = fract(pos / cell_size); | ||
vec2 grid_square_coord = floor(pos / cell_size); | ||
|
||
vec2 corner_bot_left = vec2(0.0, 0.0); | ||
vec2 corner_bot_right = vec2(1.0, 0.0); | ||
vec2 corner_top_left = vec2(0.0, 1.0); | ||
vec2 corner_top_right = vec2(1.0, 1.0); | ||
|
||
vec2 offset_bot_left = grid_st - corner_bot_left; | ||
vec2 offset_bot_right = grid_st - corner_bot_right; | ||
vec2 offset_top_left = grid_st - corner_top_left; | ||
vec2 offset_top_right = grid_st - corner_top_right; | ||
|
||
vec2 gradient_bot_left = random_gradient((grid_square_coord + corner_bot_left) * cell_size); | ||
vec2 gradient_bot_right = random_gradient((grid_square_coord + corner_bot_right) * cell_size); | ||
vec2 gradient_top_left = random_gradient((grid_square_coord + corner_top_left) * cell_size); | ||
vec2 gradient_top_right = random_gradient((grid_square_coord + corner_top_right) * cell_size); | ||
|
||
float dot_bot_left = dot(offset_bot_left, gradient_bot_left); | ||
float dot_bot_right = dot(offset_bot_right, gradient_bot_right); | ||
float dot_top_left = dot(offset_top_left, gradient_top_left); | ||
float dot_top_right = dot(offset_top_right, gradient_top_right); | ||
|
||
float x = cubic_s(grid_st.x); | ||
float y = cubic_s(grid_st.y); | ||
float bot = mix(dot_bot_left, dot_bot_right, x); | ||
float top = mix(dot_top_left, dot_top_right, x); | ||
return mix(bot, top, y); | ||
} | ||
|
||
|
||
void main() { | ||
vec2 pos = gl_FragCoord.xy + u_offset; | ||
|
||
// Mirror the y-axis to create the exact same image as the WebGPU version. | ||
pos.y = u_resolution.y - pos.y; | ||
|
||
// Multiply the noise with the vignette to create a darker spot towards the middle. | ||
float noise = perlin_noise(pos); | ||
float vignette = cubic_s(distance(pos / u_resolution, vec2(0.5, 0.5))); | ||
float r = step(0.4 - random(pos) * 0.4, vignette * noise) * 0.8; | ||
|
||
fragColor = vec4(vec3(r), 1.0); | ||
} |
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,93 @@ | ||
<script> | ||
import { WebGpuFragmentShader } from "$lib/index.js"; | ||
import shaderCode from "./shader.wgsl?raw"; | ||
import logo from "../logoDark.png"; | ||
</script> | ||
|
||
<!-- Import 'Kanit' font from Google Fonts --> | ||
<svelte:head> | ||
<link rel="preconnect" href="https://fonts.googleapis.com" /> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" /> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,100;0,400;1,800&display=swap" | ||
rel="stylesheet" | ||
/> | ||
</svelte:head> | ||
|
||
<main> | ||
<div class="canvas-container"> | ||
<WebGpuFragmentShader | ||
code={shaderCode} | ||
parameters={[ | ||
{ | ||
label: "Resolution", | ||
binding: 0, | ||
type: "uniform", | ||
data: "resolution", | ||
}, | ||
{ | ||
label: "Offset", | ||
binding: 1, | ||
type: "uniform", | ||
data: "offset", | ||
}, | ||
{ | ||
label: "Scale", | ||
binding: 2, | ||
type: "uniform", | ||
data: "scale", | ||
}, | ||
]} | ||
></WebGpuFragmentShader> | ||
</div> | ||
|
||
<div class="text"> | ||
<img src={logo} alt="S" /> | ||
<h1>SVADER</h1> | ||
</div> | ||
</main> | ||
|
||
<style> | ||
main { | ||
position: relative; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
width: 1280px; | ||
height: 640px; | ||
} | ||
.canvas-container { | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
z-index: -1; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
.text { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
color: white; | ||
font-family: "Kanit"; | ||
} | ||
img { | ||
height: 200px; | ||
width: 200px; | ||
margin: -40px -50px; | ||
} | ||
h1 { | ||
margin: 0; | ||
font-size: 80px; | ||
font-style: italic; | ||
} | ||
</style> |
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,75 @@ | ||
@group(0) @binding(0) var<uniform> resolution: vec2f; | ||
@group(0) @binding(1) var<uniform> offset: vec2f; | ||
@group(0) @binding(2) var<uniform> scale: f32; | ||
|
||
|
||
const pi = 3.14159265359; | ||
|
||
|
||
// Pick a pseudo-random number for the given `pos`. | ||
fn random(pos: vec2f) -> f32 { | ||
let st = pos / resolution; | ||
return fract(sin(dot(st, vec2f(12.9898, 78.233))) * 43758.5453); | ||
} | ||
|
||
|
||
// Create a 2-dimensional vector with a length of 1 and a pseudo-random angle. | ||
fn random_gradient(pos: vec2f) -> vec2f { | ||
let angle = random(pos) * pi * 2.0; | ||
return vec2f(cos(angle), sin(angle)); | ||
} | ||
|
||
|
||
// Interpolate the value of `x` between 0 and 1 by using a cubic function. | ||
// When drawn on a graph, this creates an S-shaped curve between 0 and 1. | ||
fn cubic_s(x: f32) -> f32 { | ||
return x * x * (3.0 - x * 2.0); | ||
} | ||
|
||
|
||
// Create Perline noise: https://en.wikipedia.org/wiki/Perlin_noise | ||
fn perlin_noise(pos: vec2f) -> f32 { | ||
let cell_size = 100.0 * scale; | ||
|
||
let grid_st = fract(pos / cell_size); | ||
let grid_square_coord = floor(pos / cell_size); | ||
|
||
let corner_bot_left = vec2f(0.0, 0.0); | ||
let corner_bot_right = vec2f(1.0, 0.0); | ||
let corner_top_left = vec2f(0.0, 1.0); | ||
let corner_top_right = vec2f(1.0, 1.0); | ||
|
||
let offset_bot_left = grid_st - corner_bot_left; | ||
let offset_bot_right = grid_st - corner_bot_right; | ||
let offset_top_left = grid_st - corner_top_left; | ||
let offset_top_right = grid_st - corner_top_right; | ||
|
||
let gradient_bot_left = random_gradient((grid_square_coord + corner_bot_left) * cell_size); | ||
let gradient_bot_right = random_gradient((grid_square_coord + corner_bot_right) * cell_size); | ||
let gradient_top_left = random_gradient((grid_square_coord + corner_top_left) * cell_size); | ||
let gradient_top_right = random_gradient((grid_square_coord + corner_top_right) * cell_size); | ||
|
||
let dot_bot_left = dot(offset_bot_left, gradient_bot_left); | ||
let dot_bot_right = dot(offset_bot_right, gradient_bot_right); | ||
let dot_top_left = dot(offset_top_left, gradient_top_left); | ||
let dot_top_right = dot(offset_top_right, gradient_top_right); | ||
|
||
let x = cubic_s(grid_st.x); | ||
let y = cubic_s(grid_st.y); | ||
let bot = mix(dot_bot_left, dot_bot_right, x); | ||
let top = mix(dot_top_left, dot_top_right, x); | ||
return mix(bot, top, y); | ||
} | ||
|
||
|
||
@fragment | ||
fn fragmentMain(@builtin(position) raw_pos: vec4f) -> @location(0) vec4f { | ||
let pos = raw_pos.xy + offset; | ||
|
||
// Multiply the noise with the vignette to create a darker spot towards the middle. | ||
let noise = perlin_noise(pos); | ||
let vignette = cubic_s(distance(pos / resolution, vec2f(0.5, 0.5))); | ||
let r = step(0.4 - random(pos) * 0.4, vignette * noise) * 0.8; | ||
|
||
return vec4(vec3(r), 1.0); | ||
} |