Лекция 4 / 2013
- Forums:
В github съм качил кодът, който написахме преди малко на лекцията.
С някои от колегите и разкрихме откъде идваше бъгът в кода на камерата. Там имаше дефинирана една локална променлива "upLeft", която се ползваше временно за смятане на разстоянието от центъра на "решетката" до ъгъла ѝ. В последствие, при изчисляването на крайните координати на краищата на решетката, записът за горния ляв ъгъл ставаше върху тази локална променлива, а не върху член-данните на класа Camera (които на другото място бях достъпил коректно чрез this->upLeft...). Изобщо - спретнах си един класически, но изтънчен C++ капан :)
В кода в github, проблемът е коригиран - "виновната" променлива е преименувана на "corner".
Comments
raytracer разцъкване на кода
Днес свалих кода и почнах да си играя с него. Искам да попитам в текущата версия има ли значение последователността на insert-ване на node-тата, защото направих нова равнина, перпендикулярна на нашата:
nodes.push_back(floor);
nodes.push_back(verticalPlane);
и по този начин изглежда, че работи уж нормално, но като разменя горните 2 реда на екрана ми излиза само verticalPlane.
Другото нещо, което почнах да правя е пресичане на лъч със сфера, но имам малко затруднения относно това как да запълня IntersectionData структурата. Не знам дали в задачите за домашна ще има такова пресичане и не знам дали е редно да се споделя код, но може ли някакви напътствия (по-специално за u,v координатите) ?
Мерси предварително :)
Здравей. Да, текущият код не
Здравей.
Да, текущият код не се справя с повече от един обект, като причината е, че не остана време на лекцията да допишем необходимите промени в raytrace() :) Принципно, трябва да се обходят всички елементи от nodes и да се намери този от тях, който е най-близък до нас, т.е. на който data.dist му е най-малко. Само с него следва да има shade()-ване.
По втория въпрос - подходящ начин да се запълнят u,v координатите при пресечане със сфера е да се сметнат сферичните координати на получената пресечна точка. За целта ти трябва вектора между пресечната точка и центъра на сферата (или иначе казано - какви биха били координатите на пресечната точка, ако сферата се намираше в (0, 0, 0)). От тези координати, "географската ширина" се смята чрез аркускосинус от y, a географската дължина - чрез аркустангенс на x,z.
Би било подходящо така получената ширина/дължина да се трансформират до удобен за човек обхват. Ако ползваш библиотечните функции acos() и atan2(), то получените v и u ще са, респективно, в [0..π] и [-π..π]. Това е доста неинтуитивно. Подходящи изходни обхвати биха били [0..1], [0..1], или дейстителни "географски" ъгли - [-90..90], [0..360]. В следващата лекция ще напишем въпросното пресичане, а по-нататък, когато реализираме bitmap текстури, ще можеш да "облепиш" получената сферичка с карта в еквидистантна цилиндрична проекция и така да си получиш глобус с планетата Земя :)
Малко игра в пясъчника
Добавих клас
class Sphere: public Geometry {
Vector mCorePoint;
double mRadius;
и също така си реализирах intersect-а с нея. Но имам проблем с определянето на 2д координатите на пресечната точка. След като знам вектора на пресечната точка и нормалата в нея мога да направя проста текстура с 1 цвят но не знам как да изчисля u , v за да мога да приложа шахматната текстура.
Точно в предходния коментар
Точно в предходния коментар съм описал как се смятат u и v :)
И аз го докарах да изкарва
И аз го докарах да изкарва сфера с обикновен цвят, но нещо се омазва при нормалата или тез u,v координати :D.
Ами paste-ни някъде код да му
Ами paste-ни някъде код да му хвърлим едно око :)
В pastebin слагам файловете,
В pastebin слагам файловете, по които съм правил промени:
main.cpp
geometry.h
geometry.cpp
shading.h
shading.cpp
util.h
Ами следните проблеми
Ами следните проблеми виждам:
1) смятането на нормала го правиш излишно сложно. По-прост код би бил (които използва и дефинираните оператори на класа Vector, вместо да открива наново колелото):
data.normal = data.p - sphereSpaceOrigin;
data.normal.normalize();
2) смятането на u, v ползва координатите на пресечната точка, игнорирайки факта, че нейните координати са световни, а не релативни спрямо центъра. Подходяща корекция би била:
Vector relative = data.p - sphereSpaceOrigin;
data.u = toDegrees(acos(relative.y));
data.v = toDegrees(atan2(relative.z, relative.x));
Много благодаря, така
Много благодаря, така наистина се получават по-реални резултати :D
Първоначално пак нещо не ставаше, но се усетих, че трябва да сложа обекта, така че да го "огрее" правилно светлината, та да се види ефекта :)
Видео запис
Здравейте!
Искам да попитам кога ще бъдат качени обновените лекции и видео записите ? Поне от 25.10 защото тогава започваше хакатона във ФМИ и предполагам доста хора са пропуснали лекцията. Ако не друго то поне лекцията да се качи в YouTube и да се даде линк към нея ?
Поздрави! :)
Разминали сме се с половин
Разминали сме се с половин час :) Вече са качени.
Видеото от лекция 3 се качва в момента, ако всичко е окей, ще кача и това от лекция 4 привечер.