@flare-engine/render 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.mts +190 -2
- package/dist/index.d.ts +190 -2
- package/dist/index.js +623 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +621 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -6
package/dist/index.js
CHANGED
|
@@ -34,10 +34,12 @@ __export(index_exports, {
|
|
|
34
34
|
SpriteBatch: () => SpriteBatch,
|
|
35
35
|
WATER_SKSL: () => WATER_SKSL,
|
|
36
36
|
caveInterior: () => caveInterior,
|
|
37
|
+
createFrameRenderer: () => createFrameRenderer,
|
|
37
38
|
createRenderSystem: () => createRenderSystem,
|
|
38
39
|
custom: () => custom,
|
|
39
40
|
drawOrderCompare: () => drawOrderCompare,
|
|
40
41
|
drawText: () => drawText,
|
|
42
|
+
dropShadow: () => dropShadow,
|
|
41
43
|
fire: () => fire,
|
|
42
44
|
flash: () => flash,
|
|
43
45
|
flashIntensity: () => flashIntensity,
|
|
@@ -594,6 +596,15 @@ function fire(opts) {
|
|
|
594
596
|
intensity: opts.intensity ?? 0.8
|
|
595
597
|
};
|
|
596
598
|
}
|
|
599
|
+
function dropShadow(opts) {
|
|
600
|
+
return {
|
|
601
|
+
type: "drop-shadow",
|
|
602
|
+
color: opts.color,
|
|
603
|
+
offsetX: opts.offsetX ?? 0,
|
|
604
|
+
offsetY: opts.offsetY ?? 6,
|
|
605
|
+
blur: opts.blur ?? 4
|
|
606
|
+
};
|
|
607
|
+
}
|
|
597
608
|
function roofsCity(opts) {
|
|
598
609
|
return {
|
|
599
610
|
type: "roofs-city",
|
|
@@ -989,6 +1000,616 @@ half4 main(float2 coord) {
|
|
|
989
1000
|
`
|
|
990
1001
|
);
|
|
991
1002
|
|
|
1003
|
+
// src/frame-renderer.ts
|
|
1004
|
+
var BLEND_SRC_OVER = 3;
|
|
1005
|
+
var BLEND_SRC_IN = 5;
|
|
1006
|
+
var OUTLINE_OFFSETS = [
|
|
1007
|
+
[1, 0],
|
|
1008
|
+
[-1, 0],
|
|
1009
|
+
[0, 1],
|
|
1010
|
+
[0, -1],
|
|
1011
|
+
[Math.SQRT1_2, Math.SQRT1_2],
|
|
1012
|
+
[Math.SQRT1_2, -Math.SQRT1_2],
|
|
1013
|
+
[-Math.SQRT1_2, Math.SQRT1_2],
|
|
1014
|
+
[-Math.SQRT1_2, -Math.SQRT1_2]
|
|
1015
|
+
];
|
|
1016
|
+
function createFrameRenderer(Skia) {
|
|
1017
|
+
const defaultPaint = Skia.Paint();
|
|
1018
|
+
let tintPaint = null;
|
|
1019
|
+
let flashPaint = null;
|
|
1020
|
+
let grayscalePaint = null;
|
|
1021
|
+
let outlinePaint = null;
|
|
1022
|
+
let customPaint = null;
|
|
1023
|
+
let waterPaint = null;
|
|
1024
|
+
let waterRuntimeEffect = null;
|
|
1025
|
+
let fogPaint = null;
|
|
1026
|
+
let fogRuntimeEffect = null;
|
|
1027
|
+
let firePaint = null;
|
|
1028
|
+
let fireRuntimeEffect = null;
|
|
1029
|
+
let dropShadowPaint = null;
|
|
1030
|
+
let roofsCityPaint = null;
|
|
1031
|
+
let roofsCityEffect = null;
|
|
1032
|
+
let forestCanopyPaint = null;
|
|
1033
|
+
let forestCanopyEffect = null;
|
|
1034
|
+
let riverWavePaint = null;
|
|
1035
|
+
let riverWaveEffect = null;
|
|
1036
|
+
let moonCraterPaint = null;
|
|
1037
|
+
let moonCraterEffect = null;
|
|
1038
|
+
let caveInteriorPaint = null;
|
|
1039
|
+
let caveInteriorEffect = null;
|
|
1040
|
+
let mountainHillsPaint = null;
|
|
1041
|
+
let mountainHillsEffect = null;
|
|
1042
|
+
const roofsCityUniforms = new Array(10).fill(0);
|
|
1043
|
+
const forestCanopyUniforms = new Array(10).fill(0);
|
|
1044
|
+
const riverWaveUniforms = new Array(10).fill(0);
|
|
1045
|
+
const moonCraterUniforms = new Array(10).fill(0);
|
|
1046
|
+
const caveInteriorUniforms = new Array(10).fill(0);
|
|
1047
|
+
const mountainHillsUniforms = new Array(10).fill(0);
|
|
1048
|
+
const recorder = Skia.PictureRecorder();
|
|
1049
|
+
const recordingBounds = Skia.XYWHRect(0, 0, 0, 0);
|
|
1050
|
+
const srcRects = [];
|
|
1051
|
+
const xforms = [];
|
|
1052
|
+
const stretchSrcRects = [];
|
|
1053
|
+
const stretchDstRects = [];
|
|
1054
|
+
let stretchPaint = null;
|
|
1055
|
+
const zoneBgRects = [];
|
|
1056
|
+
let _cachedSrcSlice = null;
|
|
1057
|
+
let _cachedSrcSliceLen = 0;
|
|
1058
|
+
let _cachedXformSlice = null;
|
|
1059
|
+
let _cachedXformSliceLen = 0;
|
|
1060
|
+
const clearColor = new Float32Array(4);
|
|
1061
|
+
const tintColor = new Float32Array(4);
|
|
1062
|
+
const flashColor = new Float32Array(4);
|
|
1063
|
+
const outlineColor = new Float32Array(4);
|
|
1064
|
+
const dropShadowColor = new Float32Array(4);
|
|
1065
|
+
const grayMatrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
|
|
1066
|
+
const customUniforms = [];
|
|
1067
|
+
const waterUniforms = new Array(11).fill(0);
|
|
1068
|
+
const fogUniforms = new Array(9).fill(0);
|
|
1069
|
+
const fireUniforms = new Array(11).fill(0);
|
|
1070
|
+
let currentFrameTime = 0;
|
|
1071
|
+
let current = null;
|
|
1072
|
+
let _boundRuntime = null;
|
|
1073
|
+
let _boundChain = null;
|
|
1074
|
+
const _loggedOnce = /* @__PURE__ */ new Set();
|
|
1075
|
+
function logOnce(msg) {
|
|
1076
|
+
if (_loggedOnce.has(msg)) return;
|
|
1077
|
+
_loggedOnce.add(msg);
|
|
1078
|
+
console.warn(`[postfx] ${msg}`);
|
|
1079
|
+
}
|
|
1080
|
+
const canvas = {
|
|
1081
|
+
save: () => current?.save() ?? 0,
|
|
1082
|
+
restore: () => {
|
|
1083
|
+
current?.restore();
|
|
1084
|
+
},
|
|
1085
|
+
translate: (x, y) => {
|
|
1086
|
+
current?.translate(x, y);
|
|
1087
|
+
},
|
|
1088
|
+
scale: (sx, sy) => {
|
|
1089
|
+
current?.scale(sx, sy);
|
|
1090
|
+
},
|
|
1091
|
+
rotate: (radians, cx, cy) => {
|
|
1092
|
+
current?.rotate(radians, cx, cy);
|
|
1093
|
+
},
|
|
1094
|
+
clear: (argb) => {
|
|
1095
|
+
if (current === null) return;
|
|
1096
|
+
clearColor[0] = (argb >>> 16 & 255) / 255;
|
|
1097
|
+
clearColor[1] = (argb >>> 8 & 255) / 255;
|
|
1098
|
+
clearColor[2] = (argb & 255) / 255;
|
|
1099
|
+
clearColor[3] = (argb >>> 24 & 255) / 255;
|
|
1100
|
+
current.clear(clearColor);
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1103
|
+
function ensurePoolCapacity(n) {
|
|
1104
|
+
while (srcRects.length < n) {
|
|
1105
|
+
srcRects.push(Skia.XYWHRect(0, 0, 0, 0));
|
|
1106
|
+
xforms.push(Skia.RSXform(1, 0, 0, 0));
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
function ensureStretchPoolCapacity(n) {
|
|
1110
|
+
while (stretchSrcRects.length < n) {
|
|
1111
|
+
stretchSrcRects.push(Skia.XYWHRect(0, 0, 0, 0));
|
|
1112
|
+
stretchDstRects.push(Skia.XYWHRect(0, 0, 0, 0));
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function ensureZoneBgPoolCapacity(n) {
|
|
1116
|
+
while (zoneBgRects.length < n) {
|
|
1117
|
+
zoneBgRects.push(Skia.XYWHRect(0, 0, 0, 0));
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
function getCachedSrcSlice(n) {
|
|
1121
|
+
if (_cachedSrcSlice !== null && _cachedSrcSliceLen === n) return _cachedSrcSlice;
|
|
1122
|
+
_cachedSrcSlice = srcRects.length === n ? srcRects : srcRects.slice(0, n);
|
|
1123
|
+
_cachedSrcSliceLen = n;
|
|
1124
|
+
return _cachedSrcSlice;
|
|
1125
|
+
}
|
|
1126
|
+
function getCachedXformSlice(n) {
|
|
1127
|
+
if (_cachedXformSlice !== null && _cachedXformSliceLen === n) return _cachedXformSlice;
|
|
1128
|
+
_cachedXformSlice = xforms.length === n ? xforms : xforms.slice(0, n);
|
|
1129
|
+
_cachedXformSliceLen = n;
|
|
1130
|
+
return _cachedXformSlice;
|
|
1131
|
+
}
|
|
1132
|
+
function fillSrcRects(commands, n) {
|
|
1133
|
+
for (let i = 0; i < n; i++) {
|
|
1134
|
+
const cmd = commands[i];
|
|
1135
|
+
srcRects[i]?.setXYWH(cmd.srcX, cmd.srcY, cmd.srcW, cmd.srcH);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
function fillXforms(commands, n, dx, dy) {
|
|
1139
|
+
for (let i = 0; i < n; i++) {
|
|
1140
|
+
const cmd = commands[i];
|
|
1141
|
+
const scale = cmd.srcW === 0 ? 1 : cmd.dstW / cmd.srcW;
|
|
1142
|
+
if (cmd.rotation === 0) {
|
|
1143
|
+
xforms[i]?.set(scale, 0, cmd.dstX + dx, cmd.dstY + dy);
|
|
1144
|
+
} else {
|
|
1145
|
+
const c = Math.cos(cmd.rotation);
|
|
1146
|
+
const s = Math.sin(cmd.rotation);
|
|
1147
|
+
const scos = scale * c;
|
|
1148
|
+
const ssin = scale * s;
|
|
1149
|
+
const px = cmd.dstX + cmd.anchorX * cmd.dstW + dx;
|
|
1150
|
+
const py = cmd.dstY + cmd.anchorY * cmd.dstH + dy;
|
|
1151
|
+
const axSrc = cmd.anchorX * cmd.srcW;
|
|
1152
|
+
const aySrc = cmd.anchorY * cmd.srcH;
|
|
1153
|
+
xforms[i]?.set(
|
|
1154
|
+
scos,
|
|
1155
|
+
ssin,
|
|
1156
|
+
px - scos * axSrc + ssin * aySrc,
|
|
1157
|
+
py - ssin * axSrc - scos * aySrc
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
function applyTint(effect) {
|
|
1163
|
+
if (tintPaint === null) tintPaint = Skia.Paint();
|
|
1164
|
+
writeColor(tintColor, effect.color, effect.amount);
|
|
1165
|
+
tintPaint.setColorFilter(Skia.ColorFilter.MakeBlend(tintColor, BLEND_SRC_OVER));
|
|
1166
|
+
return tintPaint;
|
|
1167
|
+
}
|
|
1168
|
+
function applyFlash(effect) {
|
|
1169
|
+
if (flashPaint === null) flashPaint = Skia.Paint();
|
|
1170
|
+
writeColor(flashColor, effect.color, flashIntensity(effect));
|
|
1171
|
+
flashPaint.setColorFilter(Skia.ColorFilter.MakeBlend(flashColor, BLEND_SRC_OVER));
|
|
1172
|
+
return flashPaint;
|
|
1173
|
+
}
|
|
1174
|
+
function applyGrayscale(effect) {
|
|
1175
|
+
if (grayscalePaint === null) grayscalePaint = Skia.Paint();
|
|
1176
|
+
writeGrayscaleMatrix(grayMatrix, effect.amount);
|
|
1177
|
+
grayscalePaint.setColorFilter(Skia.ColorFilter.MakeMatrix(grayMatrix));
|
|
1178
|
+
return grayscalePaint;
|
|
1179
|
+
}
|
|
1180
|
+
function applyOutlinePaint(effect) {
|
|
1181
|
+
if (outlinePaint === null) outlinePaint = Skia.Paint();
|
|
1182
|
+
writeColor(outlineColor, effect.color, 1);
|
|
1183
|
+
outlinePaint.setColorFilter(Skia.ColorFilter.MakeBlend(outlineColor, BLEND_SRC_IN));
|
|
1184
|
+
return outlinePaint;
|
|
1185
|
+
}
|
|
1186
|
+
function applyCustom(effect) {
|
|
1187
|
+
if (customPaint === null) customPaint = Skia.Paint();
|
|
1188
|
+
const shader = effect.shader;
|
|
1189
|
+
const floatCount = shader.getUniformFloatCount();
|
|
1190
|
+
while (customUniforms.length < floatCount) customUniforms.push(0);
|
|
1191
|
+
customUniforms.length = floatCount;
|
|
1192
|
+
fillCustomUniforms(effect, shader, customUniforms);
|
|
1193
|
+
customPaint.setShader(shader.makeShader(customUniforms));
|
|
1194
|
+
return customPaint;
|
|
1195
|
+
}
|
|
1196
|
+
function applyWater(effect, time) {
|
|
1197
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1198
|
+
if (waterRuntimeEffect === null) {
|
|
1199
|
+
const compiled = Skia.RuntimeEffect.Make(WATER_SKSL);
|
|
1200
|
+
if (compiled === null) return defaultPaint;
|
|
1201
|
+
waterRuntimeEffect = compiled;
|
|
1202
|
+
}
|
|
1203
|
+
if (waterPaint === null) waterPaint = Skia.Paint();
|
|
1204
|
+
waterUniforms[0] = 0;
|
|
1205
|
+
waterUniforms[1] = 0;
|
|
1206
|
+
waterUniforms[2] = effect.color.r;
|
|
1207
|
+
waterUniforms[3] = effect.color.g;
|
|
1208
|
+
waterUniforms[4] = effect.color.b;
|
|
1209
|
+
waterUniforms[5] = effect.foamColor.r;
|
|
1210
|
+
waterUniforms[6] = effect.foamColor.g;
|
|
1211
|
+
waterUniforms[7] = effect.foamColor.b;
|
|
1212
|
+
waterUniforms[8] = effect.waveSpeed;
|
|
1213
|
+
waterUniforms[9] = effect.waveAmplitude;
|
|
1214
|
+
waterUniforms[10] = time;
|
|
1215
|
+
waterPaint.setShader(waterRuntimeEffect.makeShader(waterUniforms));
|
|
1216
|
+
return waterPaint;
|
|
1217
|
+
}
|
|
1218
|
+
function applyFog(effect, time) {
|
|
1219
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1220
|
+
if (fogRuntimeEffect === null) {
|
|
1221
|
+
const compiled = Skia.RuntimeEffect.Make(FOG_SKSL);
|
|
1222
|
+
if (compiled === null) return defaultPaint;
|
|
1223
|
+
fogRuntimeEffect = compiled;
|
|
1224
|
+
}
|
|
1225
|
+
if (fogPaint === null) fogPaint = Skia.Paint();
|
|
1226
|
+
fogUniforms[0] = 0;
|
|
1227
|
+
fogUniforms[1] = 0;
|
|
1228
|
+
fogUniforms[2] = effect.color.r;
|
|
1229
|
+
fogUniforms[3] = effect.color.g;
|
|
1230
|
+
fogUniforms[4] = effect.color.b;
|
|
1231
|
+
fogUniforms[5] = effect.density;
|
|
1232
|
+
fogUniforms[6] = effect.speed;
|
|
1233
|
+
fogUniforms[7] = effect.scale;
|
|
1234
|
+
fogUniforms[8] = time;
|
|
1235
|
+
fogPaint.setShader(fogRuntimeEffect.makeShader(fogUniforms));
|
|
1236
|
+
return fogPaint;
|
|
1237
|
+
}
|
|
1238
|
+
function applyFire(effect, time) {
|
|
1239
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1240
|
+
if (fireRuntimeEffect === null) {
|
|
1241
|
+
const compiled = Skia.RuntimeEffect.Make(FIRE_SKSL);
|
|
1242
|
+
if (compiled === null) return defaultPaint;
|
|
1243
|
+
fireRuntimeEffect = compiled;
|
|
1244
|
+
}
|
|
1245
|
+
if (firePaint === null) firePaint = Skia.Paint();
|
|
1246
|
+
fireUniforms[0] = 0;
|
|
1247
|
+
fireUniforms[1] = 0;
|
|
1248
|
+
fireUniforms[2] = effect.color.r;
|
|
1249
|
+
fireUniforms[3] = effect.color.g;
|
|
1250
|
+
fireUniforms[4] = effect.color.b;
|
|
1251
|
+
fireUniforms[5] = effect.tipColor.r;
|
|
1252
|
+
fireUniforms[6] = effect.tipColor.g;
|
|
1253
|
+
fireUniforms[7] = effect.tipColor.b;
|
|
1254
|
+
fireUniforms[8] = effect.speed;
|
|
1255
|
+
fireUniforms[9] = effect.intensity;
|
|
1256
|
+
fireUniforms[10] = time;
|
|
1257
|
+
firePaint.setShader(fireRuntimeEffect.makeShader(fireUniforms));
|
|
1258
|
+
return firePaint;
|
|
1259
|
+
}
|
|
1260
|
+
function applyDropShadow(effect) {
|
|
1261
|
+
if (Skia.ImageFilter === void 0) return defaultPaint;
|
|
1262
|
+
if (dropShadowPaint === null) dropShadowPaint = Skia.Paint();
|
|
1263
|
+
writeColor(dropShadowColor, effect.color, 1);
|
|
1264
|
+
dropShadowPaint.setImageFilter(
|
|
1265
|
+
Skia.ImageFilter.MakeDropShadow(
|
|
1266
|
+
effect.offsetX,
|
|
1267
|
+
effect.offsetY,
|
|
1268
|
+
effect.blur,
|
|
1269
|
+
effect.blur,
|
|
1270
|
+
dropShadowColor,
|
|
1271
|
+
null
|
|
1272
|
+
)
|
|
1273
|
+
);
|
|
1274
|
+
return dropShadowPaint;
|
|
1275
|
+
}
|
|
1276
|
+
function applyRoofsCity(effect) {
|
|
1277
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1278
|
+
if (roofsCityEffect === null) {
|
|
1279
|
+
const compiled = Skia.RuntimeEffect.Make(ROOFS_CITY_SKSL);
|
|
1280
|
+
if (compiled === null) return defaultPaint;
|
|
1281
|
+
roofsCityEffect = compiled;
|
|
1282
|
+
}
|
|
1283
|
+
if (roofsCityPaint === null) roofsCityPaint = Skia.Paint();
|
|
1284
|
+
roofsCityUniforms[0] = effect.resolutionW;
|
|
1285
|
+
roofsCityUniforms[1] = effect.resolutionH;
|
|
1286
|
+
roofsCityUniforms[2] = effect.skyColor.r;
|
|
1287
|
+
roofsCityUniforms[3] = effect.skyColor.g;
|
|
1288
|
+
roofsCityUniforms[4] = effect.skyColor.b;
|
|
1289
|
+
roofsCityUniforms[5] = effect.roofColor.r;
|
|
1290
|
+
roofsCityUniforms[6] = effect.roofColor.g;
|
|
1291
|
+
roofsCityUniforms[7] = effect.roofColor.b;
|
|
1292
|
+
roofsCityUniforms[8] = effect.scrollOffsetY;
|
|
1293
|
+
roofsCityUniforms[9] = effect.density;
|
|
1294
|
+
roofsCityPaint.setShader(roofsCityEffect.makeShader(roofsCityUniforms));
|
|
1295
|
+
return roofsCityPaint;
|
|
1296
|
+
}
|
|
1297
|
+
function applyForestCanopy(effect) {
|
|
1298
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1299
|
+
if (forestCanopyEffect === null) {
|
|
1300
|
+
const compiled = Skia.RuntimeEffect.Make(FOREST_CANOPY_SKSL);
|
|
1301
|
+
if (compiled === null) return defaultPaint;
|
|
1302
|
+
forestCanopyEffect = compiled;
|
|
1303
|
+
}
|
|
1304
|
+
if (forestCanopyPaint === null) forestCanopyPaint = Skia.Paint();
|
|
1305
|
+
forestCanopyUniforms[0] = effect.resolutionW;
|
|
1306
|
+
forestCanopyUniforms[1] = effect.resolutionH;
|
|
1307
|
+
forestCanopyUniforms[2] = effect.skyColor.r;
|
|
1308
|
+
forestCanopyUniforms[3] = effect.skyColor.g;
|
|
1309
|
+
forestCanopyUniforms[4] = effect.skyColor.b;
|
|
1310
|
+
forestCanopyUniforms[5] = effect.leafColor.r;
|
|
1311
|
+
forestCanopyUniforms[6] = effect.leafColor.g;
|
|
1312
|
+
forestCanopyUniforms[7] = effect.leafColor.b;
|
|
1313
|
+
forestCanopyUniforms[8] = effect.scrollOffsetY;
|
|
1314
|
+
forestCanopyUniforms[9] = effect.density;
|
|
1315
|
+
forestCanopyPaint.setShader(forestCanopyEffect.makeShader(forestCanopyUniforms));
|
|
1316
|
+
return forestCanopyPaint;
|
|
1317
|
+
}
|
|
1318
|
+
function applyRiverWave(effect) {
|
|
1319
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1320
|
+
if (riverWaveEffect === null) {
|
|
1321
|
+
const compiled = Skia.RuntimeEffect.Make(RIVER_WAVE_SKSL);
|
|
1322
|
+
if (compiled === null) return defaultPaint;
|
|
1323
|
+
riverWaveEffect = compiled;
|
|
1324
|
+
}
|
|
1325
|
+
if (riverWavePaint === null) riverWavePaint = Skia.Paint();
|
|
1326
|
+
riverWaveUniforms[0] = effect.resolutionW;
|
|
1327
|
+
riverWaveUniforms[1] = effect.resolutionH;
|
|
1328
|
+
riverWaveUniforms[2] = effect.waterColor.r;
|
|
1329
|
+
riverWaveUniforms[3] = effect.waterColor.g;
|
|
1330
|
+
riverWaveUniforms[4] = effect.waterColor.b;
|
|
1331
|
+
riverWaveUniforms[5] = effect.foamColor.r;
|
|
1332
|
+
riverWaveUniforms[6] = effect.foamColor.g;
|
|
1333
|
+
riverWaveUniforms[7] = effect.foamColor.b;
|
|
1334
|
+
riverWaveUniforms[8] = effect.scrollOffsetY;
|
|
1335
|
+
riverWaveUniforms[9] = effect.waveScale;
|
|
1336
|
+
riverWavePaint.setShader(riverWaveEffect.makeShader(riverWaveUniforms));
|
|
1337
|
+
return riverWavePaint;
|
|
1338
|
+
}
|
|
1339
|
+
function applyMoonCrater(effect) {
|
|
1340
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1341
|
+
if (moonCraterEffect === null) {
|
|
1342
|
+
const compiled = Skia.RuntimeEffect.Make(MOON_CRATER_SKSL);
|
|
1343
|
+
if (compiled === null) return defaultPaint;
|
|
1344
|
+
moonCraterEffect = compiled;
|
|
1345
|
+
}
|
|
1346
|
+
if (moonCraterPaint === null) moonCraterPaint = Skia.Paint();
|
|
1347
|
+
moonCraterUniforms[0] = effect.resolutionW;
|
|
1348
|
+
moonCraterUniforms[1] = effect.resolutionH;
|
|
1349
|
+
moonCraterUniforms[2] = effect.moonColor.r;
|
|
1350
|
+
moonCraterUniforms[3] = effect.moonColor.g;
|
|
1351
|
+
moonCraterUniforms[4] = effect.moonColor.b;
|
|
1352
|
+
moonCraterUniforms[5] = effect.craterColor.r;
|
|
1353
|
+
moonCraterUniforms[6] = effect.craterColor.g;
|
|
1354
|
+
moonCraterUniforms[7] = effect.craterColor.b;
|
|
1355
|
+
moonCraterUniforms[8] = effect.scrollOffsetY;
|
|
1356
|
+
moonCraterUniforms[9] = effect.craterCount;
|
|
1357
|
+
moonCraterPaint.setShader(moonCraterEffect.makeShader(moonCraterUniforms));
|
|
1358
|
+
return moonCraterPaint;
|
|
1359
|
+
}
|
|
1360
|
+
function applyCaveInterior(effect) {
|
|
1361
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1362
|
+
if (caveInteriorEffect === null) {
|
|
1363
|
+
const compiled = Skia.RuntimeEffect.Make(CAVE_INTERIOR_SKSL);
|
|
1364
|
+
if (compiled === null) return defaultPaint;
|
|
1365
|
+
caveInteriorEffect = compiled;
|
|
1366
|
+
}
|
|
1367
|
+
if (caveInteriorPaint === null) caveInteriorPaint = Skia.Paint();
|
|
1368
|
+
caveInteriorUniforms[0] = effect.resolutionW;
|
|
1369
|
+
caveInteriorUniforms[1] = effect.resolutionH;
|
|
1370
|
+
caveInteriorUniforms[2] = effect.caveColor.r;
|
|
1371
|
+
caveInteriorUniforms[3] = effect.caveColor.g;
|
|
1372
|
+
caveInteriorUniforms[4] = effect.caveColor.b;
|
|
1373
|
+
caveInteriorUniforms[5] = effect.glowColor.r;
|
|
1374
|
+
caveInteriorUniforms[6] = effect.glowColor.g;
|
|
1375
|
+
caveInteriorUniforms[7] = effect.glowColor.b;
|
|
1376
|
+
caveInteriorUniforms[8] = effect.scrollOffsetY;
|
|
1377
|
+
caveInteriorUniforms[9] = effect.stalactiteCount;
|
|
1378
|
+
caveInteriorPaint.setShader(caveInteriorEffect.makeShader(caveInteriorUniforms));
|
|
1379
|
+
return caveInteriorPaint;
|
|
1380
|
+
}
|
|
1381
|
+
function applyMountainHills(effect) {
|
|
1382
|
+
if (Skia.RuntimeEffect === void 0) return defaultPaint;
|
|
1383
|
+
if (mountainHillsEffect === null) {
|
|
1384
|
+
const compiled = Skia.RuntimeEffect.Make(MOUNTAIN_HILLS_SKSL);
|
|
1385
|
+
if (compiled === null) return defaultPaint;
|
|
1386
|
+
mountainHillsEffect = compiled;
|
|
1387
|
+
}
|
|
1388
|
+
if (mountainHillsPaint === null) mountainHillsPaint = Skia.Paint();
|
|
1389
|
+
mountainHillsUniforms[0] = effect.resolutionW;
|
|
1390
|
+
mountainHillsUniforms[1] = effect.resolutionH;
|
|
1391
|
+
mountainHillsUniforms[2] = effect.skyColor.r;
|
|
1392
|
+
mountainHillsUniforms[3] = effect.skyColor.g;
|
|
1393
|
+
mountainHillsUniforms[4] = effect.skyColor.b;
|
|
1394
|
+
mountainHillsUniforms[5] = effect.hillColor.r;
|
|
1395
|
+
mountainHillsUniforms[6] = effect.hillColor.g;
|
|
1396
|
+
mountainHillsUniforms[7] = effect.hillColor.b;
|
|
1397
|
+
mountainHillsUniforms[8] = effect.scrollOffsetY;
|
|
1398
|
+
mountainHillsUniforms[9] = effect.ridgeScale;
|
|
1399
|
+
mountainHillsPaint.setShader(mountainHillsEffect.makeShader(mountainHillsUniforms));
|
|
1400
|
+
return mountainHillsPaint;
|
|
1401
|
+
}
|
|
1402
|
+
function drawOutlined(cvs, image, commands, n, effect, alpha) {
|
|
1403
|
+
const paint = applyOutlinePaint(effect);
|
|
1404
|
+
paint.setAlphaf(alpha);
|
|
1405
|
+
const srcs = getCachedSrcSlice(n);
|
|
1406
|
+
for (let k = 0; k < OUTLINE_OFFSETS.length; k++) {
|
|
1407
|
+
const offset = OUTLINE_OFFSETS[k];
|
|
1408
|
+
fillXforms(commands, n, offset[0] * effect.width, offset[1] * effect.width);
|
|
1409
|
+
const dsts = getCachedXformSlice(n);
|
|
1410
|
+
cvs.drawAtlas(image, srcs, dsts, paint);
|
|
1411
|
+
}
|
|
1412
|
+
paint.setAlphaf(1);
|
|
1413
|
+
defaultPaint.setAlphaf(alpha);
|
|
1414
|
+
fillXforms(commands, n, 0, 0);
|
|
1415
|
+
const mainDsts = getCachedXformSlice(n);
|
|
1416
|
+
cvs.drawAtlas(image, srcs, mainDsts, defaultPaint);
|
|
1417
|
+
defaultPaint.setAlphaf(1);
|
|
1418
|
+
}
|
|
1419
|
+
function resolveEffectPaint(effect) {
|
|
1420
|
+
switch (effect.type) {
|
|
1421
|
+
case "tint":
|
|
1422
|
+
return applyTint(effect);
|
|
1423
|
+
case "flash":
|
|
1424
|
+
return applyFlash(effect);
|
|
1425
|
+
case "grayscale":
|
|
1426
|
+
return applyGrayscale(effect);
|
|
1427
|
+
case "custom":
|
|
1428
|
+
return applyCustom(effect);
|
|
1429
|
+
case "water":
|
|
1430
|
+
return applyWater(effect, currentFrameTime);
|
|
1431
|
+
case "fog":
|
|
1432
|
+
return applyFog(effect, currentFrameTime);
|
|
1433
|
+
case "fire":
|
|
1434
|
+
return applyFire(effect, currentFrameTime);
|
|
1435
|
+
case "drop-shadow":
|
|
1436
|
+
return applyDropShadow(effect);
|
|
1437
|
+
case "outline":
|
|
1438
|
+
return applyOutlinePaint(effect);
|
|
1439
|
+
case "roofs-city":
|
|
1440
|
+
return applyRoofsCity(effect);
|
|
1441
|
+
case "forest-canopy":
|
|
1442
|
+
return applyForestCanopy(effect);
|
|
1443
|
+
case "river-wave":
|
|
1444
|
+
return applyRiverWave(effect);
|
|
1445
|
+
case "moon-crater":
|
|
1446
|
+
return applyMoonCrater(effect);
|
|
1447
|
+
case "cave-interior":
|
|
1448
|
+
return applyCaveInterior(effect);
|
|
1449
|
+
case "mountain-hills":
|
|
1450
|
+
return applyMountainHills(effect);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
return {
|
|
1454
|
+
canvas,
|
|
1455
|
+
beginFrame(viewportWidth, viewportHeight, time = 0, pixelDensity = 1) {
|
|
1456
|
+
if (viewportWidth === 0 || viewportHeight === 0) return;
|
|
1457
|
+
_boundRuntime = null;
|
|
1458
|
+
_boundChain = null;
|
|
1459
|
+
currentFrameTime = time;
|
|
1460
|
+
const pd = pixelDensity;
|
|
1461
|
+
recordingBounds.setXYWH(0, 0, viewportWidth * pd, viewportHeight * pd);
|
|
1462
|
+
current = recorder.beginRecording(recordingBounds);
|
|
1463
|
+
if (pd !== 1) current.scale(pd, pd);
|
|
1464
|
+
},
|
|
1465
|
+
drawAtlas(image, commands) {
|
|
1466
|
+
if (current === null) return;
|
|
1467
|
+
const n = commands.length;
|
|
1468
|
+
if (n === 0) return;
|
|
1469
|
+
const effect = commands[0]?.effect;
|
|
1470
|
+
const alpha = commands[0]?.alpha ?? 1;
|
|
1471
|
+
if (effect?.type === "roofs-city" || effect?.type === "forest-canopy" || effect?.type === "river-wave" || effect?.type === "moon-crater" || effect?.type === "cave-interior" || effect?.type === "mountain-hills") {
|
|
1472
|
+
const paint2 = resolveEffectPaint(effect);
|
|
1473
|
+
paint2.setAlphaf(alpha);
|
|
1474
|
+
ensureZoneBgPoolCapacity(n);
|
|
1475
|
+
for (let i = 0; i < n; i++) {
|
|
1476
|
+
const cmd = commands[i];
|
|
1477
|
+
zoneBgRects[i].setXYWH(cmd.dstX, cmd.dstY, cmd.dstW, cmd.dstH);
|
|
1478
|
+
current.drawRect(zoneBgRects[i], paint2);
|
|
1479
|
+
}
|
|
1480
|
+
paint2.setAlphaf(1);
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
if (commands[0]?.stretch) {
|
|
1484
|
+
if (stretchPaint === null) stretchPaint = Skia.Paint();
|
|
1485
|
+
ensureStretchPoolCapacity(n);
|
|
1486
|
+
stretchPaint.setAlphaf(alpha);
|
|
1487
|
+
for (let i = 0; i < n; i++) {
|
|
1488
|
+
const cmd = commands[i];
|
|
1489
|
+
const srcR = stretchSrcRects[i];
|
|
1490
|
+
const dstR = stretchDstRects[i];
|
|
1491
|
+
srcR.setXYWH(cmd.srcX, cmd.srcY, cmd.srcW, cmd.srcH);
|
|
1492
|
+
dstR.setXYWH(cmd.dstX, cmd.dstY, cmd.dstW, cmd.dstH);
|
|
1493
|
+
current.drawImageRect(image, srcR, dstR, stretchPaint);
|
|
1494
|
+
}
|
|
1495
|
+
stretchPaint.setAlphaf(1);
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
ensurePoolCapacity(n);
|
|
1499
|
+
fillSrcRects(commands, n);
|
|
1500
|
+
if (effect?.type === "outline") {
|
|
1501
|
+
drawOutlined(current, image, commands, n, effect, alpha);
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
fillXforms(commands, n, 0, 0);
|
|
1505
|
+
const srcs = getCachedSrcSlice(n);
|
|
1506
|
+
const dsts = getCachedXformSlice(n);
|
|
1507
|
+
const paint = effect === void 0 ? defaultPaint : resolveEffectPaint(effect);
|
|
1508
|
+
paint.setAlphaf(alpha);
|
|
1509
|
+
current.drawAtlas(image, srcs, dsts, paint);
|
|
1510
|
+
paint.setAlphaf(1);
|
|
1511
|
+
},
|
|
1512
|
+
setPostFxBinding(runtime, chain) {
|
|
1513
|
+
_boundRuntime = runtime;
|
|
1514
|
+
_boundChain = chain;
|
|
1515
|
+
},
|
|
1516
|
+
buildPostFxPasses(runtime, chain, width, height) {
|
|
1517
|
+
const rt = runtime ?? _boundRuntime;
|
|
1518
|
+
const ch = chain ?? _boundChain;
|
|
1519
|
+
if (rt === null || !rt.supported) return [];
|
|
1520
|
+
if (rt.buildPass === void 0) {
|
|
1521
|
+
logOnce("buildPostFxPasses: runtime.supported but buildPass absent \u2014 no passes");
|
|
1522
|
+
return [];
|
|
1523
|
+
}
|
|
1524
|
+
if (ch === null) return [];
|
|
1525
|
+
const passes = rt.buildPass(ch, width, height);
|
|
1526
|
+
if (passes.length === 0) return [];
|
|
1527
|
+
const out = [];
|
|
1528
|
+
for (const pass of passes) {
|
|
1529
|
+
const shader = pass.shader;
|
|
1530
|
+
const uniformCount = typeof shader.getUniformCount === "function" ? shader.getUniformCount() : 0;
|
|
1531
|
+
const uniforms = {};
|
|
1532
|
+
for (let i = 0; i < uniformCount; i++) {
|
|
1533
|
+
const name = typeof shader.getUniformName === "function" ? shader.getUniformName(i) : String(i);
|
|
1534
|
+
const info = typeof shader.getUniform === "function" ? shader.getUniform(i) : { columns: 1, rows: 1, slot: i };
|
|
1535
|
+
const size = info.columns * info.rows;
|
|
1536
|
+
if (size === 1) {
|
|
1537
|
+
uniforms[name] = pass.uniforms[info.slot] ?? 0;
|
|
1538
|
+
} else {
|
|
1539
|
+
const vec = [];
|
|
1540
|
+
for (let k = 0; k < size; k++) {
|
|
1541
|
+
vec.push(pass.uniforms[info.slot + k] ?? 0);
|
|
1542
|
+
}
|
|
1543
|
+
uniforms[name] = vec;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
out.push({
|
|
1547
|
+
id: pass.id,
|
|
1548
|
+
source: shader,
|
|
1549
|
+
uniforms,
|
|
1550
|
+
children: pass.children
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
return out;
|
|
1554
|
+
},
|
|
1555
|
+
endFrame() {
|
|
1556
|
+
if (current === null) return null;
|
|
1557
|
+
current = null;
|
|
1558
|
+
return recorder.finishRecordingAsPicture();
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
function writeColor(out, color, alphaMul) {
|
|
1563
|
+
out[0] = color.r;
|
|
1564
|
+
out[1] = color.g;
|
|
1565
|
+
out[2] = color.b;
|
|
1566
|
+
out[3] = color.a * alphaMul;
|
|
1567
|
+
}
|
|
1568
|
+
function writeGrayscaleMatrix(out, amount) {
|
|
1569
|
+
const inv = 1 - amount;
|
|
1570
|
+
const lr = 0.299 * amount;
|
|
1571
|
+
const lg = 0.587 * amount;
|
|
1572
|
+
const lb = 0.114 * amount;
|
|
1573
|
+
out[0] = inv + lr;
|
|
1574
|
+
out[1] = lg;
|
|
1575
|
+
out[2] = lb;
|
|
1576
|
+
out[3] = 0;
|
|
1577
|
+
out[4] = 0;
|
|
1578
|
+
out[5] = lr;
|
|
1579
|
+
out[6] = inv + lg;
|
|
1580
|
+
out[7] = lb;
|
|
1581
|
+
out[8] = 0;
|
|
1582
|
+
out[9] = 0;
|
|
1583
|
+
out[10] = lr;
|
|
1584
|
+
out[11] = lg;
|
|
1585
|
+
out[12] = inv + lb;
|
|
1586
|
+
out[13] = 0;
|
|
1587
|
+
out[14] = 0;
|
|
1588
|
+
out[15] = 0;
|
|
1589
|
+
out[16] = 0;
|
|
1590
|
+
out[17] = 0;
|
|
1591
|
+
out[18] = 1;
|
|
1592
|
+
out[19] = 0;
|
|
1593
|
+
}
|
|
1594
|
+
function fillCustomUniforms(effect, shader, out) {
|
|
1595
|
+
const count = shader.getUniformCount();
|
|
1596
|
+
for (let i = 0; i < out.length; i++) out[i] = 0;
|
|
1597
|
+
for (let i = 0; i < count; i++) {
|
|
1598
|
+
const info = shader.getUniform(i);
|
|
1599
|
+
const name = shader.getUniformName(i);
|
|
1600
|
+
const value = effect.uniforms[name];
|
|
1601
|
+
const size = info.columns * info.rows;
|
|
1602
|
+
if (value === void 0) continue;
|
|
1603
|
+
if (typeof value === "number") {
|
|
1604
|
+
out[info.slot] = value;
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1607
|
+
for (let k = 0; k < size; k++) {
|
|
1608
|
+
out[info.slot + k] = value[k] ?? 0;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
|
|
992
1613
|
// src/sprite-font.ts
|
|
993
1614
|
function parseBMFontJSON(json) {
|
|
994
1615
|
const data = json;
|
|
@@ -1128,10 +1749,12 @@ var Sprite = (0, import_ecs.defineComponent)("Sprite", () => ({
|
|
|
1128
1749
|
SpriteBatch,
|
|
1129
1750
|
WATER_SKSL,
|
|
1130
1751
|
caveInterior,
|
|
1752
|
+
createFrameRenderer,
|
|
1131
1753
|
createRenderSystem,
|
|
1132
1754
|
custom,
|
|
1133
1755
|
drawOrderCompare,
|
|
1134
1756
|
drawText,
|
|
1757
|
+
dropShadow,
|
|
1135
1758
|
fire,
|
|
1136
1759
|
flash,
|
|
1137
1760
|
flashIntensity,
|