Skip to content

Commit 3b58893

Browse files
authored
Merge pull request #18 from Absulit/dev
texture optimizations
2 parents 2983096 + 71779cb commit 3b58893

3 files changed

Lines changed: 86 additions & 30 deletions

File tree

src/main.js

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import frag0 from './renderpasses/renderpass0/frag.js';
44
import vert from './renderpasses/renderpass0/vert.js';
55
import * as dat from 'datgui';
66
import { Dexie } from 'https://unpkg.com/dexie/dist/modern/dexie.mjs';
7-
import { countImageColors, readTags, strToCodes } from './utils.js';
7+
import { countImageColors, loadImage, readTags, sprite, strToCodes, strToImage } from './utils.js';
88

99
/**
1010
* @type {Points}
@@ -47,17 +47,21 @@ function clickSong() {
4747
playSong(this);
4848
}
4949

50-
function playSong(song) {
50+
async function playSong(song) {
5151
const { file } = song;
5252
points.setUniform('showMessage', 0);
5353
const audioUrl = URL.createObjectURL(file);
5454
const name = song?.name || file.name;
55-
const title = song?.title || name;
55+
const title = name;
5656

5757
audio && audio.pause() && (audio = null);
5858
audio = points.setAudio('audio', audioUrl, options.volume, false, false);
5959
points.setUniform('numChars', title.length < MAXCHARS ? title.length : MAXCHARS);
60-
points.setStorageMap('chars', strToCodes(title));
60+
// points.setStorageMap('chars', strToCodes(title));
61+
62+
const songNameImg = strToImage(title, atlas, size);
63+
await points.setTextureImage('songName', songNameImg);
64+
6165
let artworkLoaded = 0;
6266
song?.artworkColors && points.setStorageMap('artworkColors', song?.artworkColors.flat());
6367
song?.artworkColors && (artworkLoaded = 1);
@@ -129,7 +133,8 @@ async function onCompleteTags(result) {
129133
const { tag, song } = result;
130134
const { file } = song;
131135
const { title, album, picture } = tag.tags;
132-
const name = `${title} - ${album}`
136+
const albumExists = album?` - ${album}`: '';
137+
const name = `${title}${albumExists}`
133138
let artworkImageUrl = null;
134139
let artworkColors = null;
135140

@@ -147,7 +152,7 @@ async function onCompleteTags(result) {
147152
}
148153

149154
song.name = name || file.name;
150-
song.title = title || name;
155+
song.title = name;
151156

152157

153158
if (!song.default) {
@@ -162,7 +167,10 @@ async function onCompleteTags(result) {
162167

163168
folderSongs.add(song, 'fn').name(song.name);
164169
points.setUniform('numChars', title.length < MAXCHARS ? title.length : MAXCHARS);
165-
points.setStorageMap('chars', strToCodes(title));
170+
// points.setStorageMap('chars', strToCodes(title));
171+
172+
const songNameImg = strToImage(title, atlas, size);
173+
await points.setTextureImage('songName', songNameImg);
166174
}
167175

168176
async function onErrorTags(response) {
@@ -333,11 +341,24 @@ points.setUniform('progress', 0);
333341
points.setUniform('artworkLoaded', 0);
334342
// points.setUniform('somecolor', colors.color2, 'vec3f');
335343
points.setUniform('numChars', 12);
336-
points.setStorageMap('chars', strToCodes('Gravity Pull'), 'array<f32>')// TODO: setStorageMap doesn't work with u32 wrong sized
337-
points.setStorageMap('message', strToCodes('Select a song to Play'), 'array<f32>')// TODO: setStorageMap doesn't work with u32 wrong sized
344+
// points.setStorageMap('chars', strToCodes('Gravity Pull'), 'array<f32>')// TODO: setStorageMap doesn't work with u32 wrong sized
338345
points.setStorageMap('artworkColors', Array(16).fill(1), 'array<vec4f>');
339346
points.setStorage('variables', 'Variables');
340347
await points.setTextureImage('font', './src/img/inconsolata_regular_8x22.png');
348+
349+
350+
351+
const size = { x: 8, y: 22 };
352+
const atlas = await loadImage('src/img/inconsolata_regular_8x22.png');
353+
const messageStringImg = strToImage('Select a song to Play', atlas, size);
354+
await points.setTextureImage('messageString', messageStringImg);
355+
356+
357+
358+
const songNameImg = strToImage('Gravity Pull', atlas, size);
359+
await points.setTextureImage('songName', songNameImg);
360+
361+
341362
const renderPasses = [
342363
new RenderPass(vert, frag0, null),
343364
];
@@ -432,4 +453,4 @@ async function loadSongFromURL() {
432453
window.history.replaceState(null, '', url.toString());
433454
}
434455

435-
loadSongFromURL()
456+
loadSongFromURL()

src/renderpasses/renderpass0/frag.js

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -238,30 +238,16 @@ fn main(
238238
var stringMask = 0.;
239239
var stringMask2 = 0.;
240240
let textScale = 2.476 * ratio.y + c0;
241-
let textUVR = uvr / textScale;
242-
let spaceRatio = .0017 * ratio.x;
243-
244-
for (var index = 0; index < i32(params.numChars); index++) {
245-
let indexF32 = f32(index);
246-
let charIndex = u32(chars[index]);
247-
let charPosition = charSizeF32 * vec2(indexF32, 0);
248-
let space = spaceRatio * vec2(indexF32, 0);
249-
let sfPcP = space + fontPosition + charPosition;
250-
let cIcO = charIndex - charOffset;
251-
stringMask += sprite(font, textImageSampler, sfPcP, textUVR, cIcO, charSize).x;
252-
stringMask2 += sprite(font, textImageSampler, sfPcP, textUVR + .0005, cIcO, charSize).x;
253-
}
241+
var textUVR = uvr / textScale;
242+
243+
stringMask = texturePosition(songName, textImageSampler, fontPosition, textUVR, false).r;
244+
stringMask2 = texturePosition(songName, textImageSampler, fontPosition, textUVR + .0005, false).r;
254245
255246
var messageStringMask = 0.;
256247
if(params.showMessage == 1.){
257248
let messagePosition = vec2(.15, .19) * ratio;
258-
for (var index = 0; index < 21; index++) {
259-
let indexF32 = f32(index);
260-
let charIndex = u32(message[index]);
261-
let charPosition = charSizeF32 * vec2(indexF32, sin(params.time + indexF32 * .1));
262-
let space = spaceRatio * vec2(indexF32, 0);
263-
messageStringMask += sprite(font, textImageSampler, space + messagePosition + charPosition, textUVR, charIndex - charOffset, charSize).x;
264-
}
249+
textUVR = vec2f(textUVR.x, textUVR.y + sin(params.time + textUVR.x * 10 ) * .01);
250+
messageStringMask = texturePosition(messageString, textImageSampler, messagePosition, textUVR, false).r;
265251
}
266252
267253

src/utils.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,52 @@ export async function countImageColors(src) {
6060

6161
});
6262
}
63+
64+
/**
65+
*
66+
* @param {Image} atlas Image atlas to parse
67+
* @param {CanvasRenderingContext2D} ctx Canvas context
68+
* @param {Number} index index in the atlas, so 0 is the first char
69+
* @param {Object} size cell dimensions
70+
* @param {Number} finalIndex final positional index in the canvas
71+
*/
72+
export function sprite(atlas, ctx, index, size, finalIndex) {
73+
const { width } = atlas;
74+
const numColumns = width / size.x
75+
76+
const x = index % numColumns;
77+
const y = Math.floor(index / numColumns);
78+
79+
ctx.drawImage(
80+
atlas,
81+
x * size.x,
82+
y * size.y,
83+
size.x,
84+
size.y,
85+
86+
size.x * finalIndex,
87+
0,
88+
89+
size.x,
90+
size.y);
91+
}
92+
93+
export function strToImage(str, atlasImg, size){
94+
const chars = strToCodes(str);
95+
const canvas = document.createElement('canvas');
96+
canvas.width = chars.length * size.x;
97+
canvas.height = size.y;
98+
const ctx = canvas.getContext('2d');
99+
100+
chars.forEach((c, i) => sprite(atlasImg, ctx, c - 32, size, i));
101+
return canvas.toDataURL('image/png');
102+
}
103+
104+
export async function loadImage(src) {
105+
return new Promise((resolve, reject) => {
106+
const img = new Image();
107+
img.src = src;
108+
img.onload = () => resolve(img);
109+
img.onerror = err => reject(err);
110+
});
111+
}

0 commit comments

Comments
 (0)