Skip to content

Commit d557795

Browse files
committed
Image filters.
1 parent 3c64ca4 commit d557795

9 files changed

Lines changed: 192 additions & 218 deletions

File tree

Screenshot.png

67.7 KB
Loading

app/scripts/app.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ class App {
3838
// spy.enabled = false;
3939

4040

41-
const random = new RandomFlowNodeController(this.surface);
42-
random.mode = RandomMode.VECTOR3;
41+
const r1 = new RandomFlowNodeController(this.surface);
42+
r1.mode = RandomMode.VECTOR3;
43+
const r2 = new RandomFlowNodeController(this.surface);
44+
r2.mode = RandomMode.VECTOR3;
45+
// const r3 = new RandomFlowNodeController(this.surface);
46+
// r3.mode = RandomMode.UNIT;
4347
// const barchart = new BarChartFlowNodeController(this.surface);
4448
// this.surface.connect(random.ports['Output'], barchart.ports['Input']);
4549
// const spy = new SpyFlowNodeController(this.surface);
4650
// this.surface.connect(random.ports['Output'], spy.ports['Input']);
4751
const ray = new RaytraceFlowNodeController(this.surface);
48-
this.surface.connect(random.ports['Output'], ray.ports['SurfaceColor']);
52+
this.surface.connect(r1.ports['Output'], ray.ports['SurfaceColor']);
53+
this.surface.connect(r2.ports['Output'], ray.ports['EmissionColor']);
54+
// this.surface.connect(r3.ports['Output'], ray.ports['Reflection']);
4955
this.surface.layout();
5056
}
5157

