diff --git a/src/app_context.ts b/src/app_context.ts index 25c3b77..158bafc 100644 --- a/src/app_context.ts +++ b/src/app_context.ts @@ -223,6 +223,7 @@ export class AppContext { textureAtlas: components.textureAtlas.getValue(), blockPalette: components.blockPalette.getValue().getBlocks(), dithering: components.dithering.getValue(), + ditheringMagnitude: components.ditheringMagnitude.getValue(), colourSpace: ColourSpace.RGB, fallable: components.fallable.getValue() as FallableBehaviour, resolution: Math.pow(2, components.colourAccuracy.getValue()), diff --git a/src/block_mesh.ts b/src/block_mesh.ts index 5cff482..0b34046 100644 --- a/src/block_mesh.ts +++ b/src/block_mesh.ts @@ -83,11 +83,11 @@ export class BlockMesh { break; } case 'random': { - Ditherer.ditherRandom(ditheredColour); + Ditherer.ditherRandom(ditheredColour, blockMeshParams.ditheringMagnitude); break; } case 'ordered': { - Ditherer.ditherOrdered(ditheredColour, voxel.position); + Ditherer.ditherOrdered(ditheredColour, voxel.position, blockMeshParams.ditheringMagnitude); break; } } diff --git a/src/config.ts b/src/config.ts index d9777ee..b7e7c6b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -30,7 +30,6 @@ export class AppConfig { public readonly CAMERA_SENSITIVITY_ROTATION = 0.005; public readonly CAMERA_SENSITIVITY_ZOOM = 0.005; public readonly CONSTRAINT_MAXIMUM_HEIGHT = 380; - public readonly DITHER_MAGNITUDE = 32; public readonly SMOOTHNESS_MAX = 3.0; public readonly CAMERA_SMOOTHING = 1.0; public readonly VIEWPORT_BACKGROUND_COLOUR: RGBA = { diff --git a/src/dither.ts b/src/dither.ts index 9a1b802..20f23ad 100644 --- a/src/dither.ts +++ b/src/dither.ts @@ -4,22 +4,22 @@ import { ASSERT } from './util/error_util'; import { Vector3 } from './vector'; export class Ditherer { - public static ditherRandom(colour: RGBA_255) { - const offset = (Math.random() - 0.5) * AppConfig.Get.DITHER_MAGNITUDE; + public static ditherRandom(colour: RGBA_255, magnitude: number) { + const offset = (Math.random() - 0.5) * magnitude; colour.r += offset; colour.g += offset; colour.b += offset; } - public static ditherOrdered(colour: RGBA_255, position: Vector3) { + public static ditherOrdered(colour: RGBA_255, position: Vector3, magnitude: number) { const map = this._getThresholdValue( Math.abs(position.x % 4), Math.abs(position.y % 4), Math.abs(position.z % 4), ); - const offset = map * AppConfig.Get.DITHER_MAGNITUDE; + const offset = map * magnitude; colour.r += offset; colour.g += offset; diff --git a/src/ui/layout.ts b/src/ui/layout.ts index 464a345..70d8c4c 100644 --- a/src/ui/layout.ts +++ b/src/ui/layout.ts @@ -175,7 +175,21 @@ export class UI { displayText: 'Off', payload: 'off', }]) - .setLabel('Dithering'), + .setLabel('Dithering') + .addEnabledChangedListener((isEnabled) => { + this._ui.assign.components.ditheringMagnitude.setEnabled(isEnabled && this._ui.assign.components.dithering.getValue() !== 'off', false); + }) + .addValueChangedListener((newValue: TDithering) => { + this._ui.assign.components.ditheringMagnitude.setEnabled(newValue !== 'off', false); + }), + 'ditheringMagnitude': new SliderComponent() + .setMin(1) + .setMax(64) + .setDefaultValue(32) + .setDecimals(0) + .setStep(1) + .setLabel('Dithering magnitude') + .setShouldObeyGroupEnables(false), 'fallable': new ComboboxComponent() .addItems([{ displayText: 'Replace falling with solid', @@ -238,6 +252,7 @@ export class UI { 'textureAtlas', 'blockPalette', 'dithering', + 'ditheringMagnitude', 'fallable', 'colourAccuracy', 'contextualAveraging', diff --git a/src/worker_types.ts b/src/worker_types.ts index 256bc39..1050451 100644 --- a/src/worker_types.ts +++ b/src/worker_types.ts @@ -109,6 +109,7 @@ export namespace AssignParams { textureAtlas: TAtlasId, blockPalette: string[], dithering: TDithering, + ditheringMagnitude: number, colourSpace: ColourSpace, fallable: FallableBehaviour, resolution: RGBAUtil.TColourAccuracy, diff --git a/tools/headless-config.ts b/tools/headless-config.ts index 5c6ea4c..ced6a80 100644 --- a/tools/headless-config.ts +++ b/tools/headless-config.ts @@ -20,6 +20,7 @@ export const headlessConfig: THeadlessConfig = { textureAtlas: 'vanilla', // Must be an atlas name that exists in /resources/atlases blockPalette: PALETTE_ALL_RELEASE, // Must be a palette name that exists in /resources/palettes dithering: 'ordered', + ditheringMagnitude: 32, colourSpace: ColourSpace.RGB, fallable: 'replace-falling', resolution: 32,