1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestOSPRayLights.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 // This test verifies that lighting works as expected with ospray.
16 // When advanced materials are exposed in ospray, it will also validate
17 // refractions and reflections
18 //
19 // The command line arguments are:
20 // -I => run in interactive mode; unless this is used, the program will
21 // not allow interaction and exit
22 // In interactive mode it responds to the keys listed
23 // vtkOSPRayTestInteractor.h
24
25 #include "vtkTestUtilities.h"
26
27 #include "vtkActor.h"
28 #include "vtkCamera.h"
29 #include "vtkLight.h"
30 #include "vtkOSPRayPass.h"
31 #include "vtkOSPRayRendererNode.h"
32 #include "vtkOpenGLRenderer.h"
33 #include "vtkPLYReader.h"
34 #include "vtkPlaneSource.h"
35 #include "vtkPolyDataMapper.h"
36 #include "vtkPolyDataNormals.h"
37 #include "vtkProperty.h"
38 #include "vtkRenderWindow.h"
39 #include "vtkRenderWindowInteractor.h"
40 #include "vtkRenderer.h"
41 #include "vtkSmartPointer.h"
42 #include "vtkSphereSource.h"
43
44 #include "vtkOSPRayTestInteractor.h"
45
TestOSPRayLights(int argc,char * argv[])46 int TestOSPRayLights(int argc, char* argv[])
47 {
48 vtkSmartPointer<vtkRenderWindowInteractor> iren =
49 vtkSmartPointer<vtkRenderWindowInteractor>::New();
50 vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
51 iren->SetRenderWindow(renWin);
52 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
53 renderer->AutomaticLightCreationOff();
54 renWin->AddRenderer(renderer);
55
56 const char* fileName = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/bunny.ply");
57 vtkSmartPointer<vtkPLYReader> polysource = vtkSmartPointer<vtkPLYReader>::New();
58 polysource->SetFileName(fileName);
59
60 // measure so we can place things sensibly
61 polysource->Update();
62 double bds[6];
63 polysource->GetOutput()->GetBounds(bds);
64 double x0 = bds[0] * 2;
65 double x1 = bds[1] * 2;
66 double y0 = bds[2];
67 double y1 = bds[3] * 2;
68 double z0 = bds[4];
69 double z1 = bds[5] * 4;
70
71 // TODO: ospray acts strangely without these such that Diff and Spec are not 0..255 instead of
72 // 0..1
73 vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
74 normals->SetInputConnection(polysource->GetOutputPort());
75
76 const double DIFF = 0.7;
77 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
78 mapper->SetInputConnection(normals->GetOutputPort());
79 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
80 actor->SetMapper(mapper);
81 actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
82 actor->GetProperty()->SetDiffuse(DIFF);
83 actor->GetProperty()->SetSpecularColor(1, 1, 1);
84 actor->GetProperty()->SetSpecular(0.9);
85 actor->GetProperty()->SetSpecularPower(500);
86 renderer->AddActor(actor);
87
88 vtkSmartPointer<vtkPlaneSource> backwall = vtkSmartPointer<vtkPlaneSource>::New();
89 backwall->SetOrigin(x0, y0, z0);
90 backwall->SetPoint1(x1, y0, z0);
91 backwall->SetPoint2(x0, y1, z0);
92 mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
93 mapper->SetInputConnection(backwall->GetOutputPort());
94 actor = vtkSmartPointer<vtkActor>::New();
95 actor->SetMapper(mapper);
96 actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
97 actor->GetProperty()->SetDiffuse(DIFF);
98 actor->GetProperty()->SetSpecular(0);
99 renderer->AddActor(actor);
100
101 vtkSmartPointer<vtkPlaneSource> floor = vtkSmartPointer<vtkPlaneSource>::New();
102 floor->SetOrigin(x0, y0, z0);
103 floor->SetPoint1(x0, y0, z1);
104 floor->SetPoint2(x1, y0, z0);
105 mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
106 mapper->SetInputConnection(floor->GetOutputPort());
107 actor = vtkSmartPointer<vtkActor>::New();
108 actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
109 actor->GetProperty()->SetDiffuse(DIFF);
110 actor->GetProperty()->SetSpecular(0);
111 actor->SetMapper(mapper);
112 renderer->AddActor(actor);
113
114 vtkSmartPointer<vtkPlaneSource> left = vtkSmartPointer<vtkPlaneSource>::New();
115 left->SetOrigin(x0, y0, z0);
116 left->SetPoint1(x0, y1, z0);
117 left->SetPoint2(x0, y0, z1);
118 mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
119 mapper->SetInputConnection(left->GetOutputPort());
120 actor = vtkSmartPointer<vtkActor>::New();
121 actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
122 actor->GetProperty()->SetDiffuse(DIFF);
123 actor->GetProperty()->SetSpecular(0);
124 actor->SetMapper(mapper);
125 renderer->AddActor(actor);
126
127 vtkSmartPointer<vtkSphereSource> magnifier = vtkSmartPointer<vtkSphereSource>::New();
128 magnifier->SetCenter(x0 + (x1 - x0) * 0.6, y0 + (y1 - y0) * 0.2, z0 + (z1 - z0) * 0.7);
129 magnifier->SetRadius((x1 - x0) * 0.05);
130 magnifier->SetPhiResolution(30);
131 magnifier->SetThetaResolution(30);
132 mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
133 mapper->SetInputConnection(magnifier->GetOutputPort());
134 actor = vtkSmartPointer<vtkActor>::New();
135 actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
136 actor->GetProperty()->SetInterpolationToPBR();
137 actor->GetProperty()->SetMetallic(0.0);
138 actor->GetProperty()->SetRoughness(0.1);
139 actor->SetMapper(mapper);
140 renderer->AddActor(actor);
141
142 vtkSmartPointer<vtkSphereSource> discoball = vtkSmartPointer<vtkSphereSource>::New();
143 discoball->SetCenter(x0 + (x1 - x0) * 0.5, y0 + (y1 - y0) * 0.85, z0 + (z1 - z0) * 0.5);
144 discoball->SetRadius((x1 - x0) * 0.1);
145 discoball->SetPhiResolution(30);
146 discoball->SetThetaResolution(30);
147 mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
148 mapper->SetInputConnection(discoball->GetOutputPort());
149 actor = vtkSmartPointer<vtkActor>::New();
150 actor->GetProperty()->SetColor(1.0, 1.0, 1.0);
151 actor->GetProperty()->SetMetallic(1.0);
152 actor->GetProperty()->SetRoughness(0.1);
153 actor->SetMapper(mapper);
154 renderer->AddActor(actor);
155
156 #define INTENS 0.2
157
158 vtkSmartPointer<vtkLight> light = vtkSmartPointer<vtkLight>::New();
159 // blue light casting shadows from infinity toward bottom left back corner
160 light->PositionalOff();
161 light->SetPosition(x0 + (x1 - x0) * 1, y0 + (y1 - y0) * 1, z0 + (z1 + z0) * 1);
162 light->SetFocalPoint(x0, y0, z0);
163 light->SetLightTypeToSceneLight();
164 light->SetColor(0.0, 0.0, 1.0);
165 light->SetIntensity(INTENS);
166 light->SwitchOn();
167 renderer->AddLight(light);
168
169 light = vtkSmartPointer<vtkLight>::New();
170 // red light casting shadows from top to bottom
171 light->PositionalOn();
172 double t = 1.8; // adjust t to see effect of positional
173 light->SetPosition(x0 + (x1 - x0) * 0.5, y0 + (y1 - y0) * t, z0 + (z1 - z0) * 0.5);
174 light->SetFocalPoint(x0 + (x1 - x0) * 0.5, y0 + (y1 - y0) * 0, z0 + (z1 - z0) * 0.5);
175 light->SetLightTypeToSceneLight();
176 light->SetColor(1.0, 0.0, 0.0);
177 light->SetIntensity(INTENS);
178 light->SwitchOn();
179 renderer->AddLight(light);
180
181 light = vtkSmartPointer<vtkLight>::New();
182 // green light following camera
183 light->PositionalOn();
184 light->SetLightTypeToHeadlight();
185 light->SetColor(0.0, 1.0, 0.0);
186 light->SetIntensity(INTENS);
187 light->SwitchOn();
188 renderer->AddLight(light);
189
190 renderer->SetBackground(0.0, 0.0, 0.0);
191 renWin->SetSize(400, 400);
192
193 vtkSmartPointer<vtkOSPRayPass> ospray = vtkSmartPointer<vtkOSPRayPass>::New();
194 renderer->SetPass(ospray);
195 vtkOSPRayRendererNode::SetRendererType("OSPRay pathtracer", renderer);
196
197 for (int i = 0; i < argc; ++i)
198 {
199 if (!strcmp(argv[i], "--OptiX"))
200 {
201 vtkOSPRayRendererNode::SetRendererType("optix pathtracer", renderer);
202 break;
203 }
204 }
205
206 // increase image quality from default (otherwise subsampling artifacts)
207 renWin->Render();
208 renderer->UseShadowsOn();
209 vtkOSPRayRendererNode::SetMaxFrames(0, renderer);
210 vtkOSPRayRendererNode::SetSamplesPerPixel(20, renderer);
211
212 vtkSmartPointer<vtkOSPRayTestInteractor> style = vtkSmartPointer<vtkOSPRayTestInteractor>::New();
213 style->SetPipelineControlPoints(renderer, ospray, nullptr);
214 iren->SetInteractorStyle(style);
215 style->SetCurrentRenderer(renderer);
216
217 iren->Start();
218
219 return 0;
220 }
221