Skip to content

Commit

Permalink
Improve brightness truncation and set colorMode when used with floa…
Browse files Browse the repository at this point in the history
…t color renderer
  • Loading branch information
ricktu288 committed Dec 27, 2024
1 parent 5e3dc4e commit 51a3a58
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 14 deletions.
8 changes: 8 additions & 0 deletions src/simulator/js/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,14 @@ class Editor {
}, 1);
}
});

// Currently the color mode is always determined by the renderer. This property of scene is only for the future when the float color renderer becomes stable and the user can choose the color mode.
if (this.simulator.useFloatColorRenderer) {
this.scene.colorMode = 'linear';
} else {
this.scene.colorMode = 'legacy';
}

this.selectObj(-1);
this.lastActionJson = json;
this.simulator.updateSimulation();
Expand Down
2 changes: 2 additions & 0 deletions src/simulator/js/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const DATA_VERSION = 5;
* @property {number} width - The width (in CSS pixels) of the viewport.
* @property {number} height - The height (in CSS pixels) of the viewport.
* @property {boolean} simulateColors - The "Simulate Color" option indicating if the color (wavelength) of the rays is simulated (also affecting whether the options of color filtering or Cauchy coefficients of some objects are shown.)
* @property {string} colorMode - The mode of rendering the color of rays (color mapping functions, etc, including the brightness behavior when `simulateColors` is false). This represents the intended behavior for the scene, but the hardware may or may not support it. Currently, this value is fixed by the renderer setting. Possible values are 1. 'legacy': the only behavior in v5.0 and before. When `simulateColors` is false, the alpha value of each ray equals its brightness, but when rays overlaps, the resulting brightness is blend with the usual alpha blending. The brightness is not corrected for the gamma value of the display. When `simulateColors` is true, the behavior is the same as 'linear' except that the brightness is not gamma-corrected. 2. 'linear' (experimental): The RGB values are calculated consistently with the brightness (and wavelength if `simulateColors` is true) of the rays in a floating-point buffer. The unit brightness corresponds to unit V in HSV. The buffered RGB is then converted to the display color space linearly when V <= 1. If V > 1, V is scaled down to 1 while preserving H and S. The resulting color is gamma-corrected for the display.
* @property {boolean} showRayArrows - The "Show Ray Arrows" option indicating if the arrows are shown on the rays indicating its direction.
* @property {boolean} symbolicBodyMerging - The "Symbolic body-merging" option in the gradient-index glass objects (which is a global option), indicating if the symbolic math is used to calculate the effective refractive index resulting from the "body-merging" of several gradient-index glass objects.
* @property {string|null} randomSeed - The seed for the random number generator used in the simulation, null if using randomly generated seed. Using a seed allows the simulation to be deterministic for the same version of this app when randomness is used. However, reproducibility is only guaranteed if the scene is just loaded (that is, no other editing has been done on the scene). Also, reproducibility is not guaranteed across different versions of the app.
Expand All @@ -81,6 +82,7 @@ class Scene {
width: 1500,
height: 900,
simulateColors: false,
colorMode: 'legacy',
showRayArrows: false,
symbolicBodyMerging: false,
randomSeed: null
Expand Down
4 changes: 2 additions & 2 deletions src/simulator/js/Simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ class Simulator {
this.canvasRendererMain.drawRay(geometry.line(s_point, geometry.point(s_point.x * 2 - this.pendingRays[j].p1.x, s_point.y * 2 - this.pendingRays[j].p1.y)), color, undefined, [1 * this.scene.lengthScale, 5 * this.scene.lengthScale]); // Draw the forward extension of the ray
} else {
this.canvasRendererMain.drawRay(geometry.line(this.pendingRays[j].p1, geometry.point(this.pendingRays[j].p1.x * 2 - this.pendingRays[j].p2.x, this.pendingRays[j].p1.y * 2 - this.pendingRays[j].p2.y)), [1, 0.5, 0, alpha], undefined, []); // Draw the backward extension of the ray
this.canvasRendererMain.drawRay(geometry.line(s_point, geometry.point(s_point.x * 2 - this.pendingRays[j].p1.x, s_point.y * 2 - this.pendingRays[j].p1.y)), [0.3, 0.3, 0.3, alpha], undefined, []); // Draw the forward extension of the ray
this.canvasRendererMain.drawRay(geometry.line(s_point, geometry.point(s_point.x * 2 - this.pendingRays[j].p1.x, s_point.y * 2 - this.pendingRays[j].p1.y)), this.useFloatColorRenderer ? [0.1, 0.1, 0.1, alpha] : [0.3, 0.3, 0.3, alpha], undefined, []); // Draw the forward extension of the ray
}

}
Expand Down Expand Up @@ -663,7 +663,7 @@ class Simulator {
if (this.scene.simulateColors) {
this.canvasRendererMain.drawPoint(observed_intersection, color, 1);
} else {
this.canvasRendererMain.drawPoint(observed_intersection, [0.3, 0.3, 0.3, alpha]);
this.canvasRendererMain.drawPoint(observed_intersection, this.useFloatColorRenderer ? [0.01, 0.01, 0.01, alpha] : [0.3, 0.3, 0.3, alpha]);
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/simulator/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ async function startApp() {
};
var gl = canvasLight.getContext('webgl', contextAttributes) || canvasLight.getContext('experimental-webgl', contextAttributes);
var ext = gl.getSupportedExtensions('OES_texture_float');

// Currently the color mode is always determined by the renderer, so we need to set it here.
scene.colorMode = 'linear';

if (!ext) {
throw new Error('OES_texture_float not supported');
}
Expand Down Expand Up @@ -1874,6 +1878,12 @@ function init() {
scene.origin = geometry.point(0, 0);
scene.scale = 1;

if (simulator.useFloatColorRenderer) {
scene.colorMode = 'linear';
} else {
scene.colorMode = 'legacy';
}

let dpr = window.devicePixelRatio || 1;

scene.setViewportSize(canvas.width / dpr, canvas.height / dpr);
Expand Down
20 changes: 14 additions & 6 deletions src/simulator/js/sceneObjs/BaseGlass.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ class BaseGlass extends BaseSceneObj {
if (bodyMergingObj) {
ray2.bodyMergingObj = bodyMergingObj;
}
if (ray2.brightness_s + ray2.brightness_p > 0.01) {
if (ray2.brightness_s + ray2.brightness_p > (this.scene.simulator.useFloatColorRenderer ? 1e-6 : 0.01)) {
newRays.push(ray2);
} else {
truncation += ray2.brightness_s + ray2.brightness_p;
if (!ray.gap) {
if (!ray.gap && !this.scene.simulator.useFloatColorRenderer) {
var amp = Math.floor(0.01 / ray2.brightness_s + ray2.brightness_p) + 1;
if (rayIndex % amp == 0) {
ray2.brightness_s = ray2.brightness_s * amp;
Expand All @@ -226,10 +226,18 @@ class BaseGlass extends BaseSceneObj {
ray.brightness_s = ray.brightness_s * (1 - R_s);
ray.brightness_p = ray.brightness_p * (1 - R_p);

return {
newRays: newRays,
truncation: truncation
};
if (ray.brightness_s + ray.brightness_p > (this.scene.simulator.useFloatColorRenderer ? 1e-6 : 0)) {
return {
newRays: newRays,
truncation: truncation
};
} else {
return {
isAbsorbed: true,
newRays: newRays,
truncation: truncation + ray.brightness_s + ray.brightness_p
};
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/simulator/js/sceneObjs/blocker/DiffractionGrating.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class DiffractionGrating extends LineObjMixin(BaseSceneObj) {
}

onRayIncident(ray, rayIndex, incidentPoint) {
let truncation = 0;
const mm_in_nm = 1 / 1000000;
var rx = ray.p1.x - incidentPoint.x;
var ry = ray.p1.y - incidentPoint.y;
Expand Down Expand Up @@ -183,12 +184,17 @@ class DiffractionGrating extends LineObjMixin(BaseSceneObj) {
// There is currently no good way to make image detection work here. So just set gap to true to disable image detection for the diffracted rays.
diffracted_ray.gap = true;

newRays.push(diffracted_ray);
if (diffracted_ray.brightness_s + diffracted_ray.brightness_p > (this.scene.simulator.useFloatColorRenderer ? 1e-6 : 0.01)) {
newRays.push(diffracted_ray);
} else {
truncation += diffracted_ray.brightness_s + diffracted_ray.brightness_p;
}
}

return {
isAbsorbed: true,
newRays: newRays
newRays: newRays,
truncation: truncation
};
}
};
Expand Down
9 changes: 7 additions & 2 deletions src/simulator/js/sceneObjs/mirror/BeamSplitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,19 @@ class BeamSplitter extends LineObjMixin(BaseFilter) {
ray2.wavelength = ray.wavelength;
ray.brightness_s *= (1 - transmission);
ray.brightness_p *= (1 - transmission);
if (ray2.brightness_s + ray2.brightness_p > .01) {
if (ray2.brightness_s + ray2.brightness_p > (this.scene.simulator.useFloatColorRenderer ? 1e-6 : 0.01)) {
return {
newRays: [ray2]
};
} else {
} else if (ray.brightness_s + ray.brightness_p > (this.scene.simulator.useFloatColorRenderer ? 1e-6 : 0.01)) {
return {
truncation: ray2.brightness_s + ray2.brightness_p
};
} else {
return {
isAbsorbed: true,
truncation: ray.brightness_s + ray.brightness_p + ray2.brightness_s + ray2.brightness_p
};
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion test/scenes/blocker/DiffractionGrating/reflect.csv
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Position,Irradiance
10,0
15,0
20,0
25,-0.0003774353868450432
25,0
30,0
35,0
40,0
Expand Down
2 changes: 1 addition & 1 deletion test/scenes/blocker/DiffractionGrating/trasmit.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Position,Irradiance
0,0.00037743538684504435
0,0
5,0
10,0
15,0
Expand Down

0 comments on commit 51a3a58

Please sign in to comment.