Skip to content

Commit 80f6484

Browse files
committed
tmp
1 parent cf72343 commit 80f6484

File tree

9 files changed

+946
-273
lines changed

9 files changed

+946
-273
lines changed

public/index.html

+257-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,263 @@
3636
<body>
3737
<!-- <pre></pre> -->
3838
<canvas></canvas>
39-
<script src="code/bundle.js"></script>
39+
<!-- <script src="code/bundle.js"></script> -->
40+
41+
<script>
42+
43+
// Find intersection of RAY & SEGMENT
44+
function getIntersection(ray, segment) {
45+
// RAY in parametric: Point + Delta*T1
46+
var r_px = ray.a.x;
47+
var r_py = ray.a.y;
48+
var r_dx = ray.b.x - ray.a.x;
49+
var r_dy = ray.b.y - ray.a.y;
50+
51+
// SEGMENT in parametric: Point + Delta*T2
52+
var s_px = segment.a.x;
53+
var s_py = segment.a.y;
54+
var s_dx = segment.b.x - segment.a.x;
55+
var s_dy = segment.b.y - segment.a.y;
56+
57+
// Are they parallel? If so, no intersect
58+
var r_mag = Math.sqrt(r_dx * r_dx + r_dy * r_dy);
59+
var s_mag = Math.sqrt(s_dx * s_dx + s_dy * s_dy);
60+
if (r_dx / r_mag == s_dx / s_mag && r_dy / r_mag == s_dy / s_mag) {
61+
// Unit vectors are the same.
62+
return null;
63+
}
64+
65+
// SOLVE FOR T1 & T2
66+
// r_px+r_dx*T1 = s_px+s_dx*T2 && r_py+r_dy*T1 = s_py+s_dy*T2
67+
// ==> T1 = (s_px+s_dx*T2-r_px)/r_dx = (s_py+s_dy*T2-r_py)/r_dy
68+
// ==> s_px*r_dy + s_dx*T2*r_dy - r_px*r_dy = s_py*r_dx + s_dy*T2*r_dx - r_py*r_dx
69+
// ==> T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx)
70+
var T2 = (r_dx * (s_py - r_py) + r_dy * (r_px - s_px)) / (s_dx * r_dy - s_dy * r_dx);
71+
var T1 = (s_px + s_dx * T2 - r_px) / r_dx;
72+
73+
// Must be within parametic whatevers for RAY/SEGMENT
74+
if (T1 < 0) return null;
75+
if (T2 < 0 || T2 > 1) return null;
76+
77+
// Return the POINT OF INTERSECTION
78+
return {
79+
x: r_px + r_dx * T1,
80+
y: r_py + r_dy * T1,
81+
param: T1
82+
};
83+
}
84+
85+
function getSightPolygon(sightX, sightY) {
86+
// Get all unique points
87+
var points = (function (segments) {
88+
var a = [];
89+
segments.forEach(function (seg) {
90+
a.push(seg.a, seg.b);
91+
});
92+
return a;
93+
})(segments);
94+
95+
var uniquePoints = (function (points) {
96+
var set = {};
97+
return points.filter(function (p) {
98+
var key = p.x + "," + p.y;
99+
if (key in set) {
100+
return false;
101+
} else {
102+
set[key] = true;
103+
return true;
104+
}
105+
});
106+
})(points);
107+
108+
// Get all angles
109+
var uniqueAngles = [];
110+
for (var j = 0; j < uniquePoints.length; j++) {
111+
var uniquePoint = uniquePoints[j];
112+
var angle = Math.atan2(uniquePoint.y - sightY, uniquePoint.x - sightX);
113+
uniquePoint.angle = angle;
114+
uniqueAngles.push(angle - 0.00001, angle, angle + 0.00001);
115+
}
116+
117+
// RAYS IN ALL DIRECTIONS
118+
var intersects = [];
119+
for (var j = 0; j < uniqueAngles.length; j++) {
120+
var angle = uniqueAngles[j];
121+
// Calculate dx & dy from angle
122+
var dx = Math.cos(angle);
123+
var dy = Math.sin(angle);
124+
125+
// Ray from light coord to point coord
126+
var ray = {
127+
a: { x: sightX, y: sightY },
128+
b: { x: sightX + dx, y: sightY + dy }
129+
};
130+
131+
// Find CLOSEST intersection
132+
var closestIntersect = null;
133+
for (var i = 0; i < segments.length; i++) {
134+
var intersect = getIntersection(ray, segments[i]);
135+
if (!intersect) continue;
136+
137+
// param (aka distance)
138+
if (!closestIntersect || intersect.param < closestIntersect.param) {
139+
closestIntersect = intersect;
140+
}
141+
}
142+
143+
// Intersect angle
144+
if (!closestIntersect) continue;
145+
closestIntersect.angle = angle;
146+
147+
// Add to list of intersects
148+
intersects.push(closestIntersect);
149+
}
150+
151+
// Sort intersects by angle
152+
intersects = intersects.sort(function (a, b) {
153+
return a.angle - b.angle;
154+
});
155+
156+
// Polygon is intersects, in order of angle
157+
return intersects;
158+
}
159+
160+
///////////////////////////////////////////////////////
161+
// DRAWING
162+
var canvas = document.querySelector("canvas");
163+
canvas.width = window.innerWidth;
164+
canvas.height = window.innerHeight;
165+
166+
var ctx = canvas.getContext("2d");
167+
168+
function draw() {
169+
// Clear canvas
170+
ctx.clearRect(0, 0, canvas.width, canvas.height);
171+
172+
ctx.fillStyle = '#000';
173+
ctx.fillRect(0, 0, canvas.width, canvas.height);
174+
175+
// Draw segments
176+
ctx.strokeStyle = "#999";
177+
for (var i = 0; i < segments.length; i++) {
178+
var seg = segments[i];
179+
ctx.beginPath();
180+
ctx.moveTo(seg.a.x, seg.a.y);
181+
ctx.lineTo(seg.b.x, seg.b.y);
182+
ctx.stroke();
183+
}
184+
185+
var lightsCount = 5;
186+
187+
188+
performance.mark('getSightPolygonStart');
189+
190+
// Sight Polygons
191+
var fuzzyRadius = 10;
192+
var polygons = [getSightPolygon(Mouse.x, Mouse.y)];
193+
for (var angle = 0; angle < Math.PI * 2; angle += (Math.PI * 2) / lightsCount) {
194+
var dx = Math.cos(angle) * fuzzyRadius;
195+
var dy = Math.sin(angle) * fuzzyRadius;
196+
polygons.push(getSightPolygon(Mouse.x + dx, Mouse.y + dy));
197+
};
198+
199+
performance.mark('getSightPolygonEnd');
200+
performance.measure('getSightPolygon', 'getSightPolygonStart', 'getSightPolygonEnd');
201+
202+
203+
// DRAW AS A GIANT POLYGON
204+
for (var i = 1; i < polygons.length; i++) {
205+
drawPolygon(polygons[i], ctx, `rgba(255, 255, 255, ${1 / lightsCount})`);
206+
}
207+
drawPolygon(polygons[0], ctx, "#fff");
208+
209+
210+
// Draw red dots
211+
ctx.fillStyle = "#dd3838";
212+
ctx.beginPath();
213+
ctx.arc(Mouse.x, Mouse.y, 2, 0, 2 * Math.PI, false);
214+
ctx.fill();
215+
for (var angle = 0; angle < Math.PI * 2; angle += (Math.PI * 2) / lightsCount) {
216+
var dx = Math.cos(angle) * fuzzyRadius;
217+
var dy = Math.sin(angle) * fuzzyRadius;
218+
ctx.beginPath();
219+
ctx.arc(Mouse.x + dx, Mouse.y + dy, 2, 0, 2 * Math.PI, false);
220+
ctx.fill();
221+
}
222+
}
223+
224+
function drawPolygon(polygon, ctx, fillStyle) {
225+
ctx.fillStyle = fillStyle;
226+
ctx.beginPath();
227+
ctx.moveTo(polygon[0].x, polygon[0].y);
228+
for (var i = 1; i < polygon.length; i++) {
229+
var intersect = polygon[i];
230+
ctx.lineTo(intersect.x, intersect.y);
231+
}
232+
ctx.fill();
233+
}
234+
235+
// LINE SEGMENTS
236+
var segments = [
237+
// Border
238+
{ a: { x: 0, y: 0 }, b: { x: 640, y: 0 } },
239+
{ a: { x: 640, y: 0 }, b: { x: 640, y: 360 } },
240+
{ a: { x: 640, y: 360 }, b: { x: 0, y: 360 } },
241+
{ a: { x: 0, y: 360 }, b: { x: 0, y: 0 } },
242+
// Polygon #1
243+
{ a: { x: 100, y: 150 }, b: { x: 120, y: 50 } },
244+
{ a: { x: 120, y: 50 }, b: { x: 200, y: 80 } },
245+
{ a: { x: 200, y: 80 }, b: { x: 140, y: 210 } },
246+
{ a: { x: 140, y: 210 }, b: { x: 100, y: 150 } },
247+
// Polygon #2
248+
{ a: { x: 100, y: 200 }, b: { x: 120, y: 250 } },
249+
{ a: { x: 120, y: 250 }, b: { x: 60, y: 300 } },
250+
{ a: { x: 60, y: 300 }, b: { x: 100, y: 200 } },
251+
// Polygon #3
252+
{ a: { x: 200, y: 260 }, b: { x: 220, y: 150 } },
253+
{ a: { x: 220, y: 150 }, b: { x: 300, y: 200 } },
254+
{ a: { x: 300, y: 200 }, b: { x: 350, y: 320 } },
255+
{ a: { x: 350, y: 320 }, b: { x: 200, y: 260 } },
256+
// Polygon #4
257+
{ a: { x: 340, y: 60 }, b: { x: 360, y: 40 } },
258+
{ a: { x: 360, y: 40 }, b: { x: 370, y: 70 } },
259+
{ a: { x: 370, y: 70 }, b: { x: 340, y: 60 } },
260+
// Polygon #5
261+
{ a: { x: 450, y: 190 }, b: { x: 560, y: 170 } },
262+
{ a: { x: 560, y: 170 }, b: { x: 540, y: 270 } },
263+
{ a: { x: 540, y: 270 }, b: { x: 430, y: 290 } },
264+
{ a: { x: 430, y: 290 }, b: { x: 450, y: 190 } },
265+
// Polygon #6
266+
{ a: { x: 400, y: 95 }, b: { x: 580, y: 50 } },
267+
{ a: { x: 580, y: 50 }, b: { x: 480, y: 150 } },
268+
{ a: { x: 480, y: 150 }, b: { x: 400, y: 95 } }
269+
];
270+
// DRAW LOOP
271+
272+
var updateCanvas = true;
273+
274+
function drawLoop() {
275+
requestAnimationFrame(drawLoop);
276+
if (updateCanvas) {
277+
draw();
278+
updateCanvas = false;
279+
}
280+
}
281+
window.onload = function () {
282+
drawLoop();
283+
};
284+
// MOUSE
285+
var Mouse = {
286+
x: canvas.width / 2,
287+
y: canvas.height / 2
288+
};
289+
canvas.onmousemove = function (event) {
290+
Mouse.x = event.clientX;
291+
Mouse.y = event.clientY;
292+
updateCanvas = true;
293+
};
294+
295+
</script>
40296
</body>
41297

