Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

21.06.2013, 21:26

Schatten, Licht und HTML Canvas

Hallo allesamt!

Ich spiele grad etwas mit Schatten und Licht herum. Meine erste Version ist auch schon relativ ansehnlich (zumindest schnell genug, das war so meine Hauptsorge):

(Link)

Stellt euch ein Viereck beim Schatten vor, ich zeichne erstmal nur die Umrisse...

Auch an anderen Stellen sieht's ganz gut aus:

(Link)


Jetzt habe ich nur ein Problem an Kantenstellen von zwei Lichtern, weiter rechts oder links:

(Link)


Zur Technik, wie ich das im Moment mache:
Zuerst zeichne ich die Lichter, dann bool ich das Objekt (einen Cube in dem Fall) heraus und werfe vom Mittelpunkt des Lichtes einen Strahl an allen Ecken vorbei bis zum Lichtende. Dann fülle ich die so erstellten Bereiche (immer noch mit bool herausnehmen) indem ich die Enden miteinander verbinde und dann den Inhalt fülle.
Hier kommt der noch furchtbare Spaghetticode (wird noch besser, ist nur zum Testen erstmal)

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
var dir = {x: this.position.x, y: this.position.y};
vMath.subV(dir, objects[i].position);
var dist = vMath.length(dir);
var dir2 = {x: this.position.x, y: this.position.y};
vMath.subV(dir2, {x: objects[i].position.x + objects[i].size, y: objects[i].position.y + objects[i].size});
var dist2 = vMath.length(dir2);
// 'cast' shadow
ctx.globalCompositeOperation = "destination-out";
ctx.fillRect(objects[i].position.x, objects[i].position.y, objects[i].size, objects[i].size);
// remove corners facing from light source away
ctx.beginPath();
// todo: polygons
ctx.moveTo(objects[i].position.x, objects[i].position.y);
var p2 = new Vec2M(objects[i].position.x, objects[i].position.y);
var s1 = new Vec2M(this.position.x, this.position.y);
var p1 = s1.subV(p2);
p1.normalize();
p1 = p1.mulS(dist - this.strength - 50);
var end1 = p1.addV(p2);
ctx.lineTo(end1.x, end1.y);

ctx.moveTo(objects[i].position.x + objects[i].size, objects[i].position.y + objects[i].size);
p2 = new Vec2M(objects[i].position.x + objects[i].size, objects[i].position.y + objects[i].size);
s1 = new Vec2M(this.position.x, this.position.y);
p1 = s1.subV(p2);
p1.normalize();
p1 = p1.mulS(dist2 - this.strength - 50);
var end2 = p1.addV(p2);
ctx.lineTo(end2.x, end2.y);

var dir3 = {x: this.position.x, y: this.position.y};
vMath.subV(dir3, {x: objects[i].position.x + objects[i].size, y: objects[i].position.y});
var dist3 = vMath.length(dir3);

ctx.moveTo(objects[i].position.x + objects[i].size, objects[i].position.y);
p2 = new Vec2M(objects[i].position.x + objects[i].size, objects[i].position.y);
s1 = new Vec2M(this.position.x, this.position.y);
p1 = s1.subV(p2);
p1.normalize();
p1 = p1.mulS(dist3 - this.strength - 50);
var end3 = p1.addV(p2);
ctx.lineTo(end3.x, end3.y);

var dir4 = {x: this.position.x, y: this.position.y};
vMath.subV(dir4, {x: objects[i].position.x, y: objects[i].position.y + objects[i].size});
var dist4 = vMath.length(dir4);

ctx.moveTo(objects[i].position.x, objects[i].position.y + objects[i].size);
p2 = new Vec2M(objects[i].position.x, objects[i].position.y + objects[i].size);
s1 = new Vec2M(this.position.x, this.position.y);
p1 = s1.subV(p2);
p1.normalize();
p1 = p1.mulS(dist4 - this.strength - 50);
var end4 = p1.addV(p2);
ctx.lineTo(end4.x, end4.y);

ctx.moveTo(end4.x, end4.y);
ctx.lineTo(end1.x, end1.y);
ctx.lineTo(objects[i].position.x, objects[i].position.y);
ctx.lineTo(objects[i].position.x, objects[i].position.y + objects[i].size);
ctx.fill();

