mirror of
https://github.com/dyuri/repa-shader.git
synced 2025-12-16 11:14:25 +00:00
backbuffer
This commit is contained in:
parent
68e54df51b
commit
b0d7efe523
@ -23,18 +23,19 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<repa-shader fs-input="fsinput" alpha mouse snippets="noise.glsl" width=512 height=512>
|
<repa-shader fs-input="fsinput" alpha mouse snippets="noise.glsl" width=512 height=512>
|
||||||
<script type="x-shader/x-fragmen">
|
<script type="x-shader/x-fragment">
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = gl_FragCoord.xy / resolution.xy;
|
vec2 uv = gl_FragCoord.xy / resolution.xy;
|
||||||
vec3 col = .5 + .5 * cos(uv.xyx + time + vec3(0, 2, 4));
|
vec3 col = .5 + .5 * cos(uv.xyx + time + vec3(0, 2, 4));
|
||||||
|
|
||||||
float dist = distance(uv, mouse);
|
float dist = distance(uv, mouse);
|
||||||
float circle = smoothstep(.1, .2, dist) * .5 + .5;
|
float circle = smoothstep(.15, .2, dist);
|
||||||
vec4 acolor = vec4(col * circle, circle);
|
vec4 acolor = vec4(col * (1. - circle), (1. - circle)) + circle * texture(backbuffer, uv - vec2(.01, .01)) * .9;
|
||||||
outColor = vec4(acolor);
|
outColor = vec4(acolor);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script type="x-shader/x-fragment">
|
<script type="x-shader/x-fragmen">
|
||||||
|
// https://twigl.app/?ol=true&ss=-NOAlYulOVLklxMdxBDx
|
||||||
void main() {
|
void main() {
|
||||||
vec2 n,N,q,p=FC.xy/r.y;
|
vec2 n,N,q,p=FC.xy/r.y;
|
||||||
float S=9.,a,j;
|
float S=9.,a,j;
|
||||||
@ -49,22 +50,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
o+=pow(max(o-o,(a+.5)*.1*vec4(6,1,2,0)+.003/length(N)),o-o+.45);
|
o+=pow(max(o-o,(a+.5)*.1*vec4(6,1,2,0)+.003/length(N)),o-o+.45);
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
<script type="x-shader/x-fragmen">
|
|
||||||
precision highp float;
|
|
||||||
uniform vec2 resolution;
|
|
||||||
uniform vec2 mouse;
|
|
||||||
uniform float time;
|
|
||||||
out vec4 outColor;
|
|
||||||
void main() {
|
|
||||||
vec2 uv = gl_FragCoord.xy / resolution.xy;
|
|
||||||
vec3 col = .5 + .5 * cos(uv.xyx + time + vec3(0, 2, 4));
|
|
||||||
|
|
||||||
float dist = distance(uv, mouse);
|
|
||||||
float circle = smoothstep(.1, .2, dist) * .5 + .5;
|
|
||||||
vec4 acolor = vec4(col * circle, circle);
|
|
||||||
outColor = vec4(acolor);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</repa-shader>
|
</repa-shader>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -15,14 +15,16 @@ const CHUNKS = {
|
|||||||
#define m mouse
|
#define m mouse
|
||||||
#define t time
|
#define t time
|
||||||
#define f frame
|
#define f frame
|
||||||
|
#define b backbuffer
|
||||||
#define o outColor
|
#define o outColor
|
||||||
precision highp float;
|
precision highp float;
|
||||||
uniform vec2 resolution;
|
uniform vec2 resolution;
|
||||||
uniform vec2 mouse;
|
uniform vec2 mouse;
|
||||||
uniform float time;
|
uniform float time;
|
||||||
uniform float frame;
|
uniform float frame;
|
||||||
|
uniform sampler2D backbuffer;
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
`, // TODO sampler2D, MRT
|
`, // TODO MRT
|
||||||
geekestStart: `
|
geekestStart: `
|
||||||
void main() {
|
void main() {
|
||||||
`,
|
`,
|
||||||
@ -74,6 +76,17 @@ class RepaShader extends HTMLElement {
|
|||||||
|
|
||||||
// TODO resize
|
// TODO resize
|
||||||
|
|
||||||
|
// postprocessing
|
||||||
|
this._postProgram = this._gl.createProgram();
|
||||||
|
const pvs = this._createShader(this._postProgram, this.postVS, true);
|
||||||
|
const pfs = this._createShader(this._postProgram, this.postFS);
|
||||||
|
this._gl.linkProgram(this._postProgram);
|
||||||
|
this._gl.deleteShader(pvs);
|
||||||
|
this._gl.deleteShader(pfs);
|
||||||
|
this._postUniLocation = {};
|
||||||
|
this._postUniLocation.texture = this._gl.getUniformLocation(this._postProgram, 'drawTexture');
|
||||||
|
this._postAttLocation = this._gl.getAttribLocation(this._postProgram, 'position');
|
||||||
|
|
||||||
this._gl.bindBuffer(this._gl.ARRAY_BUFFER, this._gl.createBuffer());
|
this._gl.bindBuffer(this._gl.ARRAY_BUFFER, this._gl.createBuffer());
|
||||||
this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array([-1,1,0,-1,-1,0,1,1,0,1,-1,0]), this._gl.STATIC_DRAW);
|
this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array([-1,1,0,-1,-1,0,1,1,0,1,-1,0]), this._gl.STATIC_DRAW);
|
||||||
this._gl.disable(this._gl.DEPTH_TEST);
|
this._gl.disable(this._gl.DEPTH_TEST);
|
||||||
@ -154,8 +167,74 @@ class RepaShader extends HTMLElement {
|
|||||||
this._mousePosition = [x / this._target.width, 1 - y / this._target.height];
|
this._mousePosition = [x / this._target.width, 1 - y / this._target.height];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_resetBuffer(buff) {
|
||||||
|
if (!this._gl || !buff) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// framebuffer
|
||||||
|
if (buff.framebuffer && this._gl.isFramebuffer(buff.framebuffer)) {
|
||||||
|
this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, null);
|
||||||
|
this._gl.deleteFramebuffer(buff.framebuffer);
|
||||||
|
buff.framebuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderbuffer
|
||||||
|
if (buff.renderbuffer && this._gl.isRenderbuffer(buff.renderbuffer)) {
|
||||||
|
this._gl.bindRenderbuffer(this._gl.RENDERBUFFER, null);
|
||||||
|
this._gl.deleteRenderbuffer(buff.renderbuffer);
|
||||||
|
buff.renderbuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// texture
|
||||||
|
if (buff.texture && this._gl.isTexture(buff.texture)) {
|
||||||
|
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
||||||
|
this._gl.deleteTexture(buff.texture);
|
||||||
|
buff.texture = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_createBuffer(w, h) {
|
||||||
|
const buff = {};
|
||||||
|
|
||||||
|
// framebuffer
|
||||||
|
buff.framebuffer = this._gl.createFramebuffer();
|
||||||
|
this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, buff.framebuffer);
|
||||||
|
|
||||||
|
// renderbuffer
|
||||||
|
buff.renderbuffer = this._gl.createRenderbuffer();
|
||||||
|
this._gl.bindRenderbuffer(this._gl.RENDERBUFFER, buff.renderbuffer);
|
||||||
|
this._gl.renderbufferStorage(this._gl.RENDERBUFFER, this._gl.DEPTH_COMPONENT16, w, h);
|
||||||
|
this._gl.framebufferRenderbuffer(this._gl.FRAMEBUFFER, this._gl.DEPTH_ATTACHMENT, this._gl.RENDERBUFFER, buff.renderbuffer);
|
||||||
|
|
||||||
|
// texture
|
||||||
|
buff.texture = this._gl.createTexture();
|
||||||
|
this._gl.bindTexture(this._gl.TEXTURE_2D, buff.texture);
|
||||||
|
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, w, h, 0, this._gl.RGBA, this._gl.UNSIGNED_BYTE, null);
|
||||||
|
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, this._gl.LINEAR);
|
||||||
|
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, this._gl.LINEAR);
|
||||||
|
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
|
||||||
|
this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
|
||||||
|
this._gl.framebufferTexture2D(this._gl.FRAMEBUFFER, this._gl.COLOR_ATTACHMENT0, this._gl.TEXTURE_2D, buff.texture, 0);
|
||||||
|
|
||||||
|
// unbind
|
||||||
|
this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
||||||
|
this._gl.bindRenderbuffer(this._gl.RENDERBUFFER, null);
|
||||||
|
this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, null);
|
||||||
|
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
_resetBuffers() {
|
||||||
|
this._resetBuffer(this.backbuffer);
|
||||||
|
this._resetBuffer(this.frontbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
async reset(time) {
|
async reset(time) {
|
||||||
this._resizeTarget();
|
this._resizeTarget();
|
||||||
|
this._resetBuffers();
|
||||||
|
this.backbuffer = this._createBuffer(this._target.width, this._target.height);
|
||||||
|
this.frontbuffer = this._createBuffer(this._target.width, this._target.height);
|
||||||
|
|
||||||
if (this.hasAttribute('mouse')) {
|
if (this.hasAttribute('mouse')) {
|
||||||
this._target.addEventListener('pointermove', this._onMouseMove.bind(this));
|
this._target.addEventListener('pointermove', this._onMouseMove.bind(this));
|
||||||
@ -186,11 +265,7 @@ class RepaShader extends HTMLElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolution = 'resolution';
|
// TODO sound? mrt? textures?
|
||||||
const mouse = 'mouse';
|
|
||||||
const nowTime = 'time';
|
|
||||||
const frame = 'frame';
|
|
||||||
// TODO sound? backbuffer? mrt?
|
|
||||||
|
|
||||||
if (this._program) {
|
if (this._program) {
|
||||||
this._gl.deleteProgram(this._program);
|
this._gl.deleteProgram(this._program);
|
||||||
@ -198,10 +273,11 @@ class RepaShader extends HTMLElement {
|
|||||||
this.program = program;
|
this.program = program;
|
||||||
this._gl.useProgram(this.program);
|
this._gl.useProgram(this.program);
|
||||||
this._uniLocation = {};
|
this._uniLocation = {};
|
||||||
this._uniLocation.resolution = this._gl.getUniformLocation(this.program, resolution);
|
this._uniLocation.resolution = this._gl.getUniformLocation(this.program, 'resolution');
|
||||||
this._uniLocation.mouse = this._gl.getUniformLocation(this.program, mouse);
|
this._uniLocation.mouse = this._gl.getUniformLocation(this.program, 'mouse');
|
||||||
this._uniLocation.time = this._gl.getUniformLocation(this.program, nowTime);
|
this._uniLocation.time = this._gl.getUniformLocation(this.program, 'time');
|
||||||
this._uniLocation.frame = this._gl.getUniformLocation(this.program, frame);
|
this._uniLocation.frame = this._gl.getUniformLocation(this.program, 'frame');
|
||||||
|
this._uniLocation.backbuffer = this._gl.getUniformLocation(this.program, 'backbuffer');
|
||||||
|
|
||||||
this._attLocation = this._gl.getAttribLocation(this.program, 'position');
|
this._attLocation = this._gl.getAttribLocation(this.program, 'position');
|
||||||
this._mousePosition= [0, 0];
|
this._mousePosition= [0, 0];
|
||||||
@ -226,6 +302,13 @@ class RepaShader extends HTMLElement {
|
|||||||
|
|
||||||
this._gl.useProgram(this.program);
|
this._gl.useProgram(this.program);
|
||||||
|
|
||||||
|
this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, this.frontbuffer.framebuffer);
|
||||||
|
|
||||||
|
// backbuffer
|
||||||
|
this._gl.activeTexture(this._gl.TEXTURE0);
|
||||||
|
this._gl.bindTexture(this._gl.TEXTURE_2D, this.backbuffer.texture);
|
||||||
|
this._gl.uniform1i(this._uniLocation.backbuffer, 0);
|
||||||
|
|
||||||
this._gl.enableVertexAttribArray(this._attLocation);
|
this._gl.enableVertexAttribArray(this._attLocation);
|
||||||
this._gl.vertexAttribPointer(this._attLocation, 3, this._gl.FLOAT, false, 0, 0);
|
this._gl.vertexAttribPointer(this._attLocation, 3, this._gl.FLOAT, false, 0, 0);
|
||||||
this._gl.clear(this._gl.COLOR_BUFFER_BIT);
|
this._gl.clear(this._gl.COLOR_BUFFER_BIT);
|
||||||
@ -236,7 +319,22 @@ class RepaShader extends HTMLElement {
|
|||||||
|
|
||||||
this._gl.drawArrays(this._gl.TRIANGLE_STRIP, 0, 4);
|
this._gl.drawArrays(this._gl.TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
// fill buffer
|
||||||
|
this._gl.useProgram(this._postProgram);
|
||||||
|
this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, null);
|
||||||
|
this._gl.activeTexture(this._gl.TEXTURE0);
|
||||||
|
this._gl.bindTexture(this._gl.TEXTURE_2D, this.frontbuffer.texture);
|
||||||
|
this._gl.enableVertexAttribArray(this._postAttLocation);
|
||||||
|
this._gl.vertexAttribPointer(this._postAttLocation, 3, this._gl.FLOAT, false, 0, 0);
|
||||||
|
this._gl.clear(this._gl.COLOR_BUFFER_BIT);
|
||||||
|
this._gl.uniform1i(this._postUniLocation.texture, 0);
|
||||||
|
this._gl.drawArrays(this._gl.TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
this._gl.flush();
|
this._gl.flush();
|
||||||
|
|
||||||
|
// swap buffers
|
||||||
|
[this.frontbuffer, this.backbuffer] = [this.backbuffer, this.frontbuffer];
|
||||||
|
|
||||||
// TODO draw callback
|
// TODO draw callback
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,12 +417,33 @@ class RepaShader extends HTMLElement {
|
|||||||
in vec3 position;
|
in vec3 position;
|
||||||
void main(){
|
void main(){
|
||||||
gl_Position=vec4(position, 1.);
|
gl_Position=vec4(position, 1.);
|
||||||
}
|
}`;
|
||||||
`;
|
}
|
||||||
|
|
||||||
|
get postVS() {
|
||||||
|
return `#version 300 es
|
||||||
|
in vec3 position;
|
||||||
|
out vec2 vTexCoord;
|
||||||
|
void main() {
|
||||||
|
vTexCoord = (position.xy + 1.0) * 0.5;
|
||||||
|
gl_Position = vec4(position, 1.);
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get postFS() {
|
||||||
|
return `#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
uniform sampler2D drawTexture;
|
||||||
|
in vec2 vTexCoord;
|
||||||
|
layout (location = 0) out vec4 outColor;
|
||||||
|
void main() {
|
||||||
|
outColor = texture(drawTexture, vTexCoord);
|
||||||
|
}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFS() {
|
async getFS() {
|
||||||
// auto guessing mode
|
// auto guessing mode
|
||||||
|
// - starts with #version -> raw
|
||||||
// - contains `precision` -> twigl classic300es
|
// - contains `precision` -> twigl classic300es
|
||||||
// - no `precision`, but has `main()` -> twigl geeker300es
|
// - no `precision`, but has `main()` -> twigl geeker300es
|
||||||
// - no `precision`, no `main()` -> twigl geekest300es
|
// - no `precision`, no `main()` -> twigl geekest300es
|
||||||
@ -350,6 +469,8 @@ void main(){
|
|||||||
let end = '';
|
let end = '';
|
||||||
let snippets = '';
|
let snippets = '';
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
case 'raw':
|
||||||
|
return this._fsSource;
|
||||||
case 'classic':
|
case 'classic':
|
||||||
start = CHUNKS.es300;
|
start = CHUNKS.es300;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user