Fixed alpha factor on solid materials

This commit is contained in:
Lucas Dower 2022-11-13 00:45:03 +00:00
parent a34734265e
commit 74a2964808
No known key found for this signature in database
GPG Key ID: B3EE6B8499593605
6 changed files with 175 additions and 20 deletions

View File

@ -4,6 +4,88 @@ uniform vec4 u_fillColour;
varying float v_lighting;
float dither8x8(vec2 position, float alpha) {
int x = int(mod(position.x, 8.0));
int y = int(mod(position.y, 8.0));
int index = x + y * 8;
float limit = 0.0;
if (x < 8) {
if (index == 0) limit = 0.015625;
if (index == 1) limit = 0.515625;
if (index == 2) limit = 0.140625;
if (index == 3) limit = 0.640625;
if (index == 4) limit = 0.046875;
if (index == 5) limit = 0.546875;
if (index == 6) limit = 0.171875;
if (index == 7) limit = 0.671875;
if (index == 8) limit = 0.765625;
if (index == 9) limit = 0.265625;
if (index == 10) limit = 0.890625;
if (index == 11) limit = 0.390625;
if (index == 12) limit = 0.796875;
if (index == 13) limit = 0.296875;
if (index == 14) limit = 0.921875;
if (index == 15) limit = 0.421875;
if (index == 16) limit = 0.203125;
if (index == 17) limit = 0.703125;
if (index == 18) limit = 0.078125;
if (index == 19) limit = 0.578125;
if (index == 20) limit = 0.234375;
if (index == 21) limit = 0.734375;
if (index == 22) limit = 0.109375;
if (index == 23) limit = 0.609375;
if (index == 24) limit = 0.953125;
if (index == 25) limit = 0.453125;
if (index == 26) limit = 0.828125;
if (index == 27) limit = 0.328125;
if (index == 28) limit = 0.984375;
if (index == 29) limit = 0.484375;
if (index == 30) limit = 0.859375;
if (index == 31) limit = 0.359375;
if (index == 32) limit = 0.0625;
if (index == 33) limit = 0.5625;
if (index == 34) limit = 0.1875;
if (index == 35) limit = 0.6875;
if (index == 36) limit = 0.03125;
if (index == 37) limit = 0.53125;
if (index == 38) limit = 0.15625;
if (index == 39) limit = 0.65625;
if (index == 40) limit = 0.8125;
if (index == 41) limit = 0.3125;
if (index == 42) limit = 0.9375;
if (index == 43) limit = 0.4375;
if (index == 44) limit = 0.78125;
if (index == 45) limit = 0.28125;
if (index == 46) limit = 0.90625;
if (index == 47) limit = 0.40625;
if (index == 48) limit = 0.25;
if (index == 49) limit = 0.75;
if (index == 50) limit = 0.125;
if (index == 51) limit = 0.625;
if (index == 52) limit = 0.21875;
if (index == 53) limit = 0.71875;
if (index == 54) limit = 0.09375;
if (index == 55) limit = 0.59375;
if (index == 56) limit = 1.0;
if (index == 57) limit = 0.5;
if (index == 58) limit = 0.875;
if (index == 59) limit = 0.375;
if (index == 60) limit = 0.96875;
if (index == 61) limit = 0.46875;
if (index == 62) limit = 0.84375;
if (index == 63) limit = 0.34375;
}
return alpha < limit ? 0.0 : 1.0;
}
void main() {
float alpha = dither8x8(gl_FragCoord.xy, u_fillColour.a);
if (alpha < 0.5)
{
discard;
}
gl_FragColor = vec4(u_fillColour.rgb * v_lighting, u_fillColour.a);
}

View File

