Śledzenie promieniami świecącej kuli

15

Pobrałem POV-ray i renderowałem ten błyszczący metalowy kula w stylu lat 90 .:

wprowadź opis zdjęcia tutaj

Twoim zadaniem jest zrobić to samo, ale zrobić to, wdrażając sam silnik renderujący w jak najmniejszej liczbie bajtów. Nie musisz replikować tego dokładnego obrazu - wystarczy dowolny obraz odbijającej się kuli nad nieskończoną szachownicą, o ile spełnia poniższe kryteria.

Zasady:

  • Obraz musi przedstawiać kulę odbijającą unoszącą się nad nieskończoną szachownicą. Zarówno sama szachownica, jak i jej odbicie w kuli muszą być pokazane na obrazie. Musi być wizualnie jasne, że właśnie to widzimy. Poza tym szczegóły dotyczące geometrii, kolorów, właściwości materiału itp. Zależą od Ciebie.

  • Na scenie musi być trochę światła: części kuli powinny być ciemniejsze niż inne części, a wizualnie powinno być możliwe przybliżone określenie, skąd pochodzi światło. Poza tym szczegóły modelu oświetlenia zależą od Ciebie. (Jeśli chcesz, możesz wynaleźć własny uproszczony model oświetlenia). Kula nie musi rzucać cienia.

  • Dwa powyższe kryteria - czy naprawdę wygląda jak błyszcząca kula nad szachownicą oświetloną źródłem światła - zostaną ocenione przez społeczność za pomocą głosowania. Dlatego odpowiedź musi mieć pozytywny wynik, aby móc wygrać.

  • Dane wyjściowe muszą mieć co najmniej 300 x 300 pikseli. Może być wyświetlany na ekranie lub zapisany w pliku, albo jest w porządku.

  • Twój kod powinien działać w niecałą godzinę na rozsądnym nowoczesnym komputerze. (Jest to hojne - POV-ray renderuje powyższą scenę praktycznie natychmiast.)

  • Nie można używać wbudowanej funkcji śledzenia promieni - należy samodzielnie zaimplementować moduł renderujący.

  • To jest , więc wygrywa pozycja z dodatnim wynikiem z najkrótszym kodem (w bajtach). Możesz również zagrać w meta-grę, w której najwięcej głosów uzyskasz, rysując ładny obrazek (oczywiście z pominięciem kodu).

To wyzwanie może wydawać się absurdalnie trudne, ale ponieważ geometria jest ustalona, ​​algorytm renderowania takiej sceny za pomocą śledzenia promieni jest dość prosty. To tak naprawdę tylko przypadek iteracji nad każdym pikselem na obrazie wyjściowym i oceny wyrażenia matematycznego, aby zobaczyć, jaki powinien być kolor, więc jestem optymistą, że zobaczymy kilka dobrych odpowiedzi.

Nataniel
źródło
Osobiście nie lubię wymagań dotyczących oświetlenia. Myślę, że to dodaje dużo dodatkowej złożoności, przy bardzo niewielkim zysku. Ale tylko moja opinia.
stokastic
Mówisz, że kolory zależą od nas. Czy obejmuje to obrazy w skali szarości?
Martin Ender
@ MartinBüttner tak, obrazy w skali szarości są w porządku.
Nathaniel,
@stokastic mam nadzieję, że będzie źródłem kreatywności, ponieważ ludzie wymyślą radykalnie uproszczone, ale tylko przekonujące modele oświetlenia, które można określić za pomocą niewielkiej ilości kodu. Dodałem notatkę w pytaniu, że uproszczone modele oświetlenia są OK.
Nathaniel,
To już zostało zrobione: fabiensanglard.net/rayTracing_back_of_business_card/index.php Oczywiście może to być nieco krótszy redukując go do jednej sfery, usuwając antyaliasing itp
Shujal

Odpowiedzi:

28

Python 2, 484 468 467 bajtów

wprowadź opis zdjęcia tutaj

i=int;u=249.3
def Q(A,B):
 a=A*A+B*B+9e4;b=B*u+36e4;I=b*b-a*128e4
 if I>0:
    t=(-b+I**.5)/(5e2*a);F,G,H=A*t,B*t,u*t;J,K,M=F,G+.6,H+2.4;L=a**-.5;k=2*(A*J+B*K+u*M)*L;C,D,E=A*L-k*J,B*L-k*K,u*L-k*M;L=(C*C+D*D+E*E)**-.5;t=(-4e2-G)/D;return(D*D*L*L*u,((i(F+t*C)/200+i(H+t*E)/200)&1)*(u*D*L))[D>0]
 else:return(u*B*B/a,((i(-2e2/B*A)/200+i(-6e4/B)/100)&1)*u*B/a**.5)[B>0]
open("s.pgm","wb").write("P5 800 600 255 "+"".join(chr(i(Q(j%800-4e2,j/800-u)))for j in range(480000)))

Uwaga: po if I>0:pojawieniu się nowego wiersza, po którym następuje pojedynczy znak tabulacji przed t=...

Uruchomienie programu spowoduje utworzenie obrazu 800x600 o nazwie s.pgm

Zaczęłam od „prawdziwych” formuł ray tracera (trochę poprawiłam grę w golfa).

Renderowanie zajmuje około 3 sekund na moim martwym starym komputerze (0,7 sekundy z pypy).

6502
źródło
4
Piękny obraz!
Nathaniel
Możesz zaoszczędzić kilka bajtów bez robienia sztuczki zlib, zastępując 0000je e4przez cały.
Nataniel
@Nathaniel: Doh ... bardzo duży błąd w golfa kodu :-) Naprawiono. Usunąłem również sztuczkę pakowania zlib, ponieważ muszę zbadać jej legalność (najnowsza wersja, na przykład, gdy zip działa ze standardowym pythonem, ale nie działa z pypy, a to bardzo dziwne).
6502
Kolejna sztuczka golfowa, którą możesz zastąpić, a if b else co (c,a)[b]ile nie polegasz na zwarciach, aby uniknąć np. Dzielenia przez zero błędów. if A:code;return B\nelse:return CMożesz także zastąpić code;return(C,B)[A].
Claudiu
@Claudiu: Dzięki za sugestię. Musiałem trochę zmienić parametry, aby uniknąć podziału przez zero. Użyłem również pojedynczej pętli nad obrazem, co znacznie zaoszczędziło.
6502