app/scripts/core/Surface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export class Surface implements ISurface {
138138

139139
const realValue = JSON.parse(value);
140140
if (_.isNumber(realValue)) {
141-
return value;
141+
return Math.round(realValue * 100) / 100;
142142
} else if (_.isArray(realValue)) {
143143
const els = _.take(realValue, 2).map(x => Math.round(x * 100) / 100).join(', ');
144144
return `Array: ${els}...`;

app/scripts/elements/random/RandomFlowNodeViewModel.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import * as _ from 'lodash';
1010
export enum RandomMode {
1111
NUNBER,
1212
NUMBER_ARRAY,
13-
VECTOR3
13+
VECTOR3,
14+
UNIT
1415
}
1516

1617
export interface IRandomGenerator {
@@ -49,6 +50,17 @@ export class Vector3Generator implements IRandomGenerator {
4950
}
5051
}
5152

53+
export class UnitGenerator implements IRandomGenerator {
54+
55+
constructor() {
56+
57+
}
58+
59+
generate(amount = 10): string {
60+
return JSON.stringify(Math.random());
61+
}
62+
}
63+
5264
export class RandomFlowNodeViewModel extends FlowNodeViewModel {
5365
get mode(): RandomMode {
5466
return this._mode;
@@ -114,10 +126,14 @@ export class RandomFlowNodeViewModel extends FlowNodeViewModel {
114126
case RandomMode.VECTOR3:
115127
this.generator = new Vector3Generator();
116128
break;
129+
case RandomMode.UNIT:
130+
this.generator = new UnitGenerator()
131+
break;
117132
case RandomMode.NUNBER:
118133
this.generator = new RandomNumberGenerator();
119134
break;
120135

136+
121137
}
122138
this.ticker = setInterval(() => {
123139
this.value = this.generator.generate();

app/scripts/elements/raytrace/RaytraceFlowNodeController.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,25 @@ import {RaytraceFlowNodeViewModel} from './RaytraceFlowNodeViewModel';
66

77
export class RaytraceFlowNodeController extends FlowNodeController {
88

9-
constructor( surface: ISurface) {
10-
super( surface);
9+
constructor(surface: ISurface) {
10+
super(surface);
1111
this.viewModel = new RaytraceFlowNodeViewModel(this.model);
1212

13-
this.node= this.surface.graph.createNode({
13+
this.node = this.surface.graph.createNode({
1414
style: new RaytraceNodeStyle(),
1515
layout: new Rect(0, 0, 105, 150),
1616
tag: this.viewModel
1717
});
1818

19-
const vmInput = this.viewModel.portViewModels['SurfaceColor'];
20-
this.ports['SurfaceColor'] = this.surface.graph.addPort({owner: this.node, locationParameter: FreeNodePortLocationModel.INSTANCE.createParameter( this.node, vmInput.position), style: this.inputStyle, tag: vmInput});
19+
const surfaceColorInput = this.viewModel.portViewModels['SurfaceColor'];
20+
const emissionColorInput = this.viewModel.portViewModels['EmissionColor'];
21+
const transparencyInput = this.viewModel.portViewModels['Transparency'];
22+
const reflectionInput = this.viewModel.portViewModels['Reflection'];
23+
this.ports['SurfaceColor'] = this.surface.graph.addPort({owner: this.node, locationParameter: FreeNodePortLocationModel.INSTANCE.createParameter(this.node, surfaceColorInput.position), style: this.inputStyle, tag: surfaceColorInput});
24+
this.ports['EmissionColor'] = this.surface.graph.addPort({owner: this.node, locationParameter: FreeNodePortLocationModel.INSTANCE.createParameter(this.node, emissionColorInput.position), style: this.inputStyle, tag: emissionColorInput});
25+
// posted an issue, these params seem not to work in the raytracer
26+
// this.ports['Transparency'] = this.surface.graph.addPort({owner: this.node, locationParameter: FreeNodePortLocationModel.INSTANCE.createParameter(this.node, transparencyInput.position), style: this.inputStyle, tag: transparencyInput});
27+
// this.ports['Reflection'] = this.surface.graph.addPort({owner: this.node, locationParameter: FreeNodePortLocationModel.INSTANCE.createParameter(this.node, reflectionInput.position), style: this.inputStyle, tag: reflectionInput});
2128

2229
}
2330

app/scripts/elements/raytrace/RaytraceFlowNodeViewModel.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,46 @@ import {Material, Vector3} from '../../style/raytracer';
99
export class RaytraceFlowNodeViewModel extends FlowNodeViewModel {
1010

1111
get material() {
12-
return new Material(this.surfaceColor, 0.1, 0.05, new Vector3(0.8, 0, 0));
12+
return new Material(this.surfaceColor || new Vector3(0.0, 0.2, 0.8), this.reflection || 0.1, this.transparency || 0.05, this.emissionColor || new Vector3(0.8, 0, 0));
1313
}
1414

1515
get emissionColor(): any {
1616
return this._emissionColor;
1717
}
1818

1919
set emissionColor(value: any) {
20-
value.forEach(this.ensureUnitSize);
21-
this._emissionColor = value;
20+
if (_.isString(value)) {
21+
const found = this.parseVector3(value);
22+
this._emissionColor = found;
23+
} else {
24+
value.forEach(this.ensureUnitSize);
25+
this._emissionColor = new Vector3(value[0], value[1], value[2]);
26+
}
27+
this.firePropertyChanged('emissionColor');
28+
this.setPropertyValue('emissionColor', this._emissionColor);
2229
}
2330

24-
get reflection(): number {
31+
get reflection(): any {
2532
return this._reflection;
2633
}
2734

28-
set reflection(value: number) {
29-
this.ensureUnitSize(value);
35+
set reflection(value: any) {
36+
value = this.parseUnit(value);
3037
this._reflection = value;
38+
this.firePropertyChanged('reflection');
39+
this.setPropertyValue('reflection', this._reflection);
40+
3141
}
3242

33-
get transparency(): number {
43+
get transparency(): any {
3444
return this._transparency;
3545
}
3646

37-
set transparency(value: number) {
38-
this.ensureUnitSize(value);
47+
set transparency(value: any) {
48+
value = this.parseUnit(value);
3949
this._transparency = value;
50+
this.firePropertyChanged('transparency');
51+
this.setPropertyValue('transparency', this._transparency);
4052
}
4153

4254
get surfaceColor(): any {
@@ -49,7 +61,7 @@ export class RaytraceFlowNodeViewModel extends FlowNodeViewModel {
4961
this._surfaceColor = found;
5062
} else {
5163
value.forEach(this.ensureUnitSize);
52-
this._surfaceColor = new Vector3(value[0],value[1],value[2]);
64+
this._surfaceColor = new Vector3(value[0], value[1], value[2]);
5365
}
5466
this.firePropertyChanged('surfaceColor');
5567
this.setPropertyValue('surfaceColor', this._surfaceColor);
@@ -73,6 +85,9 @@ export class RaytraceFlowNodeViewModel extends FlowNodeViewModel {
7385
super('Raytracer', model);
7486

7587
this.portViewModels['SurfaceColor'] = new FlowPortViewModel('surfaceColor', PortType.INPUT, this, new Point(0.0, 30 - 2));
88+
this.portViewModels['EmissionColor'] = new FlowPortViewModel('emissionColor', PortType.INPUT, this, new Point(0.0, 50 - 2));
89+
this.portViewModels['Reflection'] = new FlowPortViewModel('reflection', PortType.INPUT, this, new Point(0.0, 70 - 2));
90+
this.portViewModels['Transparency'] = new FlowPortViewModel('transparency', PortType.INPUT, this, new Point(0.0, 90 - 2));
7691
this.model.nodes[this.id] = new FlowNodeModel(this.id, this.model);
7792

7893
}
@@ -82,6 +97,13 @@ export class RaytraceFlowNodeViewModel extends FlowNodeViewModel {
8297

8398
}
8499

100+
parseUnit(x: any): number {
101+
if (_.isString(x)) {
102+
x = parseFloat(x);
103+
}
104+
this.ensureUnitSize(x);
105+
return x;
106+
}
85107

86108
parseVector3(x: string): Vector3 {
87109
if (_.isString(x)) {
@@ -91,7 +113,7 @@ export class RaytraceFlowNodeViewModel extends FlowNodeViewModel {
91113
throw new Error('Given string is not a Vector3 type.');
92114
}
93115
found.forEach(this.ensureUnitSize);
94-
return new Vector3(found[0],found[1],found[2]);
116+
return new Vector3(found[0], found[1], found[2]);
95117
}
96118
}
97119
throw new Error('Expected a Vector3 type.');

app/scripts/style/RaytraceNodeStyle.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {HtmlCanvasVisual, IRenderContext, NodeStyleBase, Rect, SvgVisual} from '
22
import * as _ from 'lodash';
33
import {Material, RayTracer, roundRect, Scene, Sphere, Vector3} from './raytracer'
44
import {RaytraceFlowNodeViewModel} from '../elements/raytrace/RaytraceFlowNodeViewModel';
5+
import ImageFilters from './imageFilters';
56

67
export class RaytraceVisual extends HtmlCanvasVisual {
78
get material(): Material {
@@ -78,10 +79,12 @@ export class RaytraceVisual extends HtmlCanvasVisual {
7879
ctx.restore();
7980
const factor = canvas.zoom;
8081
const im = this.getRendering(factor);
81-
if(!_.isNil(im)){
82+
if (!_.isNil(im)) {
8283
const imageData = ctx.getImageData(l.x, l.y, Math.round(factor * (105 - 2)), Math.round(factor * (150 - 12)));
8384
imageData.data.set(im);
8485
ctx.putImageData(imageData, canvas.zoom * (-viewPoint.x + l.x + 1), canvas.zoom * (-viewPoint.y + l.y + 1));
86+
// const gs = ImageFilters.threshold(imageData);
87+
// ctx.putImageData(gs, canvas.zoom * (-viewPoint.x + l.x + 1), canvas.zoom * (-viewPoint.y + l.y + 1));
8588
}
8689

8790

@@ -132,7 +135,7 @@ export default class RaytraceNodeStyle extends NodeStyleBase {
132135
const visual = oldVisual as RaytraceVisual;
133136
visual.layout = node.layout;
134137
visual.material = (node.tag as RaytraceFlowNodeViewModel).material;
135-
138+
console.log(visual.material.reflection)
136139
return visual;
137140
}
138141

app/scripts/style/imageFilters.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export default class ImageFilters {
2+
static getPixels(ctx, width, height): ImageData {
3+
return ctx.getImageData(0, 0, width, height);
4+
}
5+
6+
static applyFilter(ctx, filter, width, height) {
7+
var idata = filter(ImageFilters.getPixels(ctx, width, height));
8+
ctx.putImageData(idata, 0, 0);
9+
}
10+
11+
static grayscale(pixels) {
12+
var d = pixels.data;
13+
for (var i = 0; i < d.length; i += 4) {
14+
var r = d[i];
15+
var g = d[i + 1];
16+
var b = d[i + 2];
17+
// CIE luminance for the RGB
18+
// The human eye is bad at seeing red and blue, so we de-emphasize them.
19+
var v = 0.2126 * r + 0.7152 * g + 0.0722 * b;
20+
d[i] = d[i + 1] = d[i + 2] = v
21+
}
22+
return pixels;
23+
};
24+
25+
static threshold(pixels, threshold = 100) {
26+
var d = pixels.data;
27+
for (var i = 0; i < d.length; i += 4) {
28+
var r = d[i];
29+
var g = d[i + 1];
30+
var b = d[i + 2];
31+
var v = (0.2126 * r + 0.7152 * g + 0.0722 * b >= threshold) ? 255 : 0;
32+
d[i] = d[i + 1] = d[i + 2] = v
33+
}
34+
return pixels;
35+
};
36+
37+
}
38+
39+

0 commit comments

Comments
 (0)