Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple Color Adjustments #219

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion src/edit-ops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,40 @@ class ResetOp extends StateOp {
}
}

interface EntityColorAdjustment {
brightness: number
temperature: number
tint: number
}

class EntityColorAdjustmentOp {
name = 'entityColorAdjustment';

splat: Splat;
oldAdj: EntityColorAdjustment;
newAdj: EntityColorAdjustment;

constructor(options: { splat: Splat, oldAdj: EntityColorAdjustment, newAdj: EntityColorAdjustment }) {
this.splat = options.splat;
this.oldAdj = options.oldAdj;
this.newAdj = options.newAdj;
}

do() {
this.splat.colorAdjustment = this.newAdj;
}

undo() {
this.splat.colorAdjustment = this.oldAdj;
}

destroy() {
this.splat = null;
this.oldAdj = null;
this.oldAdj = null;
}
}

// op for modifying a splat transform
class EntityTransformOp {
name = 'entityTransform';
Expand Down Expand Up @@ -348,5 +382,7 @@ export {
EntityTransformOp,
SplatsTransformOp,
PlacePivotOp,
MultiOp
MultiOp,
EntityColorAdjustment,
EntityColorAdjustmentOp
};
4 changes: 4 additions & 0 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S
scene.forceRender = true;
});

events.on('splat.color', () => {
scene.forceRender = true;
});

events.on('camera.bound', () => {
scene.forceRender = true;
});
Expand Down
4 changes: 3 additions & 1 deletion src/shaders/splat-shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ uniform sampler2D splatState;
uniform highp usampler2D splatTransform; // per-splat index into transform palette
uniform sampler2D transformPalette; // palette of transform matrices

uniform vec4 colorAdjustment; // rgba factors to be applied to SH0

varying mediump vec2 texCoord;
varying mediump vec4 color;
flat varying highp uint vertexState;
Expand Down Expand Up @@ -66,7 +68,7 @@ void main(void)
vec4 v1v2 = calcV1V2(splat_cam.xyz, covA, covB, transpose(mat3(model_view)));

// get color
color = texelFetch(splatColor, splatUV, 0);
color = texelFetch(splatColor, splatUV, 0) * colorAdjustment;

// calculate scale based on alpha
// float scale = min(1.0, sqrt(-log(1.0 / 255.0 / color.a)) / 2.0);
Expand Down
26 changes: 25 additions & 1 deletion src/splat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Serializer } from "./serializer";
import { State } from './splat-state';
import { vertexShader, fragmentShader } from './shaders/splat-shader';
import { TransformPalette } from './transform-palette';
import { EntityColorAdjustment } from './edit-ops';

const vec = new Vec3();
const veca = new Vec3();
Expand Down Expand Up @@ -55,6 +56,11 @@ class Splat extends Element {
localBoundDirty = true;
worldBoundDirty = true;
_visible = true;
_colorAdjustment: EntityColorAdjustment = {
brightness: 1,
temperature: 0,
tint: 0
};
transformPalette: TransformPalette;

selectionAlpha = 1;
Expand Down Expand Up @@ -120,10 +126,18 @@ class Splat extends Element {
// @ts-ignore
instance.createMaterial(getMaterialOptions(instance.splat.hasSH ? bands : 0));

const material = instance.material;
const material = instance.material;
const {brightness, temperature, tint} = this._colorAdjustment;

material.setParameter('splatState', this.stateTexture);
material.setParameter('splatTransform', this.transformTexture);
material.setParameter('transformPalette', this.transformPalette.texture);
material.setParameter('colorAdjustment', [
(1.0 + temperature + tint) * brightness,
(1.0 - Math.abs(temperature / 2) - tint) * brightness,
(1.0 - temperature + tint / 2) * brightness,
1
]);
material.update();
};

Expand Down Expand Up @@ -391,6 +405,16 @@ class Splat extends Element {
this.scene.events.fire('splat.visibility', this);
}
}

set colorAdjustment(adj: EntityColorAdjustment){
this._colorAdjustment = adj;
this.rebuildMaterial(this.scene.events.invoke('view.bands'));
this.scene.events.fire('splat.color', this);
}

get colorAdjustment() {
return this._colorAdjustment;
}
}

export { Splat };
62 changes: 62 additions & 0 deletions src/ui/color-panel.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#color-panel {
display: flex;
flex-direction: column;

background-color: $bcg-primary;

padding: 0px 6px 12px 6px;
}