42298
</html>

src/main.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import StateWorker from 'worker-loader?name=state-worker.[hash:5].js!./workers/state/state-worker';
88
import { initStateEvent, triggerEvent } from './workers/state/events';
99
import RenderWorker from 'worker-loader?name=render-worker.[hash:5].js!./workers/render/render-worker';
10-
import { initRenderEvent } from './workers/render/events';
10+
import { initRenderEvent, setLightLocationEvent } from './workers/render/events';
1111

1212
const stateWorker = new StateWorker();
1313
const renderWorker = new RenderWorker();
@@ -59,14 +59,26 @@ const pointsCount = 0;
5959

6060
console.log(x, y);
6161
stateWorker.postMessage(triggerEvent({ x, y: -y }));
62+
// renderWorker.postMessage(setLightLocationEvent({ x, y: -y }));
63+
})
64+
65+
window.addEventListener('mousemove', (e: MouseEvent) => {
66+
const { left, top } = canvas.getBoundingClientRect()
67+
68+
const x = e.clientX - left - canvas.width / 2;
69+
const y = e.clientY - top - canvas.height / 2;
70+
71+
renderWorker.postMessage(setLightLocationEvent({ x, y: -y }));
6272
})
6373

6474
const getShaderSource = async (name: string) => (await import(`./shaders/${name}`)).default;
65-
const [pV, pF, cV, cF] = await Promise.all([
75+
const [pV, pF, cV, cF, lV, lF] = await Promise.all([
6676
getShaderSource('particles.v.glsl'),
6777
getShaderSource('particles.f.glsl'),
6878
getShaderSource('color.v.glsl'),
6979
getShaderSource('color.f.glsl'),
80+
getShaderSource('light.v.glsl'),
81+
getShaderSource('light.f.glsl'),
7082
])
7183

7284
renderWorker.postMessage(initRenderEvent({
@@ -78,6 +90,8 @@ const pointsCount = 0;
7890
particlesFragment: pF,
7991
colorVertex: cV,
8092
colorFragment: cF,
93+
lightVertex: lV,
94+
lightFragment: lF,
8195
}
8296
}), [offscreen]);
8397
})();

