메뉴 닫기

VTK 조명(Lighting)

광선이 공간을 통과하면서 일부는 사물에 부딪치면서 상호 작용하여 색상이 나타납니다. 사실 색상의 일부는 직사광 때문이 아니라 다른 물체에서 반사되거나 산란되는 주변광에 영향을 받습니다.

  • Ambient light (주변광/환경광): 광원이 아닌 다른 물체에서 반사되거나 산란되는 빛 (간접조명)
  • Diffuse light (산란광/난반사광/분산광): 물체에 빛이 닿을 때, 여러방향으로 반사되는 것(난반사)을 나타내는 빛
  • Specular light(정반사광): 물체에 빛이 닿을 때 특정 방향으로만 반사되는 빛. 즉, 광원이 직접 반사되는 하이라이트 지점을 나타내는 빛

실행 결과



  •  Ambient light 변화 확인: Red sphere
  •  Diffuse light 변화 확인: Blue sphere
  •  Specular light 변화 확인: Green sphere
  •  Specular power (=shininess factor) 변화 확인: 왼쪽 → 오른쪽

예제 코드

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkLight.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>

#include <array>

int main(int, char*[])
{
	vtkNew<vtkNamedColors> colors;

	std::array<unsigned char, 4> bkg{{26, 51, 102, 255}};
	colors->SetColor("bkg", bkg.data());

	vtkNew<vtkSphereSource> sphere;
	sphere->SetThetaResolution(100);
	sphere->SetPhiResolution(50);
	
	vtkNew<vtkPolyDataMapper> sphereMapper;
	sphereMapper->SetInputConnection(sphere->GetOutputPort());

	auto const numberOfSpheres = 12;
	std::array<vtkNew<vtkActor>, numberOfSpheres> spheres;
	auto ambient = 0.4;
	auto diffuse = 0.4;
	auto specular = 0.4;
	auto spBase = 5.0;
	auto spScale = 1.0;
	std::array<double, 3> position{{0, 0, 0}};
	
	// Ambient light
	for (auto i = 0; i < 4; ++i)
	{
		auto specularPower = spBase * spScale;
		spheres[i]->SetMapper(sphereMapper);
		spheres[i]->GetProperty()->SetColor(colors->GetColor3d("Red").GetData());
		spheres[i]->GetProperty()->SetAmbient(ambient);
		spheres[i]->GetProperty()->SetDiffuse(diffuse);
		spheres[i]->GetProperty()->SetSpecular(specular);
		spheres[i]->GetProperty()->SetSpecularPower(specularPower);
		spheres[i]->GetProperty()->SetSpecularColor(
			colors->GetColor3d("White").GetData());
		spheres[i]->AddPosition(position.data());
		spScale = spScale * 2.0;
		position[0] += 1.25;
		ambient += 0.2;
	}

	ambient = 0.4;
	spScale = 1.0;
	position[0] = 0;
	position[1] = 1.25;

	// Diffuse light
	for (auto i = 4; i < 8; i++)
	{
		auto specularPower = spBase * spScale;
		spheres[i]->SetMapper(sphereMapper);
		spheres[i]->GetProperty()->SetColor(colors->GetColor3d("Blue").GetData());
		spheres[i]->GetProperty()->SetAmbient(ambient);
		spheres[i]->GetProperty()->SetDiffuse(diffuse);
		spheres[i]->GetProperty()->SetSpecular(specular);
		spheres[i]->GetProperty()->SetSpecularPower(specularPower);
		spheres[i]->GetProperty()->SetSpecularColor(
			colors->GetColor3d("White").GetData());
		spheres[i]->AddPosition(position.data());
		spScale = spScale * 2.0;
		position[0] += 1.25;
		diffuse += 0.2;
	}

	diffuse = 0.4;
	spScale = 1.0;
	position[0] = 0;
	position[1] = 2.5;

	// Specular light
	for (auto i = 8; i < 12; i++)
	{
		auto specularPower = spBase * spScale;
		spheres[i]->SetMapper(sphereMapper);
		spheres[i]->GetProperty()->SetColor(colors->GetColor3d("Green").GetData());
		spheres[i]->GetProperty()->SetAmbient(ambient);
		spheres[i]->GetProperty()->SetDiffuse(diffuse);
		spheres[i]->GetProperty()->SetSpecular(specular);
		spheres[i]->GetProperty()->SetSpecularPower(specularPower);
		spheres[i]->GetProperty()->SetSpecularColor(
			colors->GetColor3d("White").GetData());
		spheres[i]->AddPosition(position.data());
		spScale = spScale * 2.0;
		position[0] += 1.25;
		specular += 0.2;
	}

	vtkNew<vtkRenderer> ren;
	vtkNew<vtkRenderWindow> renWin;
	renWin->AddRenderer(ren);
	vtkNew<vtkRenderWindowInteractor> iren;
	iren->SetRenderWindow(renWin);
	
	for (auto i = 0; i < numberOfSpheres; ++i)
	{
		ren->AddActor(spheres[i]);
	}
	
	ren->SetBackground(colors->GetColor3d("bkg").GetData());
	renWin->SetSize(640, 640);
	renWin->SetWindowName("Specular Spheres");
	
	vtkNew<vtkLight> light;
	light->SetFocalPoint(1.875, 0.6125, 0);
	light->SetPosition(0.875, 1.6125, 1);
	ren->AddLight(light);

	ren->GetActiveCamera()->SetFocalPoint(0, 0, 0);
	ren->GetActiveCamera()->SetPosition(0, 0, 1);
	ren->GetActiveCamera()->SetViewUp(0, 1, 0);
	ren->GetActiveCamera()->ParallelProjectionOn();
	ren->ResetCamera();
	ren->GetActiveCamera()->SetParallelScale(3.0);
	
	iren->Initialize();
	renWin->Render();
	iren->Start();
	
	return EXIT_SUCCESS;
}

* Reference

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다