.color-row{
height: 32px;
line-height: 32px;
width: 100%;
display: flex;
flex-direction: row;
flex-grow: 1;
align-items: center;
}

.color-label{
width: 70px;
flex-shrink: 0;
flex-grow: 0;
margin: 0px;
}

.color-expand {
flex-grow: 1;
}

$height: 22px;

#color-panel > div > div.pcui-vector-input {
margin: 0px;
gap: 10px;
height: $height;
}

#color-panel > div > div.pcui-numeric-input {
margin: 0px;
height: $height;
line-height: $height;

& > input {
padding: 0px;
margin: 0px 0px 0px 4px;
height: $height;
}
}

#color-panel > div > div > div.pcui-numeric-input {
margin: 0px;
height: $height;
line-height: $height;

& > input {
padding: 0px;
margin: 0px 0px 0px 4px;
height: $height;
}
}
162 changes: 162 additions & 0 deletions src/ui/color-panel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { Container, ContainerArgs, Label, NumericInput } from 'pcui';
import { Events } from '../events';
import { Splat } from '../splat';
import { EntityColorAdjustmentOp } from '../edit-ops';
import { localize } from './localization';

class ColorPanel extends Container {
constructor(events: Events, args: ContainerArgs = {}) {
args = {
...args,
id: 'color-panel'
};

super(args);

const brightness = new Container({
class: 'color-row'
});

const brightnessLabel = new Label({
class: 'color-label',
text: localize('color.brightness')
});

const brightnessInput = new NumericInput({
class: 'color-expand',
precision: 2,
value: 1.0,
min: 0.0,
max: 10.0,
enabled: false
});

brightness.append(brightnessLabel);
brightness.append(brightnessInput);

const temperature = new Container({
class: 'color-row'
});

const temperatureLabel = new Label({
class: 'color-label',
text: localize('color.temperature')
});

const temperatureInput = new NumericInput({
class: 'color-expand',
precision: 2,
value: 0,
min: -0.5,
max: 0.5,
enabled: false
});

temperature.append(temperatureLabel);
temperature.append(temperatureInput);

const tint = new Container({
class: 'color-row'
});

const tintLabel = new Label({
class: 'color-label',
text: localize('color.tint')
});

const tintInput = new NumericInput({
class: 'color-expand',
precision: 2,
value: 0,
max: 0.5,
min: -0.5,
enabled: false
});

tint.append(tintLabel);
tint.append(tintInput);

this.append(brightness);
this.append(temperature);
this.append(tint);

let selection: Splat | null = null;

let uiUpdating = false;

const updateUI = () => {
uiUpdating = true;
brightnessInput.value = selection.colorAdjustment.brightness;
temperatureInput.value = selection.colorAdjustment.temperature;
tintInput.value = selection.colorAdjustment.tint;
uiUpdating = false;
};

events.on('selection.changed', (splat) => {
selection = splat;

if (selection) {
// enable inputs
updateUI();
temperatureInput.enabled = tintInput.enabled = brightnessInput.enabled = true;
} else {
// disable inputs
temperatureInput.enabled = tintInput.enabled = brightnessInput.enabled = false;
}
});

let op: EntityColorAdjustmentOp | null = null;

const createOp = () => {
op = new EntityColorAdjustmentOp({
splat: selection,
oldAdj: selection.colorAdjustment,
newAdj: selection.colorAdjustment
});
};

const updateOp = () => {
op.newAdj = {
brightness: brightnessInput.value,
temperature: temperatureInput.value,
tint: tintInput.value
};

op.do();
};

const submitOp = () => {
events.fire('edit.add', op);
op = null;
};

const change = () => {
if (!uiUpdating) {
if (op) {
updateOp();
} else {
createOp();
updateOp();
submitOp();
}
}
};

const mousedown = () => {
createOp();
};

const mouseup = () => {
updateOp();
submitOp();
};

[brightnessInput, temperatureInput, tintInput].forEach((input) => {
input.on('change', change);
input.on('slider:mousedown', mousedown);
input.on('slider:mouseup', mouseup);
});
}
}

export { ColorPanel };
4 changes: 4 additions & 0 deletions src/ui/localization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ const localizeInit = () => {
"position": "Position",
"rotation": "Rotation",
"scale": "Scale",
"color": "COLOR",
"color.brightness": "Brightness",
"color.temperature": "Temperature",
"color.tint": "Tint",

// Options panel
"options": "VIEW OPTIONS",
Expand Down
Loading
Loading