ctx.moveTo(end1.x, end1.y);
ctx.lineTo(end3.x, end3.y);
ctx.lineTo(objects[i].position.x + objects[i].size, objects[i].position.y);
ctx.lineTo(objects[i].position.x, objects[i].position.y);
ctx.fill();

ctx.moveTo(end3.x, end3.y);
ctx.lineTo(end2.x, end2.y);
ctx.lineTo(objects[i].position.x + objects[i].size, objects[i].position.y + objects[i].size);
ctx.lineTo(objects[i].position.x + objects[i].size, objects[i].position.y);
ctx.fill();

ctx.moveTo(end2.x, end2.y);
ctx.lineTo(end4.x, end4.y);
ctx.lineTo(objects[i].position.x, objects[i].position.y + objects[i].size);
ctx.lineTo(objects[i].position.x + objects[i].size, objects[i].position.y + objects[i].size);
ctx.fill();

ctx.stroke();


Hat jemand eine bessere Idee das zu machen, oder eine Möglichkeit wie man diese unschöne Kante da vielleicht wegbekommt?

Hier könnt ihr's übrigens in Aktion sehen:
http://www.walawala.org/digga/

Grüße,
Alexander
Development blog: http://www.walawala.org/blog

FSA

Community-Fossil

  • Private Nachricht senden

2

21.06.2013, 21:53

Dass das Licht sich so verhält, ist richtig. Lichter sind additiv. Ich sehe kein Problem.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

3

21.06.2013, 21:56

Argh, wenn man sich das nochmal überlegt hast du recht! Sorry ;)

Aber irgendwas ist da trotzdem noch nicht richtig, ich kann nur nicht den Finger drauf legen was genau...
Development blog: http://www.walawala.org/blog

FSA

Community-Fossil

  • Private Nachricht senden

4

21.06.2013, 22:02

Es könnte unnatürlich für dich aussehen, weil der Falloff sehr schwach ist. Normalerweise ist der Falloff quadratisch proportional zur Entfernung von der Lichtquelle. Bei dir scheint mir es eher nur ein Kreis zu sein wo kaum Unterschiede in der Helligkeit sind.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

5

21.06.2013, 22:05

Wenn das korrigiert wäre, sähe das additive Verhalten auch (wieder) realistischer aus. :)
Ist der extrem große Schatten, wenn man mit dem Rechteck über die Lichtquelle geht, gewollt? Der macht mir irgendwie irgendwo 'Sorgen'... :huh:

MfG
Check

6

21.06.2013, 22:05

Hmja, das kanns wirklich sein, das ist im Moment einfach ein Gradient, "weils so schön Einfach ist". Der wird ab 1/3 der Strecke halt von Alpha 1 auf Alpha 0 gesetzt... Ich probier damit mal etwas mehr herum... Eine Idee wie man das mit Canvas-Bordmitteln machen könnte?
Development blog: http://www.walawala.org/blog

7

21.06.2013, 22:07

@Checkmateing: Gewollt ist übertrieben, eigentlich sollte die Quelle ja komplett verdeckt sein wenn da was drauf ist, aber das ist so der Kompromiss mit dem ich leben konnte...
Development blog: http://www.walawala.org/blog

FSA

Community-Fossil

  • Private Nachricht senden

8

21.06.2013, 22:14

Du müsstest den Abstand zwischen dem beleuchtet Pixel und Lichtquelle berechnen.
Wenn du den Abstand hast, ist das ganze einfach:

C-/C++-Quelltext

1
2
3
4
float distance = ...;
distance = pow(distance,2.0f);

FinalColor *= distance;

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

9

21.06.2013, 22:21

Das Problem ist, sobald ich Pixeloperationen mach' die Performance furchtbar in den Keller geht, das heisst ich müsste das über einen Verlauf oder ähnliches machen. Ich guck mir das morgen nochmal genauer an, vielleicht finde ich noch eine Möglichkeit das zu Faken.
Development blog: http://www.walawala.org/blog

Werbeanzeige

Ähnliche Themen