src/shaders/color.f.glsl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
precision lowp float;
22

3-
uniform vec3 color;
3+
uniform vec4 color;
44

55
void main() {
6-
gl_FragColor = vec4(color, 1.0);
6+
gl_FragColor = color;
77
}

src/shaders/light.f.glsl

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
precision lowp float;
2+
3+
uniform vec2 resolution;
4+
5+
varying vec2 lightPos;
6+
7+
void main() {
8+
// if (gl_FragColor.x < 0.1 && gl_FragColor.y < 0.1 && gl_FragColor.z < 0.1) {
9+
// return;
10+
// }
11+
12+
float vSize = 300.0;
13+
float innerRadius = vSize * 0.3;
14+
float outerRadius = vSize * 0.5;
15+
float blurFactor = 0.275;
16+
17+
18+
19+
float m = min(resolution.x, resolution.y);
20+
21+
float x1 = (gl_FragCoord.x - resolution.x * 0.5) - lightPos.x;
22+
float y1 = (gl_FragCoord.y - resolution.y * 0.5) - lightPos.y;
23+
24+
25+
float r = max(resolution.x, resolution.y);
26+
float d = max(r / sqrt(x1 * x1 + y1 * y1), 1.0);
27+
28+
float c = max(d * 0.05, 0.01);
29+
gl_FragColor = vec4(c, c, c * 0.65, 1.0);
30+
}

src/shaders/light.v.glsl

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
precision lowp float;
2+
3+
attribute vec2 coord;
4+
attribute vec2 scale;
5+
6+
attribute vec2 lightCoord;
7+
8+
varying vec2 lightPos;
9+
10+
void main() {
11+
lightPos = lightCoord;
12+
13+
gl_Position = vec4(
14+
coord.x * scale.x,
15+
coord.y * scale.y,
16+
0.0,
17+
1.0
18+
);
19+
}

src/workers/render/events.ts

+11
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,14 @@ export const initRenderEvent = (data: InitRenderData): WorkerEvent<InitRenderDat
1616

1717
initRenderEvent.toString = () => 'init-render';
1818

19+
export type SetLightLocationData = {
20+
x: number;
21+
y: number;
22+
}
23+
24+
export const setLightLocationEvent = (data: SetLightLocationData): WorkerEvent<SetLightLocationData> => ({
25+
type: 'set-light-location',
26+
data,
27+
});
28+
29+
setLightLocationEvent.toString = () => 'set-light-location';

0 commit comments

Comments
 (0)