Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

КомпГр_ЛР6_Заболотников_Петрова_Романова_9373

.pdf
Скачиваний:
12
Добавлен:
20.06.2023
Размер:
874.64 Кб
Скачать

МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА) Кафедра ИС

ОТЧЕТ по лабораторной работе№6

по дисциплине «Компьютерная графика» Тема: Формирования реалистических изображений с использованием

простых моделей освещения одним или двумя точечными источниками

Студент гр. 9373

_______________

Заболотников М. Е.

Студентка гр. 9373

_______________

Петрова С. В.

Студентка гр. 9373

_______________

Романова Е. С.

Преподаватель

_______________

Матвеева И.В.

Санкт-Петербург

2022

Цель работы.

Реализовать алгоритм трассировки лучей при формировании сложной сцены.

Задание на работу.

Необходимо написать программу в которой реализуется алгоритм трассировки лучей для сложной сцены с тремя сферами.

Общие сведения.

Для выполнения работы потребовались следующие теоретические

сведения.

Трассировка лучей – один из методов геометрической оптики – исследование оптических систем путём отслеживания взаимодействия отдельных лучей с поверхностями. В узком смысле - технология построения изображения трёхмерных моделей в компьютерных программах, при которых отслеживается обратная траектория распространения луча (от экрана к

источнику).

Трассировка лучей в компьютерных играх – это решение для создания реалистичного освещения, отражений и теней, обеспечивающее более высокий уровень реализма по сравнению с традиционными способами

рендеринга.

 

 

Пусть у нас есть две точки

и

– независимо от размерности:

1, 2, 3, … , , тогда вектор, идущий

от

к , может быть найден путем

поэлементного вычитания из .

Длину вектора – независимо от его размерности – можно найти,

вычислив квадратный корень из суммы возведенных в квадрат компонентов.

Длина вектора обозначается || ||.

Единичный вектор — это вектор длины 1: || || = 1.

2

Для данного вектора другой вектор, идущий в том же направлении, но имеющий длину 1, может быть найден путем деления каждого компонента первого вектора на его длину — это называется нормализацией: = || ||.

Скалярное произведение для векторов вычисляется как: , = || ||².

Ход работы.

Рассмотрим работу программы, которая заключается в взятии значений из полей и вызове функции отрисовки изображения с посредствующим вызовом окошка для отображения получавшегося изображения.

Выполнение работы.

Ссылка на видео с демонстрацией работы программы: https://www.youtube.com/watch?v=J7k6sftALfM

Программа была написана в приложении Jupiter на языке Python с

использованием графических библиотек.

Для работы с программой необходимо ввести координаты и радиус сфер в соответствующие для этого поля и цвет для каждой сферы, также следует указать высоту изображения, а затем нажать на «Обновить значения» и «Нарисовать сцену». Так как данный процесс занимает время, то под

«Загрузка», будет двигаться ползунок. Когда он достигнет конца строки, то появится окошко и изображением. Кнопка «Обнулить значения» обнуляется все поля ввода.

Тесты работы программы.

На рис.1 – 3 представлены результаты выполнения работы программы:

3

Рисунок 1 – Трассировка лучей сложной сцены с тремя сферами с высотой 100

Рисунок 2 – Трассировка лучей сложной сцены с тремя сферами с высотой 200

4

Рисунок 3 – Трассировка лучей сложной сцены без сфер

Выводы.

В данной работе была реализована программа трассировки лучей при формировании сложной сцены, состоящий из трех сфер, с возможностью регулировки высоты изображения.

5

ПРИЛОЖЕНИЕ А

Файл «Komp_GR_6.ipynb»

import tkinter

from tkinter import StringVar import tkinter.messagebox import customtkinter as ctk from vector import *

from color import * from start import * import numpy

ctk.set_appearance_mode("Light") ctk.set_default_color_theme("green")

class App(ctk.CTk): WIDTH = 780 HEIGHT = 660

def __init__(self): super().__init__()

self.x1 = StringVar(value="-3.0") self.y1 = StringVar(value="1.0") self.z1 = StringVar(value="1.0") self.x2 = StringVar(value="0.0") self.y2 = StringVar(value="1.0") self.z2 = StringVar(value="1.0") self.x3 = StringVar(value="2.0") self.y3 = StringVar(value="1.0") self.z3 = StringVar(value="1.0") self.sph_c = [

[self.x1, self.y1, self.z1], [self.x2, self.y2, self.z2], [self.x3, self.y3, self.z3]

]

self.r1 = StringVar(value="2.0") self.g1 = StringVar(value="2.0") self.b1 = StringVar(value="2.0") self.r2 = StringVar(value="1.0") self.g2 = StringVar(value="1.0")

6

self.b2 = StringVar(value="1.0") self.r3 = StringVar(value="1.0") self.g3 = StringVar(value="2.") self.b3 = StringVar(value="2.0") self.sph_col = [

[self.r1, self.g1, self.b1], [self.r2, self.g2, self.b2], [self.r3, self.g3, self.b3]

]

self.width_im = StringVar(value="100") self.height = int(self.width_im.get()) self.width = int(self.height*16.0/9.0)

self.spheres = [Sphere(vect3(0, -1000, 0), vect3(1, 1, 1), 1000), Sphere(vect3(-3,1,1), vect3(2,2,2), 1), Sphere(vect3(0,1,1), vect3(1,1,1), 0.8), Sphere(vect3(2,1,1), vect3(1,2,2), 0.6),

]

# light sources

