mirror of
https://github.com/danbee/danbarber.me.hugo.git
synced 2025-03-04 08:59:18 +00:00
Add Plasmatron post
This commit is contained in:
parent
25b110032e
commit
074b53ae8d
88
content/blog/2020-06-25-plasmatron/index.md
Normal file
88
content/blog/2020-06-25-plasmatron/index.md
Normal file
@ -0,0 +1,88 @@
|
||||
---
|
||||
title: Plasmatron Shader
|
||||
layout: post
|
||||
categories:
|
||||
- shaders
|
||||
- webgl
|
||||
- demoscene
|
||||
- effects
|
||||
date: '2020-06-25'
|
||||
image: plasmatron.jpg
|
||||
---
|
||||
|
||||
I've been interested in computer graphics for as long as I can remember. The
|
||||
reason I started programming at all was because I wanted to make things happen
|
||||
on the screen.
|
||||
|
||||
Recently I've been playing around with fragment shaders. Fragment shaders are
|
||||
tiny programs that run on the GPU and compute the colour of individual pixels
|
||||
(fragments). They do this incredibly quickly because the GPU has a large number
|
||||
of simple processing cores, often numbering in the hundreds or thousands, to
|
||||
enable massive parallelisation.
|
||||
|
||||
<!--more-->
|
||||
|
||||
Shaders are written in a language called GLSL, or OpenGL Shader Language. It's
|
||||
pretty similar to C. Here is a simple plasma shader I wrote a few years ago:
|
||||
|
||||
```glsl
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec2 u_mouse;
|
||||
uniform float u_time;
|
||||
|
||||
const float PI = 3.14159265;
|
||||
|
||||
void main() {
|
||||
float width = u_resolution.x;
|
||||
float height = u_resolution.y;
|
||||
|
||||
float scale = (width + height) / 2.0;
|
||||
|
||||
float time = u_time * 0.3;
|
||||
|
||||
// calculate the centre of the circular sines
|
||||
vec2 center = vec2((width / 2.0) + sin(time) * (width / 1.5),
|
||||
(height / 2.0) + cos(time) * (height / 1.5));
|
||||
|
||||
float distance = length(gl_FragCoord.xy - center);
|
||||
|
||||
// circular plasmas sines
|
||||
float circ = (sin(distance / (scale / 7.6) + sin(time * 1.1) * 5.0) + 1.25)
|
||||
+ (sin(distance / (scale / 11.5) - sin(time * 1.1) * 6.0) + 1.25);
|
||||
|
||||
// x and y plasma sines
|
||||
float xval = (sin(gl_FragCoord.x / (scale / 6.5) + sin(time * 1.1) * 4.5) + 1.25)
|
||||
+ (sin(gl_FragCoord.x / (scale / 9.2) - sin(time * 1.1) * 5.5) + 1.25);
|
||||
|
||||
float yval = (sin(gl_FragCoord.y / (scale / 6.8) + sin(time * 1.1) * 4.75) + 1.25)
|
||||
+ (sin(gl_FragCoord.y / (scale / 12.5) - sin(time * 1.1) * 5.75) + 1.25);
|
||||
|
||||
// add the values together for the pixel
|
||||
float tval = circ + xval + yval / 3.0;
|
||||
|
||||
// work out the colour
|
||||
vec3 color = vec3((cos(PI * tval / 4.0 + time * 3.0) + 1.0) / 2.0,
|
||||
(sin(PI * tval / 3.5 + time * 3.0) + 1.0) / 2.5,
|
||||
(sin(PI * tval / 2.0 + time * 3.0) + 2.0) / 8.0);
|
||||
|
||||
// set the fragment colour
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
```
|
||||
|
||||
WebGL makes it possible to embed shaders directly into web pages, so I can show
|
||||
you the result of the code above in realtime!
|
||||
|
||||
<figure>
|
||||
<canvas class="glslCanvas shader" data-fragment-url="plasmatron.frag" width="800" height="450"></canvas>
|
||||
</figure>
|
||||
|
||||
If you want to see the kind of things that are possible with fragment shaders,
|
||||
you should check out [Shadertoy](https://www.shadertoy.com/). There are some
|
||||
incredibly impressive creations on there!
|
||||
|
||||
<script type="text/javascript" src="/js/glsl-canvas.js"></script>
|
||||
49
content/blog/2020-06-25-plasmatron/plasmatron.frag
Normal file
49
content/blog/2020-06-25-plasmatron/plasmatron.frag
Normal file
@ -0,0 +1,49 @@
|
||||
// Author: Daniel Barber
|
||||
// Title: Plasmatron
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec2 u_mouse;
|
||||
uniform float u_time;
|
||||
|
||||
const float PI = 3.14159265;
|
||||
|
||||
void main() {
|
||||
float width = u_resolution.x;
|
||||
float height = u_resolution.y;
|
||||
|
||||
float scale = (width + height) / 2.0;
|
||||
|
||||
float time = u_time * 0.3;
|
||||
|
||||
// calculate the centre of the circular sines
|
||||
vec2 center = vec2((width / 2.0) + sin(time) * (width / 1.5),
|
||||
(height / 2.0) + cos(time) * (height / 1.5));
|
||||
|
||||
float distance = length(gl_FragCoord.xy - center);
|
||||
|
||||
// circular plasmas sines
|
||||
float circ = (sin(distance / (scale / 7.6) + sin(time * 1.1) * 5.0) + 1.25)
|
||||
+ (sin(distance / (scale / 11.5) - sin(time * 1.1) * 6.0) + 1.25);
|
||||
|
||||
// x and y plasma sines
|
||||
float xval = (sin(gl_FragCoord.x / (scale / 6.5) + sin(time * 1.1) * 4.5) + 1.25)
|
||||
+ (sin(gl_FragCoord.x / (scale / 9.2) - sin(time * 1.1) * 5.5) + 1.25);
|
||||
|
||||
float yval = (sin(gl_FragCoord.y / (scale / 6.8) + sin(time * 1.1) * 4.75) + 1.25)
|
||||
+ (sin(gl_FragCoord.y / (scale / 12.5) - sin(time * 1.1) * 5.75) + 1.25);
|
||||
|
||||
// add the values together for the pixel
|
||||
float tval = circ + xval + yval / 3.0;
|
||||
|
||||
// work out the colour
|
||||
vec3 color = vec3((cos(PI * tval / 4.0 + time * 3.0) + 1.0) / 2.0,
|
||||
(sin(PI * tval / 3.5 + time * 3.0) + 1.0) / 2.5,
|
||||
(sin(PI * tval / 2.0 + time * 3.0) + 2.0) / 8.0);
|
||||
|
||||
// set the fragment colour
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
BIN
content/blog/2020-06-25-plasmatron/plasmatron.jpg
Normal file
BIN
content/blog/2020-06-25-plasmatron/plasmatron.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Loading…
Reference in New Issue
Block a user