forked from mirror/ObjToSchematic
Fixed alpha factor on solid materials
This commit is contained in:
parent
a34734265e
commit
74a2964808
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
16
src/mesh.ts
16
src/mesh.ts
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -696,4 +696,9 @@ a:hover {
|
||||
|
||||
.texture-hover {
|
||||
border-color: var(--text-standard) !important;
|
||||
}
|
||||
|
||||
.material-container {
|
||||
border-left: 1px solid #8C8C8C80;
|
||||
padding-left: 5px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user