self.lights = [Sphere(vect3(0, 100, 0), vect3(0.0, 0.1, 0.2), 0), Sphere(vect3(100, 100, 200), vect3(0.3, 0.1, 0), 0), Sphere(vect3(-100, 100, 200), vect3(0.1, 0.3, 0.0), 0)]

self.title("Работа №6") self.geometry(f"{App.WIDTH}x{App.HEIGHT}") self.protocol("WM_DELETE_WINDOW", self.on_closing) # call

.on_closing() when app gets closed

# ============ create two frames ============

self.grid_columnconfigure(1, weight=1) self.grid_rowconfigure(0, weight=1)

self.frame_left = ctk.CTkFrame(master=self, width=180, corner_radius=0)

self.frame_left.grid(row=0, column=0, sticky="nswe")

self.frame_right = ctk.CTkFrame(master=self) self.frame_right.grid(row=0, column=1, sticky="nswe", padx=20,

pady=20)

# ============ frame_left ============

7

self.frame_left.grid_rowconfigure(0, minsize=10)

# empty row with

minsize as spacing

 

self.frame_left.grid_rowconfigure(5, weight=1) #

empty row as

spacing

 

self.frame_left.grid_rowconfigure(8, minsize=20)

# empty row with

minsize as spacing

 

self.frame_left.grid_rowconfigure(11, minsize=10)

# empty row with

minsize as spacing

 

self.label_1 = ctk.CTkLabel(master=self.frame_left, text="Значения",

text_font=("Roboto Medium", -16)) # font

name and size in px

self.label_1.grid(row=7, column=0, pady=10, padx=10)

self.button_1 = ctk.CTkButton(master=self.frame_left, text="Обновить значения", command = self.apply)

self.button_1.grid(row=8, column=0, pady=10, padx=20)

self.button_2 = ctk.CTkButton(master=self.frame_left, text="Обнулить значения", command=self.reset)

self.button_2.grid(row=9, column=0, pady=10, padx=20)

#============ frame_right ============

#configure grid layout (3x7)

self.frame_right.rowconfigure((0, 1, 2, 3), weight=1) self.frame_right.rowconfigure(7, weight=10) self.frame_right.columnconfigure((0, 1), weight=1) self.frame_right.columnconfigure(2, weight=0)

self.frame_info = ctk.CTkFrame(master=self.frame_right) self.frame_info.grid(row=0, column=0, columnspan=4, rowspan=4,

pady=20, padx=20, sticky="nsew")

#============ frame_info ============

#configure grid layout (1x1)

8

self.frame_info.rowconfigure(0, weight=1) self.frame_info.columnconfigure(0, weight=1)

self.label_info_1 = ctk.CTkLabel(master=self.frame_info, text="Загрузка...", text_font=("Roboto Medium", -16), height=100,

corner_radius=6, # <- custom corner

radius

fg_color=("#9de0b4", "gray38"), #

<- custom tuple-color

justify=tkinter.LEFT) self.label_info_1.grid(column=0, row=0, sticky="nwe", padx=15,

pady=15)

self.progressbar = ctk.CTkProgressBar(master=self.frame_info) self.progressbar.grid(row=1, column=0, sticky="ew", padx=15, pady=15) self.progressbar.set(0)

# ============ frame_right ============

self.radio_var = tkinter.IntVar(value=0)

self.sphere = ctk.CTkLabel(master=self.frame_right,

text="Введите координаты и радиус сфер

",

text_font=("Roboto Medium", -16)) # font

name and size in px

self.sphere.grid(row=4, column=0, pady=5, padx=0)

 

self.sphere_col = ctk.CTkLabel(master=self.frame_right,

 

text="

Введите цвет сфер

",

text_font=("Roboto Medium", -16))

#

font name and size in px

 

 

self.sphere_col.grid(row=8, column=0, pady=0, padx=0, sticky="w")

 

self.sphere_col = ctk.CTkLabel(master=self.frame_right,

 

text="

Высота изображения

 

(16:9) ",

 

 

text_font=("Roboto Medium", -16))

#

font name and size in px

self.sphere_col.grid(row=12, column=0, pady=0, padx=0, sticky="wn")

9

self.entry0 = ctk.CTkEntry(master=self.frame_right,

width=80, textvariable=self.x1, validate =

"all")

self.entry0.grid(row=5, column=0, columnspan=2, pady=-0, padx=20, sticky="w")

self.entry1 = ctk.CTkEntry(master=self.frame_right, width=50, textvariable=self.y1)

self.entry1.grid(row=5, column=0, columnspan=2, pady=-0, padx=145, sticky="we")

self.entry2 = ctk.CTkEntry(master=self.frame_right, width=80,

textvariable=self.z1) self.entry2.grid(row=5, column=0, columnspan=2, pady=0, padx=20,

sticky="e")

self.label_number_sphere_1 = ctk.CTkLabel(master=self.frame_right, text="Первая сфера")

self.label_number_sphere_1.grid(row=5, column=0,columnspan=4, pady=0, padx=20, sticky="e")

self.entry00 = ctk.CTkEntry(master=self.frame_right, width=80,

textvariable=self.x2) self.entry00.grid(row=6, column=0, columnspan=2, pady=0, padx=20,

sticky="w")

self.entry11 = ctk.CTkEntry(master=self.frame_right, width=50,

textvariable=self.y2) self.entry11.grid(row=6, column=0, columnspan=2, pady=0, padx=145,

sticky="we")

self.entry22 = ctk.CTkEntry(master=self.frame_right, width=80,

textvariable=self.z2) self.entry22.grid(row=6, column=0, columnspan=2, pady=0, padx=20,

sticky="e")

10