4.8 KiB
Trees in environment
Aby zasymulować środowisko wykorzystamy voxel space. W środowisku będziemy rozpatrywać tylko jedną cechę - zacienienie.
Klasa Environment
Klasa environment zawiera voxel space z informacją o zacienieniu.
addShadow
Funkcja addShadow implementuje metodę shadow propagation. Najpierw zwiększa wartość cienia w zadanej pozycji. Następnie przechodzi w pentlach w dół, zmniejszając z każdym poziomem siłę cienia, ale zwiększając szerokość oddziałowywania.
for(int j = (int)voxelPosition.y; j >= 0; j--)
{
for(int i = (int)voxelPosition.x-rotj; i <= (int)voxelPosition.x+rotj; i++)
{
for(int k = (int)voxelPosition.z-rotj; k <= (int)voxelPosition.z+rotj; k++)
{
float secondaryStrength = 1.0f*strength;
secondaryStrength = secondaryStrength / ((Mathf.Abs(k-(int)voxelPosition.z) + 1 + Mathf.Abs(i-(int)voxelPosition.x))/8.0f);
(...)
}
}
}
shadowStrength
Zwraca siłę cienia w zadanej pozycji
inVoxelSpace
Sprawdza, czy dane współrzędne się mieszczą w voxel space
bool inVoxelSpace(int a, int b, int c)
{
return (a<sizeX&&a>=0&&b<sizeY&&b>=0&&c<sizeZ&&c>=0);
}
positionInVoxel i positionInWorld
public Vector3 positionInVoxel(Vector3 positionInWorld)
{
Vector3 voxelPosition = new Vector3(0.0f,0.0f,0.0f);
positionInWorld -= gameObject.GetComponent<Transform>().position;
voxelPosition.x = (int)(0.5f + (positionInWorld.x / voxelSize));
voxelPosition.y = (int)(0.5f + (positionInWorld.y / voxelSize));
voxelPosition.z = (int)(0.5f + (positionInWorld.z / voxelSize));
return voxelPosition;
}
public Vector3 positionInWorld(Vector3 positionInVoxel)
{
return positionInVoxel*voxelSize+gameObject.GetComponent<Transform>().position;
}
Zadanie 1
- Otwórz Unity Project, wersję na te ćwiczenia. Następnie otwórz scenę "Pipe Model"
- Do objektu shadowBox jest przypięty skrypt Cast Shadow. Otwórz ten skrypt.
- Zmodyfikuj skrypt, tak aby ten obiekt rzucał cień w dół.
- Wykorzystaj funkcję środowiska (Environment)
- public void addShadow(Vector3 position, sbyte strength) // ujemna siła, aby usunąć (Vector3 position to pozycja shadowBox)
Zadanie 2
- W objekcie inShadow jest skrypt receiveShadow
- Zmodyfikuj skrypt - jak na ten objekt spadnie cień, to zmień materiał na inShadow, jak nie będzie w cieniu, to na noShadow
- Wykorzystaj funkcję środowiska (Environment)
- public byte shadowStrength(Vector3 pos)
Zadanie 3
-
Wybierz objekt tree (001)
-
Jeśli nie jest ustawione, to ustaw odpowiednią ścieżkę (L-System Path) do ShadowModel.txt
-
Uruchom grę i przejdź kilka kroków (Load File na start i Evaluate - krok)
-
Gałęzie w cieniu nadal się rozwijają. Wylicz zacienienie do L-Systemu
-
Skrypt TurtleLSystemEnvironment, funkcja lightDirection (20 linijka), od 38 linijki
-
Zacienienie mierzymy w prostopadłościanie wokół obecnego elementu (2*lookForLightLength x lookForLightLength x 2*lookForLightLength)
-
Transformacja z obecną pozycją (transformation*resultTransformation) funkcja transformacja.ExtractPosition() zwraca pozycję dla transformacji
-
-
Wyślij wartość zacienienia do L-Systemu
#ignore + - \ / ^ &
#axiom
S(0,0)
#rules
S(a,c) : c>=50 -> S(a+1,0)
S(a,c) : c<50 -> G\(90)[-S(0,0)]S(0,0)
-
- L-System będzie odczytywał jako cień drugą wartość - dla S(a, c) to będzie c
- node.literal.values jest tablicą z wartościami L-Systemu
Zadanie 4
- Dodaj do objektu Environment więcej drzew (Trees) i zobacz jak drzewa wpływają na siebie nawzajem
- Napisz skrypt, który utworzy 9 drzew (3 wiersze i 3 kolumny) rozmieszczonych co równą odległość, przetestuj różne odległości
- Zobacz jak się w takim układzie rozwijają
Zadanie 5 - domowe
Zintegruj L-System pipe model z wcześniejszych ćwiczeń z obsługą cienia
Napisz L-System, który modeluje wybrany przez ciebie kształt drzewa. Kształt ma być twój indywidualny, ale możesz się wspomóc: