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