3d texture related refactor

This commit is contained in:
Gyuri Horák 2023-03-25 20:17:23 +01:00
parent 0fb709ff7c
commit e31e7e39c3
Signed by: dyuri
GPG Key ID: 4993F07B3EAE8D38
3 changed files with 61 additions and 59 deletions

View File

@ -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;

View File

@ -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};

View File

@ -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';
} }