mirror of
https://gitgud.io/BondageProjects/Bondage-College.git
synced 2025-04-25 17:59:34 +00:00
Merge branch 'extreme_corset' into 'master'
Improve graphics for extreme corset See merge request BondageProjects/Bondage-College!5528
This commit is contained in:
commit
8463daae4b
16 changed files with 58 additions and 46 deletions
BondageClub
Assets/Female3DCG
Female3DCG.jsFemale3DCG_Types.d.ts
ItemTorso
ExtremeCorset_Large_BodyMask.pngExtremeCorset_Large_Highlights.pngExtremeCorset_Normal_BodyMask.pngExtremeCorset_Normal_Highlights.pngExtremeCorset_Small_BodyMask.pngExtremeCorset_Small_Highlights.pngExtremeCorset_XLarge_BodyMask.pngExtremeCorset_XLarge_Highlights.png
LayerNames.csvScreens/Character/Appearance
Scripts
|
@ -8058,9 +8058,10 @@ var AssetFemale3DCG = [
|
|||
Hogtied: PoseType.HIDE,
|
||||
AllFours: PoseType.HIDE,
|
||||
},
|
||||
DefaultColor: ["#545454", "#BC8B84"],
|
||||
DefaultColor: ["#545454", "#EEEEEE", "#BC8B84"],
|
||||
Layer: [
|
||||
{ Name: "Main" },
|
||||
{ Name: "Highlights" },
|
||||
{ Name: "Buckles" },
|
||||
{
|
||||
Name: "BodyMask",
|
||||
|
@ -28729,9 +28730,10 @@ var AssetFemale3DCG = [
|
|||
Hogtied: PoseType.HIDE,
|
||||
AllFours: PoseType.HIDE,
|
||||
},
|
||||
DefaultColor: ["#545454", "#BC8B84"],
|
||||
DefaultColor: ["#545454", "#EEEEEE", "#BC8B84"],
|
||||
Layer: [
|
||||
{ Name: "Main" },
|
||||
{ Name: "Highlights" },
|
||||
{ Name: "Buckles" },
|
||||
{
|
||||
Name: "BodyMask",
|
||||
|
@ -30143,9 +30145,10 @@ var AssetFemale3DCG = [
|
|||
Hogtied: PoseType.HIDE,
|
||||
AllFours: PoseType.HIDE,
|
||||
},
|
||||
DefaultColor: ["#545454", "#BC8B84"],
|
||||
DefaultColor: ["#545454", "#EEEEEE", "#BC8B84"],
|
||||
Layer: [
|
||||
{ Name: "Main" },
|
||||
{ Name: "Highlights" },
|
||||
{ Name: "Buckles" },
|
||||
{
|
||||
Name: "BodyMask",
|
||||
|
|
|
@ -809,6 +809,8 @@ type AssetDefinition = (
|
|||
interface AssetLayerMaskTexureDefinition {
|
||||
/** The groups that will be affected */
|
||||
Groups: AssetGroupName[];
|
||||
/** If true, the texture mask will apply to all layers in the groups specified, event if their priority is higher than the mask layer */
|
||||
ApplyToAbove?: boolean;
|
||||
}
|
||||
|
||||
interface AssetLayerDefinition extends AssetCommonPropertiesGroupAssetLayer, AssetCommonPropertiesAssetLayer {
|
||||
|
|
Binary file not shown.
Before ![]() (image error) Size: 2.9 KiB After ![]() (image error) Size: 4.2 KiB ![]() ![]() |
Binary file not shown.
After ![]() (image error) Size: 15 KiB |
Binary file not shown.
Before ![]() (image error) Size: 3 KiB After ![]() (image error) Size: 4.1 KiB ![]() ![]() |
Binary file not shown.
After ![]() (image error) Size: 15 KiB |
Binary file not shown.
Before ![]() (image error) Size: 3.1 KiB After ![]() (image error) Size: 3.9 KiB ![]() ![]() |
Binary file not shown.
After ![]() (image error) Size: 14 KiB |
Binary file not shown.
Before ![]() (image error) Size: 2.9 KiB After ![]() (image error) Size: 4 KiB ![]() ![]() |
Binary file not shown.
After ![]() (image error) Size: 16 KiB |
|
@ -2368,6 +2368,7 @@ ItemTorsoThinLeatherStrapsStrap,Straps
|
|||
ItemTorsoShinyLeotardLockLatex,Base
|
||||
ItemTorsoShinyLeotardLockShine,Shine
|
||||
ItemTorsoExtremeCorsetMain,Main
|
||||
ItemTorsoExtremeCorsetHighlights,Highlights
|
||||
ItemTorsoExtremeCorsetBuckles,Buckles
|
||||
ItemVulvaBasicCockringCockRing,Cock Ring
|
||||
ItemVulvaBasicCockringPenis,Penis
|
||||
|
|
|
|
@ -483,7 +483,7 @@ function CharacterAppearanceSortLayers(C) {
|
|||
/**
|
||||
* Builds a map of all mask layers in a character's appearance, grouped by the asset groups they affect.
|
||||
* Only includes mask layers from visible assets that aren't blocked and are allowed in the current chat room.
|
||||
*
|
||||
*
|
||||
* @param {Character} C - The character whose masks should be built
|
||||
* @returns {AssetLayer[]} A map of group names to arrays of mask layers that affect them
|
||||
*/
|
||||
|
|
|
@ -69,8 +69,8 @@ function CommonDrawAppearancePrepareMaskLayers(C) {
|
|||
let blendingMode = "destination-in";
|
||||
if(layer.BlendingMode === "destination-in" || layer.BlendingMode === "destination-out") {
|
||||
blendingMode = layer.BlendingMode;
|
||||
}
|
||||
else if(!!layer.BlendingMode) return acc;
|
||||
}
|
||||
else if(layer.BlendingMode) return acc;
|
||||
|
||||
// Safeguard against a null pose
|
||||
if (typeof pose !== "string") pose = /** @type {AssetPoseName} */("");
|
||||
|
@ -95,11 +95,14 @@ function CommonDrawAppearancePrepareMaskLayers(C) {
|
|||
const urlParts = [asset.Name, parentAssetName, layerType, layerSegment].filter(c => c);
|
||||
const layerURL = urlParts.join("_") + ".png";
|
||||
|
||||
const maskPriority = layer.TextureMask.ApplyToAbove ? -1 : (item.Property?.OverridePriority?.[layer.Name] ?? layer.Priority);
|
||||
|
||||
/** @type {TextureAlphaMask} */
|
||||
const maskLayer = {
|
||||
Url: baseURL + layerURL,
|
||||
X, Y,
|
||||
Mode: blendingMode,
|
||||
Priority: maskPriority,
|
||||
};
|
||||
|
||||
/** @type {TextureAlphaMask} */
|
||||
|
@ -107,6 +110,7 @@ function CommonDrawAppearancePrepareMaskLayers(C) {
|
|||
Url: baseURLBlink + layerURL,
|
||||
X, Y,
|
||||
Mode: blendingMode,
|
||||
Priority: maskPriority,
|
||||
};
|
||||
|
||||
for(const maskedGroup of layer.TextureMask.Groups) {
|
||||
|
@ -341,8 +345,8 @@ function CommonDrawAppearanceBuild(C, {
|
|||
|
||||
|
||||
// prepare mask layers for the current group
|
||||
const maskLayer = maskTexLayers.get(groupName) ?? [];
|
||||
const maskLayerBlink = maskTexLayersBlink.get(groupName) ?? [];
|
||||
const maskLayer = (maskTexLayers.get(group.Name) ?? []).filter(m => m.Priority < 0 || m.Priority >= layer.Priority);
|
||||
const maskLayerBlink = (maskTexLayersBlink.get(group.Name) ?? []).filter(m => m.Priority < 0 || m.Priority >= layer.Priority);
|
||||
|
||||
if (shouldColorize) {
|
||||
drawImageColorize(
|
||||
|
|
|
@ -585,10 +585,10 @@ function DrawImage(Source, X, Y, Invert) {
|
|||
|
||||
/**
|
||||
* Applies texture masks to a canvas about to be drawn
|
||||
* @param {CanvasRenderingContext2D} destCanvas
|
||||
* @param {CanvasRenderingContext2D} destCanvas
|
||||
* @param {number} X - Position of the image on the X axis
|
||||
* @param {number} Y - Position of the image on the Y axis
|
||||
* @param {readonly TextureAlphaMask[]} TextureAlphaMasks
|
||||
* @param {readonly TextureAlphaMask[]} TextureAlphaMasks
|
||||
*/
|
||||
function DrawApplyTextureAlphaMask(destCanvas, X, Y, TextureAlphaMasks) {
|
||||
const key = "TexMask:" + JSON.stringify({
|
||||
|
|
|
@ -363,18 +363,18 @@ var GLDrawFragmentShaderSourceHalfAlpha = `
|
|||
uniform vec4 u_color;
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture2D(u_texture, v_texcoord);
|
||||
vec4 alphaColor = texture2D(u_alpha_texture, v_texcoord);
|
||||
vec4 texColor = texture2D(u_texture, v_texcoord);
|
||||
vec4 alphaColor = texture2D(u_alpha_texture, v_texcoord);
|
||||
vec4 maskColor = texture2D(u_mask_texture, v_texcoord);
|
||||
if (texColor.w < ` + GLDrawAlphaThreshold + `) discard;
|
||||
if (alphaColor.w < ` + GLDrawAlphaThreshold + `) discard;
|
||||
if (maskColor.w < ` + GLDrawAlphaThreshold + `) discard;
|
||||
float t = (texColor.x + texColor.y + texColor.z) / 383.0;
|
||||
if (t < ` + GLDrawHalfAlphaLow + ` || t > ` + GLDrawHalfAlphaHigh + `) {
|
||||
gl_FragColor = texColor;
|
||||
} else {
|
||||
gl_FragColor = u_color * vec4(t, t, t, texColor.w);
|
||||
}
|
||||
if (texColor.w < ` + GLDrawAlphaThreshold + `) discard;
|
||||
if (alphaColor.w < ` + GLDrawAlphaThreshold + `) discard;
|
||||
if (maskColor.w < ` + GLDrawAlphaThreshold + `) discard;
|
||||
float t = (texColor.x + texColor.y + texColor.z) / 383.0;
|
||||
if (t < ` + GLDrawHalfAlphaLow + ` || t > ` + GLDrawHalfAlphaHigh + `) {
|
||||
gl_FragColor = texColor;
|
||||
} else {
|
||||
gl_FragColor = u_color * vec4(t, t, t, texColor.w);
|
||||
}
|
||||
gl_FragColor.a *= maskColor.w;
|
||||
}
|
||||
`;
|
||||
|
@ -675,23 +675,23 @@ function GLDrawLoadMask(gl, texWidth, texHeight, offsetX, offsetY, alphaMasks) {
|
|||
* @returns {WebGLTexture} - A default mask texture
|
||||
*/
|
||||
function GLDrawCreateEmptyTextureAlphaMask(gl, texWidth, texHeight) {
|
||||
const key = "EmptyTexMask:" + texWidth + "x" + texHeight;
|
||||
let mask = gl.maskCache.get(key);
|
||||
|
||||
if (!mask) {
|
||||
// Create a white 1x1 texture (fully visible)
|
||||
const data = new Uint8Array([255, 255, 255, 255]);
|
||||
mask = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, mask);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
|
||||
gl.maskCache.set(key, mask);
|
||||
}
|
||||
|
||||
return mask;
|
||||
const key = "EmptyTexMask:" + texWidth + "x" + texHeight;
|
||||
let mask = gl.maskCache.get(key);
|
||||
|
||||
if (!mask) {
|
||||
// Create a white 1x1 texture (fully visible)
|
||||
const data = new Uint8Array([255, 255, 255, 255]);
|
||||
mask = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, mask);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
|
||||
gl.maskCache.set(key, mask);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
function canvasToNewWin(canvas) {
|
||||
|
@ -708,7 +708,7 @@ function canvasToNewWin(canvas) {
|
|||
|
||||
/**
|
||||
* Loads mask layers and combines them into a single texture mask
|
||||
* @param {WebGL2RenderingContext} gl
|
||||
* @param {WebGL2RenderingContext} gl
|
||||
* @param {number} texWidth - The width of the texture
|
||||
* @param {number} texHeight - The height of the texture
|
||||
* @param {number} offsetX - The X offset for the texture
|
||||
|
@ -718,7 +718,7 @@ function canvasToNewWin(canvas) {
|
|||
*/
|
||||
function GLDrawLoadTextureAlphaMask(gl, texWidth, texHeight, offsetX, offsetY, maskLayers) {
|
||||
// If no mask layers, return empty texture or null
|
||||
if (!maskLayers || maskLayers.length === 0
|
||||
if (!maskLayers || maskLayers.length === 0
|
||||
// placeholder texures
|
||||
|| (texWidth === 1 && texHeight === 1)) {
|
||||
return GLDrawCreateEmptyTextureAlphaMask(gl, texWidth, texHeight);
|
||||
|
@ -738,11 +738,11 @@ function GLDrawLoadTextureAlphaMask(gl, texWidth, texHeight, offsetX, offsetY, m
|
|||
const ctx = tmpCanvas.getContext("2d");
|
||||
ctx.fillStyle = "rgb(0,0,0)";
|
||||
ctx.fillRect(0, 0, texWidth, texHeight);
|
||||
|
||||
// Process and draw each mask layer
|
||||
|
||||
// Process and draw each mask layer
|
||||
// Combining textures is just too heavy for this scenario
|
||||
// so a canvas ctx is used to combine them
|
||||
for (const layer of maskLayers) {
|
||||
for (const layer of maskLayers) {
|
||||
GLDrawLoadImage(gl, layer.Url);
|
||||
const img = GLDrawImageCache.get(layer.Url);
|
||||
if(img.width === 0 || img.height === 0) {
|
||||
|
@ -751,7 +751,7 @@ function GLDrawLoadTextureAlphaMask(gl, texWidth, texHeight, offsetX, offsetY, m
|
|||
|
||||
ctx.globalCompositeOperation = layer.Mode || "destination-in";
|
||||
ctx.drawImage(img, layer.X - offsetX, layer.Y - offsetY, img.width, img.height);
|
||||
}
|
||||
}
|
||||
|
||||
mask = gl.createTexture();
|
||||
|
||||
|
@ -761,8 +761,8 @@ function GLDrawLoadTextureAlphaMask(gl, texWidth, texHeight, offsetX, offsetY, m
|
|||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tmpCanvas);
|
||||
|
||||
// Cache the generated mask
|
||||
gl.maskCache.set(key, mask);
|
||||
// Cache the generated mask
|
||||
gl.maskCache.set(key, mask);
|
||||
}
|
||||
|
||||
return mask;
|
||||
|
|
2
BondageClub/Scripts/Typedef.d.ts
vendored
2
BondageClub/Scripts/Typedef.d.ts
vendored
|
@ -3855,6 +3855,8 @@ interface TextureAlphaMask {
|
|||
Y: number;
|
||||
Url: string;
|
||||
Mode: "destination-in" | "destination-out";
|
||||
/** The priority of the mask, -1 means it will ignores priority and applied to the layers on top of it */
|
||||
Priority: number;
|
||||
}
|
||||
|
||||
/** Options available to most draw calls */
|
||||
|
|
Loading…
Add table
Reference in a new issue