mirror of
https://github.com/dyuri/repa-shader.git
synced 2025-12-16 11:14:25 +00:00
snippet loading
This commit is contained in:
parent
3f3f40b331
commit
68e54df51b
@ -22,14 +22,40 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<repa-shader fs-input="fsinput" alpha mouse snippet-prefix="../src/snippets">
|
<repa-shader fs-input="fsinput" alpha mouse snippets="noise.glsl" width=512 height=512>
|
||||||
<script type="x-shader/x-vertex">
|
<script type="x-shader/x-fragmen">
|
||||||
attribute vec3 position;
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(position, 1.0);
|
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>
|
||||||
<script type="x-shader/x-fragment">
|
<script type="x-shader/x-fragment">
|
||||||
|
void main() {
|
||||||
|
vec2 n,N,q,p=FC.xy/r.y;
|
||||||
|
float S=9.,a,j;
|
||||||
|
for(mat2 m=rotate2D(5.);j++<30.;){
|
||||||
|
p*=m;
|
||||||
|
n*=m;
|
||||||
|
q=p*S+j+n+t;
|
||||||
|
a+=dot(cos(q)/S,r/r);
|
||||||
|
n+=q=sin(q);
|
||||||
|
N+=q/(S+60.);
|
||||||
|
S*=1.2;
|
||||||
|
}
|
||||||
|
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() {
|
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));
|
||||||
|
|||||||
@ -49,9 +49,8 @@ void main() {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
class RepaShader extends HTMLElement {
|
class RepaShader extends HTMLElement {
|
||||||
constructor(cfg = {}) {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._cfg = cfg;
|
|
||||||
this.attachShadow({ mode: 'open' });
|
this.attachShadow({ mode: 'open' });
|
||||||
this.logger = createLogger(["%c[repa-shader]", "background: #1d2021; color: #bada55"]);
|
this.logger = createLogger(["%c[repa-shader]", "background: #1d2021; color: #bada55"]);
|
||||||
this._snippets = {};
|
this._snippets = {};
|
||||||
@ -65,7 +64,7 @@ class RepaShader extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this._gl) {
|
if (!this._gl) {
|
||||||
const glopts = this._cfg.glopts || {alpha: this.hasAttribute('alpha'), preserveDrawingBuffer: true};
|
const glopts = {alpha: this.hasAttribute('alpha'), preserveDrawingBuffer: true};
|
||||||
this._gl = this._target.getContext('webgl2', glopts);
|
this._gl = this._target.getContext('webgl2', glopts);
|
||||||
if (!this._gl) {
|
if (!this._gl) {
|
||||||
this.logger.error("WebGL2 not supported");
|
this.logger.error("WebGL2 not supported");
|
||||||
@ -74,8 +73,6 @@ class RepaShader extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO resize
|
// TODO resize
|
||||||
// TODO postprogram
|
|
||||||
// TODO source + reset
|
|
||||||
|
|
||||||
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);
|
||||||
@ -84,7 +81,6 @@ class RepaShader extends HTMLElement {
|
|||||||
this._gl.disable(this._gl.BLEND);
|
this._gl.disable(this._gl.BLEND);
|
||||||
this._gl.clearColor(0,0,0,1);
|
this._gl.clearColor(0,0,0,1);
|
||||||
|
|
||||||
// TODO remove
|
|
||||||
this.render(this.getFragmentShaderSource());
|
this.render(this.getFragmentShaderSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +93,18 @@ class RepaShader extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get snippetPrefix() {
|
get snippetPrefix() {
|
||||||
return this.getAttribute('snippet-prefix') || 'snippets';
|
if (this.hasAttribute('snippet-prefix')) {
|
||||||
|
return this.getAttribute('snippet-prefix');
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = '';
|
||||||
|
if (import.meta?.url) {
|
||||||
|
const pathparts = new URL(import.meta.url).pathname.split('/');
|
||||||
|
pathparts.pop();
|
||||||
|
path = pathparts.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return path + '/snippets';
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadSnippet(name) {
|
async loadSnippet(name) {
|
||||||
@ -123,11 +130,21 @@ class RepaShader extends HTMLElement {
|
|||||||
return this._snippets[name];
|
return this._snippets[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _getSnippets() {
|
||||||
|
if (!this.hasAttribute('snippets')) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const snippetNames = this.getAttribute('snippets').split(',');
|
||||||
|
const promises = snippetNames.map(s => this.getSnippet(s));
|
||||||
|
|
||||||
|
return await Promise.all(promises).then(snippets => snippets.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
_resizeTarget() {
|
_resizeTarget() {
|
||||||
const {width, height} = this._target.getBoundingClientRect();
|
const {width, height} = this._target.getBoundingClientRect();
|
||||||
this._target.width = width;
|
this._target.width = width;
|
||||||
this._target.height = height;
|
this._target.height = height;
|
||||||
// TODO buffers
|
|
||||||
this._gl.viewport(0, 0, width, height);
|
this._gl.viewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +186,6 @@ class RepaShader extends HTMLElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO geek mode
|
|
||||||
const resolution = 'resolution';
|
const resolution = 'resolution';
|
||||||
const mouse = 'mouse';
|
const mouse = 'mouse';
|
||||||
const nowTime = 'time';
|
const nowTime = 'time';
|
||||||
@ -209,7 +225,6 @@ class RepaShader extends HTMLElement {
|
|||||||
++this._frame;
|
++this._frame;
|
||||||
|
|
||||||
this._gl.useProgram(this.program);
|
this._gl.useProgram(this.program);
|
||||||
// TODO buffers
|
|
||||||
|
|
||||||
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);
|
||||||
@ -263,10 +278,18 @@ class RepaShader extends HTMLElement {
|
|||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get width() {
|
||||||
|
return this.getAttribute('width');
|
||||||
|
}
|
||||||
|
|
||||||
|
get height() {
|
||||||
|
return this.getAttribute('height');
|
||||||
|
}
|
||||||
|
|
||||||
_createTarget() {
|
_createTarget() {
|
||||||
const target = document.createElement('canvas');
|
const target = document.createElement('canvas');
|
||||||
target.width = this._cfg.width || 300; // TODO
|
target.width = this.width || 300; // TODO
|
||||||
target.height = this._cfg.height || 300; // TODO
|
target.height = this.height || 300; // TODO
|
||||||
this.shadowRoot.appendChild(target);
|
this.shadowRoot.appendChild(target);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
@ -291,7 +314,6 @@ class RepaShader extends HTMLElement {
|
|||||||
return this._target;
|
return this._target;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
get VS() {
|
get VS() {
|
||||||
return `#version 300 es
|
return `#version 300 es
|
||||||
in vec3 position;
|
in vec3 position;
|
||||||
@ -309,29 +331,36 @@ void main(){
|
|||||||
// TODO: mrt
|
// TODO: mrt
|
||||||
let mode = this.mode;
|
let mode = this.mode;
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
|
const hasVersion = this._fsSource.startsWith('#version');
|
||||||
const hasPrecision = this._fsSource.includes('precision');
|
const hasPrecision = this._fsSource.includes('precision');
|
||||||
const hasMain = this._fsSource.includes('main()');
|
const hasMain = this._fsSource.includes('main()');
|
||||||
if (hasPrecision) {
|
if (hasVersion) {
|
||||||
|
mode = 'raw';
|
||||||
|
} else if (hasPrecision) {
|
||||||
mode = 'classic';
|
mode = 'classic';
|
||||||
} else if (hasMain) {
|
} else if (hasMain) {
|
||||||
mode = 'geeker';
|
mode = 'geeker';
|
||||||
} else {
|
} else {
|
||||||
mode = 'geekest';
|
mode = 'geekest';
|
||||||
}
|
}
|
||||||
|
this.logger.info(`Auto guessing mode: ${mode}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = '';
|
let start = '';
|
||||||
let end = '';
|
let end = '';
|
||||||
|
let snippets = '';
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'classic':
|
case 'classic':
|
||||||
start = CHUNKS.es300;
|
start = CHUNKS.es300;
|
||||||
break;
|
break;
|
||||||
case 'geeker':
|
case 'geeker':
|
||||||
start = CHUNKS.es300 + CHUNKS.geeker;
|
snippets = await this._getSnippets();
|
||||||
|
start = CHUNKS.es300 + CHUNKS.geeker + snippets;
|
||||||
break;
|
break;
|
||||||
case 'geekest':
|
case 'geekest':
|
||||||
|
snippets = await this._getSnippets();
|
||||||
const noise = await this.getSnippet('noise.glsl');
|
const noise = await this.getSnippet('noise.glsl');
|
||||||
start = CHUNKS.es300 + CHUNKS.geeker + noise + CHUNKS.geekestStart;
|
start = CHUNKS.es300 + CHUNKS.geeker + noise + snippets + CHUNKS.geekestStart;
|
||||||
end = CHUNKS.geekestEnd;
|
end = CHUNKS.geekestEnd;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user