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>
|
||||
<body>
|
||||
<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() {
|
||||
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);
|
||||
float circle = smoothstep(.15, .2, dist);
|
||||
vec4 acolor = vec4(col * (1. - circle), (1. - circle)) + circle * texture(backbuffer, uv - vec2(.01, .01)) * .9;
|
||||
outColor = vec4(acolor);
|
||||
}
|
||||
</script>
|
||||
<script type="x-shader/x-fragment">
|
||||
<script type="x-shader/x-fragmen">
|
||||
// https://twigl.app/?ol=true&ss=-NOAlYulOVLklxMdxBDx
|
||||
void main() {
|
||||
vec2 n,N,q,p=FC.xy/r.y;
|
||||
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);
|
||||
}
|
||||
</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>
|
||||
</repa-shader>
|
||||
<div>
|
||||
|
||||
@ -15,14 +15,16 @@ const CHUNKS = {
|
||||
#define m mouse
|
||||
#define t time
|
||||
#define f frame
|
||||
#define b backbuffer
|
||||
#define o outColor
|
||||
precision highp float;
|
||||
uniform vec2 resolution;
|
||||
uniform vec2 mouse;
|
||||
uniform float time;
|
||||
uniform float frame;
|
||||
uniform sampler2D backbuffer;
|
||||
out vec4 outColor;
|
||||
`, // TODO sampler2D, MRT
|
||||
`, // TODO MRT
|
||||
geekestStart: `
|
||||
void main() {
|
||||
`,
|
||||
@ -74,6 +76,17 @@ class RepaShader extends HTMLElement {
|
||||
|
||||
// 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.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);
|
||||
@ -154,8 +167,74 @@ class RepaShader extends HTMLElement {
|
||||
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) {
|
||||
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')) {
|
||||
this._target.addEventListener('pointermove', this._onMouseMove.bind(this));
|
||||
@ -186,11 +265,7 @@ class RepaShader extends HTMLElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolution = 'resolution';
|
||||
const mouse = 'mouse';
|
||||
const nowTime = 'time';
|
||||
const frame = 'frame';
|
||||
// TODO sound? backbuffer? mrt?
|
||||
// TODO sound? mrt? textures?
|
||||
|
||||
if (this._program) {
|
||||
this._gl.deleteProgram(this._program);
|
||||
@ -198,10 +273,11 @@ class RepaShader extends HTMLElement {
|
||||
this.program = program;
|
||||
this._gl.useProgram(this.program);
|
||||
this._uniLocation = {};
|
||||
this._uniLocation.resolution = this._gl.getUniformLocation(this.program, resolution);
|
||||
this._uniLocation.mouse = this._gl.getUniformLocation(this.program, mouse);
|
||||
this._uniLocation.time = this._gl.getUniformLocation(this.program, nowTime);
|
||||
this._uniLocation.frame = this._gl.getUniformLocation(this.program, frame);
|
||||
this._uniLocation.resolution = this._gl.getUniformLocation(this.program, 'resolution');
|
||||
this._uniLocation.mouse = this._gl.getUniformLocation(this.program, 'mouse');
|
||||
this._uniLocation.time = this._gl.getUniformLocation(this.program, 'time');
|
||||
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._mousePosition= [0, 0];
|
||||
@ -226,6 +302,13 @@ class RepaShader extends HTMLElement {
|
||||
|
||||
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.vertexAttribPointer(this._attLocation, 3, this._gl.FLOAT, false, 0, 0);
|
||||
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);
|
||||
|
||||
// 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();
|
||||
|
||||
// swap buffers
|
||||
[this.frontbuffer, this.backbuffer] = [this.backbuffer, this.frontbuffer];
|
||||
|
||||
// TODO draw callback
|
||||
}
|
||||
|
||||
@ -319,12 +417,33 @@ class RepaShader extends HTMLElement {
|
||||
in vec3 position;
|
||||
void main(){
|
||||
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() {
|
||||
// auto guessing mode
|
||||
// - starts with #version -> raw
|
||||
// - contains `precision` -> twigl classic300es
|
||||
// - no `precision`, but has `main()` -> twigl geeker300es
|
||||
// - no `precision`, no `main()` -> twigl geekest300es
|
||||
@ -350,6 +469,8 @@ void main(){
|
||||
let end = '';
|
||||
let snippets = '';
|
||||
switch (mode) {
|
||||
case 'raw':
|
||||
return this._fsSource;
|
||||
case 'classic':
|
||||
start = CHUNKS.es300;
|
||||
break;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user