mirror of
https://github.com/dyuri/repa-shader.git
synced 2025-12-16 11:14:25 +00:00
3d texture related refactor
This commit is contained in:
parent
0fb709ff7c
commit
e31e7e39c3
@ -25,11 +25,12 @@
|
|||||||
<body>
|
<body>
|
||||||
<repa-shader id="demoshader" fs-input="fsinput" alpha mouse width=512 height=512>
|
<repa-shader id="demoshader" fs-input="fsinput" alpha mouse width=512 height=512>
|
||||||
<repa-texture src="avatar.png" name="tex_avatar" wrap="mirrored_repeat"></repa-texture>
|
<repa-texture src="avatar.png" name="tex_avatar" wrap="mirrored_repeat"></repa-texture>
|
||||||
|
<repa-texture t3d name="test3d" filter="nearest"></repa-texture>
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = gl_FragCoord.xy / resolution.xy;
|
vec2 uv = gl_FragCoord.xy / resolution.xy;
|
||||||
vec3 col = texture(tex_avatar, uv).rgb;
|
vec3 col = texture(tex_avatar, uv).rgb;
|
||||||
|
|
||||||
col = texture(test3d, vec3(uv.xy, mouse.x)).rrr;
|
col *= texture(test3d, vec3(uv.xy, mouse.x)).rrr;
|
||||||
|
|
||||||
float dist = distance(uv, mouse.xy);
|
float dist = distance(uv, mouse.xy);
|
||||||
float circle = smoothstep(.025, .026, dist) * .5 + .5;
|
float circle = smoothstep(.025, .026, dist) * .5 + .5;
|
||||||
|
|||||||
@ -263,8 +263,9 @@ class RepaShader extends HTMLElement {
|
|||||||
|
|
||||||
_collectTextures() {
|
_collectTextures() {
|
||||||
this._textures = [];
|
this._textures = [];
|
||||||
|
this._textures3d = [];
|
||||||
|
|
||||||
this.querySelectorAll('repa-texture').forEach(t => {
|
this.querySelectorAll('repa-texture:not([t3d])').forEach(t => {
|
||||||
const texture = this._gl.createTexture();
|
const texture = this._gl.createTexture();
|
||||||
this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
||||||
|
|
||||||
@ -282,54 +283,22 @@ class RepaShader extends HTMLElement {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO 3d texture experiment
|
this.querySelectorAll('repa-texture[t3d]').forEach(t => {
|
||||||
let texture = this._gl.createTexture();
|
let texture = this._gl.createTexture();
|
||||||
this._gl.bindTexture(this._gl.TEXTURE_3D, texture);
|
this._gl.bindTexture(this._gl.TEXTURE_3D, texture);
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, this._gl.NEAREST);
|
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, this._getFilter(t.minFilter));
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, this._gl.NEAREST);
|
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, this._getFilter(t.magFilter));
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
|
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._getWrap(t.wrapS));
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
|
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._getWrap(t.wrapT));
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._gl.CLAMP_TO_EDGE);
|
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._getWrap(t.wrapR));
|
||||||
// ???
|
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_BASE_LEVEL, 0);
|
|
||||||
this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAX_LEVEL, 0);
|
|
||||||
|
|
||||||
let size = 32;
|
this._gl.texImage3D(this._gl.TEXTURE_3D, 0, this._gl.RGBA, 1, 1, 1, 0, this._gl.RGBA, this._gl.UNSIGNED_BYTE, new Uint8Array([64, 255, 128, 255]));
|
||||||
let t3data = new Uint8Array(size * size * size);
|
|
||||||
|
|
||||||
for (let i = 0; i < size; i++) {
|
this._textures3d.push({
|
||||||
for (let j = 0; j < size; j++) {
|
texture,
|
||||||
for (let k = 0; k < size; k++) {
|
texElement: t
|
||||||
let index = i * size * size + j * size + k;
|
});
|
||||||
t3data[index] = (i * j * k) % 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._gl.texImage3D(
|
|
||||||
this._gl.TEXTURE_3D, // target
|
|
||||||
0, // level
|
|
||||||
this._gl.R8, // format - red8 (1byte)
|
|
||||||
size, // width
|
|
||||||
size, // height
|
|
||||||
size, // depth
|
|
||||||
0, // border
|
|
||||||
this._gl.RED, // format - red
|
|
||||||
this._gl.UNSIGNED_BYTE, // type - unsigned byte
|
|
||||||
t3data // data
|
|
||||||
);
|
|
||||||
|
|
||||||
this._textures3d = [];
|
|
||||||
this._textures3d.push({
|
|
||||||
texture,
|
|
||||||
texElement: {
|
|
||||||
name: 'test3d',
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
depth: size,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
// TODO end of 3d texture experiment
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async reset(time) {
|
async reset(time) {
|
||||||
@ -375,8 +344,6 @@ class RepaShader extends HTMLElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO sound?
|
|
||||||
|
|
||||||
if (this._program) {
|
if (this._program) {
|
||||||
this._gl.deleteProgram(this._program);
|
this._gl.deleteProgram(this._program);
|
||||||
}
|
}
|
||||||
@ -401,11 +368,10 @@ class RepaShader extends HTMLElement {
|
|||||||
t.texElement.forceUpdate();
|
t.texElement.forceUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO 3d texture experiment
|
|
||||||
this._textures3d.forEach((t) => {
|
this._textures3d.forEach((t) => {
|
||||||
this._uniLocation[t.texElement.name] = this._gl.getUniformLocation(this.program, t.texElement.name); // texture
|
this._uniLocation[t.texElement.name] = this._gl.getUniformLocation(this.program, t.texElement.name); // texture
|
||||||
this._uniLocation[t.texElement.name+'_d'] = this._gl.getUniformLocation(this.program, t.texElement.name+'_d'); // dimensions
|
this._uniLocation[t.texElement.name+'_d'] = this._gl.getUniformLocation(this.program, t.texElement.name+'_d'); // dimensions
|
||||||
// TODO
|
t.texElement.forceUpdate();
|
||||||
});
|
});
|
||||||
|
|
||||||
this._attLocation = this._gl.getAttribLocation(this.program, 'position');
|
this._attLocation = this._gl.getAttribLocation(this.program, 'position');
|
||||||
@ -465,13 +431,17 @@ class RepaShader extends HTMLElement {
|
|||||||
this._gl.uniform2fv(this._uniLocation[t.texElement.name+'_d'], [t.texElement.width || 1, t.texElement.height || 1]);
|
this._gl.uniform2fv(this._uniLocation[t.texElement.name+'_d'], [t.texElement.width || 1, t.texElement.height || 1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO 3d texture experiment
|
|
||||||
this._textures3d.forEach((t, i) => {
|
this._textures3d.forEach((t, i) => {
|
||||||
this._gl.activeTexture(this._gl.TEXTURE0 + i + this.mrt + this._textures.length);
|
this._gl.activeTexture(this._gl.TEXTURE0 + i + this.mrt + this._textures.length);
|
||||||
this._gl.bindTexture(this._gl.TEXTURE_3D, t.texture);
|
this._gl.bindTexture(this._gl.TEXTURE_3D, t.texture);
|
||||||
this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, 0);
|
|
||||||
|
|
||||||
// TODO update, etc
|
// update if needed
|
||||||
|
if (t.texElement.shouldUpdate) {
|
||||||
|
const format = this._getFormat(t.texElement.format);
|
||||||
|
this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, 0);
|
||||||
|
|
||||||
|
this._gl.texImage3D(this._gl.TEXTURE_3D, 0, format, t.texElement.width, t.texElement.height, t.texElement.depth, 0, format, this._gl.UNSIGNED_BYTE, t.texElement.update());
|
||||||
|
}
|
||||||
|
|
||||||
this._gl.uniform1i(this._uniLocation[t.texElement.name], i + this.mrt + this._textures.length);
|
this._gl.uniform1i(this._uniLocation[t.texElement.name], i + this.mrt + this._textures.length);
|
||||||
this._gl.uniform3fv(this._uniLocation[t.texElement.name+'_d'], [t.texElement.width || 1, t.texElement.height || 1, t.texElement.depth || 1]);
|
this._gl.uniform3fv(this._uniLocation[t.texElement.name+'_d'], [t.texElement.width || 1, t.texElement.height || 1, t.texElement.depth || 1]);
|
||||||
@ -591,7 +561,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get postFS() {
|
get postFS() {
|
||||||
// TODO 3d texture experiment
|
|
||||||
return `#version 300 es
|
return `#version 300 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
uniform sampler2D drawTexture;
|
uniform sampler2D drawTexture;
|
||||||
@ -636,7 +605,6 @@ void main() {
|
|||||||
uniform vec2 ${t.texElement.name}_d;
|
uniform vec2 ${t.texElement.name}_d;
|
||||||
`;
|
`;
|
||||||
}).join('') +
|
}).join('') +
|
||||||
// TODO 3d texture experiment
|
|
||||||
this._textures3d.map(t => {
|
this._textures3d.map(t => {
|
||||||
return `
|
return `
|
||||||
uniform sampler3D ${t.texElement.name};
|
uniform sampler3D ${t.texElement.name};
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class RepaTexture extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
return ['src', 'type', 'mag-filter', 'min-filter', 'filter', 'wrap-s', 'wrap-t', 'wrap', 'format'];
|
return ['src', 'type', 'mag-filter', 'min-filter', 'filter', 'wrap-s', 'wrap-t', 'wrap-r', 'wrap', 'format'];
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
@ -86,8 +86,29 @@ class RepaTexture extends HTMLElement {
|
|||||||
this._forceUpdate = true;
|
this._forceUpdate = true;
|
||||||
} else if (this.textContent) {
|
} else if (this.textContent) {
|
||||||
this.content = JSON.parse(this.textContent);
|
this.content = JSON.parse(this.textContent);
|
||||||
|
} else if (this.t3d) { // TODO 3d texture experiment
|
||||||
|
let size = 32;
|
||||||
|
this._width = size;
|
||||||
|
this._height = size;
|
||||||
|
this._depth = size;
|
||||||
|
|
||||||
|
let t3data = new Uint8Array(size * size * size);
|
||||||
|
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
for (let j = 0; j < size; j++) {
|
||||||
|
for (let k = 0; k < size; k++) {
|
||||||
|
let index = i * size * size + j * size + k;
|
||||||
|
t3data[index] = (i * j * k) % 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._content = t3data;
|
||||||
|
this._forceUpdate = true;
|
||||||
|
this._format = 'luminance';
|
||||||
|
this.ready = true;
|
||||||
} else {
|
} else {
|
||||||
this.logger.error('Source cannot be loaded');
|
this.logger.error('Texture content cannot be loaded!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,8 +233,12 @@ class RepaTexture extends HTMLElement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get t3d() {
|
||||||
|
return this.hasAttribute('t3d');
|
||||||
|
}
|
||||||
|
|
||||||
get flipY() {
|
get flipY() {
|
||||||
return this.type !== 'raw';
|
return !this.t3d && this.type !== 'raw';
|
||||||
}
|
}
|
||||||
|
|
||||||
setContent(data) {
|
setContent(data) {
|
||||||
@ -334,6 +359,10 @@ class RepaTexture extends HTMLElement {
|
|||||||
return this._height || this.ref?.videoHeight || this.ref?.height || 0;
|
return this._height || this.ref?.videoHeight || this.ref?.height || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get depth() {
|
||||||
|
return this._depth || this.ref?.depth || 0;
|
||||||
|
}
|
||||||
|
|
||||||
get magFilter() {
|
get magFilter() {
|
||||||
return this._filter || this.getAttribute('mag-filter') || this.getAttribute('filter') || 'linear';
|
return this._filter || this.getAttribute('mag-filter') || this.getAttribute('filter') || 'linear';
|
||||||
}
|
}
|
||||||
@ -350,6 +379,10 @@ class RepaTexture extends HTMLElement {
|
|||||||
return this.getAttribute('wrap-t') || this.getAttribute('wrap') || 'clamp-to-edge';
|
return this.getAttribute('wrap-t') || this.getAttribute('wrap') || 'clamp-to-edge';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get wrapR() {
|
||||||
|
return this.getAttribute('wrap-r') || this.getAttribute('wrap') || 'clamp-to-edge';
|
||||||
|
}
|
||||||
|
|
||||||
get format() {
|
get format() {
|
||||||
return this._format || this.getAttribute('format') || 'rgba';
|
return this._format || this.getAttribute('format') || 'rgba';
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user