@ -403,7 +403,12 @@ export class ObjImporter extends IImporter {
} else {
this._materials[this._currentMaterialName] = {
type: MaterialType.solid,
colour: this._currentColour,
colour: {
r: this._currentColour.r,
g: this._currentColour.g,
b: this._currentColour.b,
a: this._currentAlpha,
},
edited: false,
canBeTextured: false,
};

View File

@ -150,7 +150,9 @@ export class Mesh {
throw new AppError('Loaded mesh has no materials');
}
// Check used materials exist
const usedMaterials = new Set<string>();
const missingMaterials = new Set<string>();
for (const tri of this._tris) {
if (!(tri.material in this._materials)) {
@ -178,7 +180,21 @@ export class Mesh {
missingMaterials.add(tri.material);
}
usedMaterials.add(tri.material);
}
const materialsToRemove = new Set<string>();
for (const materialName in this._materials) {
if (!usedMaterials.has(materialName)) {
LOG_WARN(`'${materialName}' is not used by any triangles, removing...`);
materialsToRemove.add(materialName);
}
}
materialsToRemove.forEach((materialName) => {
delete this._materials[materialName];
});
if (missingMaterials.size > 0) {
LOG_WARN('Triangles use these materials but they were not found', missingMaterials);
}

View File

@ -5,17 +5,20 @@ import { AppContext } from '../../app_context';
import { RGBAUtil } from '../../colour';
import { SolidMaterial, TexturedMaterial } from '../../mesh';
import { getRandomID } from '../../util';
import { ASSERT } from '../../util/error_util';
import { FileUtil } from '../../util/file_util';
export abstract class MaterialUIElement {
protected readonly _materialName: string;
protected readonly _appContext: AppContext;
private _actions: { text: string, onClick: () => void, id: string }[];
private _metadata: string[];
public constructor(materialName: string, appContext: AppContext) {
this._materialName = materialName;
this._appContext = appContext;
this._actions = [];
this._metadata = [];
}
public hasWarning() {
@ -23,10 +26,15 @@ export abstract class MaterialUIElement {
}
public buildHTML(): string {
let html = this.buildChildHTML();
let html = `<div class="material-container">`;
html += this.buildChildHTML();
this._metadata.forEach((data) => {
html += `<br>${data}`;
});
this._actions.forEach((action) => {
html += `<br><a id="${action.id}">[${action.text}]</a>`;
});
html += `</div>`;
return html;
}
@ -45,17 +53,23 @@ export abstract class MaterialUIElement {
this._actions.push({ text: text, onClick: onClick, id: getRandomID() });
}
public addMetadata(text: string) {
this._metadata.push(text);
}
protected abstract buildChildHTML(): string
}
export class TextureMaterialUIElement extends MaterialUIElement {
private _material: TexturedMaterial;
private _imageId: string;
private _diffuseImageId: string;
private _alphaImageId: string;
public constructor(materialName: string, appContext: AppContext, material: TexturedMaterial) {
super(materialName, appContext);
this._material = material;
this._imageId = getRandomID();
this._diffuseImageId = getRandomID();
this._alphaImageId = getRandomID();
const parsedPath = path.parse(material.path);
const isMissingTexture = parsedPath.base === 'debug.png';
@ -77,6 +91,11 @@ export class TextureMaterialUIElement extends MaterialUIElement {
super.addAction('Switch to colour', () => {
this._appContext.onMaterialTypeSwitched(materialName);
});
super.addMetadata(`Alpha multiplier: ${this._material.alphaFactor}`);
if (this._material.alphaPath !== undefined) {
super.addMetadata(`Alpha texture: ${this._material.alphaPath}`);
}
}
private _isMissingTexture() {
@ -90,26 +109,51 @@ export class TextureMaterialUIElement extends MaterialUIElement {
}
protected buildChildHTML(): string {
return `<img id="${this._imageId}" class="texture-preview" src="${this._material.path}" width="75%" loading="lazy"></img>`;
let html = `<img id="${this._diffuseImageId}" class="texture-preview" src="${this._material.path}" width="75%" loading="lazy"></img>`;
if (this._material.alphaPath !== undefined) {
html += `<br><img id="${this._alphaImageId}" class="texture-preview" src="${this._material.alphaPath}" width="75%" loading="lazy"></img>`;
}
return html;
}
public registerEvents(): void {
super.registerEvents();
const element = document.getElementById(this._imageId) as HTMLLinkElement;
if (element) {
if (!this._isMissingTexture()) {
element.addEventListener('mouseover', () => {
element.classList.add('texture-hover');
});
element.addEventListener('mouseleave', () => {
element.classList.remove('texture-hover');
});
element.addEventListener('click', () => {
FileUtil.openDir(this._material.path);
});
} else {
element.classList.add('texture-preview-missing');
{
const element = document.getElementById(this._diffuseImageId) as HTMLLinkElement;
if (element) {
if (!this._isMissingTexture()) {
element.addEventListener('mouseover', () => {
element.classList.add('texture-hover');
});
element.addEventListener('mouseleave', () => {
element.classList.remove('texture-hover');
});
element.addEventListener('click', () => {
FileUtil.openDir(this._material.path);
});
} else {
element.classList.add('texture-preview-missing');
}
}
}
{
const element = document.getElementById(this._alphaImageId) as HTMLLinkElement;
if (element) {
if (!this._isMissingTexture()) {
element.addEventListener('mouseover', () => {
element.classList.add('texture-hover');
});
element.addEventListener('mouseleave', () => {
element.classList.remove('texture-hover');
});
element.addEventListener('click', () => {
ASSERT(this._material.alphaPath !== undefined);
FileUtil.openDir(this._material.alphaPath);
});
} else {
element.classList.add('texture-preview-missing');
}
}
}
}
@ -129,6 +173,8 @@ export class SolidMaterialUIElement extends MaterialUIElement {
this._appContext.onMaterialTypeSwitched(materialName);
});
}
this.addMetadata(`Alpha multiplier: ${this._material.colour.a}`);
}
protected buildChildHTML(): string {
@ -142,6 +188,7 @@ export class SolidMaterialUIElement extends MaterialUIElement {
if (colourElement !== null) {
colourElement.addEventListener('change', () => {
const newColour = RGBAUtil.fromHexString(colourElement.value);
newColour.a = this._material.colour.a;
this._appContext.onMaterialColourChanged(this._materialName, newColour);
});

View File

@ -75,7 +75,7 @@ export class UITreeBuilder implements IUIOutputElement {
} else {
childrenHTML += child.warning ? `<p style="margin:0px; color:orange;">${child.html}</p>` : child.html;
}
childrenHTML += '<li>';
childrenHTML += '</li>';
});
if (this.getWarning()) {

View File

@ -696,4 +696,9 @@ a:hover {
.texture-hover {
border-color: var(--text-standard) !important;
}
.material-container {
border-left: 1px solid #8C8C8C80;
padding-left: 5px;
}