diff --git a/examples/frontier_benchmark/FrontierBenchmark.cxx b/examples/frontier_benchmark/FrontierBenchmark.cxx index 6d0179bb7..3392ecbfa 100644 --- a/examples/frontier_benchmark/FrontierBenchmark.cxx +++ b/examples/frontier_benchmark/FrontierBenchmark.cxx @@ -30,6 +30,16 @@ #include #include +#include +#include +#include +#include + +const static std::string PERLIN_MODE_GROW = "grow"; +const static std::string PERLIN_MODE_SUBDIVIDE = "subdivide"; +const static std::string CAMERA_MODE_STATIC = "static"; +const static std::string CAMERA_MODE_ORBIT = "orbit"; + struct BenchmarkOptions { BenchmarkOptions(int argc, char** argv) { this->Parse(argc, argv); } @@ -42,11 +52,15 @@ struct BenchmarkOptions auto seperatorPos = arg.find('='); if (seperatorPos == std::string::npos) { - continue; + seperatorPos = arg.size(); } - auto key = arg.substr(0, seperatorPos); - auto val = arg.substr(seperatorPos + 1); + std::string key = arg.substr(0, seperatorPos); + std::string val = ""; + if (seperatorPos != std::string::npos && seperatorPos + 1 < arg.size()) + { + val = arg.substr(seperatorPos + 1); + } if (key == "--perlin-dims") { @@ -63,6 +77,14 @@ struct BenchmarkOptions { this->PerlinSeed = std::stoi(val); } + else if (key == "--perlin-mode") + { + this->PerlinMode = val; + } + else if (key == "--perlin-scale") + { + this->PerlinScale = std::stof(val); + } else if (key == "--width") { this->CanvasWidth = std::stoi(val); @@ -79,14 +101,31 @@ struct BenchmarkOptions { this->TimingFileName = val; } + else if (key == "--camera-mode") + { + this->CameraMode = val; + } + else if (key == "--image-format") + { + this->ImageFormat = val; + } + else if (key == "--show-args") + { + this->ShowArgs = true; + } } } vtkm::Id3 PerlinDimensions = vtkm::Id3(1024, 1024, 1024); vtkm::IdComponent PerlinSeed = 1; + std::string PerlinMode = PERLIN_MODE_GROW; + vtkm::Float32 PerlinScale = 3.0f; vtkm::Id CanvasWidth = 1920; vtkm::Id CanvasHeight = 1080; vtkm::Id NumIterations = 10; std::string TimingFileName = "timing.csv"; + std::string ImageFormat = "png"; + std::string CameraMode = CAMERA_MODE_STATIC; + bool ShowArgs = false; }; struct MpiTopology @@ -133,8 +172,21 @@ std::string GetImageName(const std::string& prefix, const MpiTopology& mpiTopology) { std::stringstream ss; - ss << prefix << "_" << options.CanvasWidth << "x" << options.CanvasHeight << "_" - << mpiTopology.Size << ".png"; + ss << options.CameraMode << "/" << prefix << "_" << options.PerlinMode << "_" + << options.CanvasWidth << "x" << options.CanvasHeight << "_" << mpiTopology.Size << "." + << options.ImageFormat; + return ss.str(); +} + +std::string GetFrameName(const std::string& prefix, + int frameNumber, + const BenchmarkOptions& options, + const MpiTopology& mpiTopology) +{ + std::stringstream ss; + ss << options.CameraMode << "/" << prefix << "_" << options.PerlinMode << "_" << mpiTopology.Size + << "_" << options.CameraMode << "_frame_" << std::setw(4) << std::setfill('0') << frameNumber + << "." << options.ImageFormat; return ss.str(); } @@ -231,31 +283,66 @@ void GenerateDataSet(const BenchmarkOptions& options, // Perlin Noise does not generate "interesting" surfaces when the scale is too small, .i.e, // X, Y, Z values are too close to each other. Hence we scale the perlin noise by a factor - vtkm::FloatDefault scale = 3.0f; - vtkm::Vec3f origin = { mpiTopology.XRank * scale, - mpiTopology.YRank * scale, - mpiTopology.ZRank * scale }; - vtkm::Vec3f maxExtent = origin + vtkm::Vec3f{ scale, scale, scale }; - perlin.SetOrigin(origin); - perlin.SetMaxExtent(maxExtent); - dataSet = perlin.Execute(); + if (options.PerlinMode == PERLIN_MODE_GROW) + { + vtkm::Vec3f origin = vtkm::Vec3f_32{ static_cast(mpiTopology.XRank), + static_cast(mpiTopology.YRank), + static_cast(mpiTopology.ZRank) } * + options.PerlinScale; + vtkm::Vec3f maxExtent = origin + vtkm::Vec3f{ options.PerlinScale }; + perlin.SetOrigin(origin); + perlin.SetMaxExtent(maxExtent); + dataSet = perlin.Execute(); + } + else if (options.PerlinMode == PERLIN_MODE_SUBDIVIDE) + { + vtkm::Vec3f_32 blockSpacing = vtkm::Vec3f_32{ options.PerlinScale } * + vtkm::Vec3f_32{ 1.0f / static_cast(mpiTopology.XSize), + 1.0f / static_cast(mpiTopology.YSize), + 1.0f / static_cast(mpiTopology.ZSize) }; + vtkm::Vec3f_32 origin = vtkm::Vec3f_32{ static_cast(mpiTopology.XRank), + static_cast(mpiTopology.YRank), + static_cast(mpiTopology.ZRank) } * + blockSpacing; + vtkm::Vec3f_32 maxExtent = origin + blockSpacing; + + perlin.SetOrigin(origin); + perlin.SetMaxExtent(maxExtent); + dataSet = perlin.Execute(); + } + + std::vector isoValues{ 0.4f, 0.75f }; vtkm::filter::contour::Contour contour; - contour.SetNumberOfIsoValues(1); - contour.SetIsoValue(0, 0.5f); + contour.SetIsoValues(isoValues); contour.SetActiveField(fieldName); dataSet = contour.Execute(dataSet); globalFiendRange = { 0.0f, 1.0f }; - globalBounds = { vtkm::Vec3f{ 0.0f, 0.0f, 0.0f }, - vtkm::Vec3f{ static_cast(mpiTopology.XSize), - static_cast(mpiTopology.YSize), - static_cast(mpiTopology.ZSize) } * - scale }; - vtkm::Float64 boundsEps = 0.1f; + if (options.PerlinMode == PERLIN_MODE_GROW) + { + globalBounds = { vtkm::Vec3f{ 0.0f, 0.0f, 0.0f }, + vtkm::Vec3f{ static_cast(mpiTopology.XSize), + static_cast(mpiTopology.YSize), + static_cast(mpiTopology.ZSize) } * + options.PerlinScale }; + } + else if (options.PerlinMode == PERLIN_MODE_SUBDIVIDE) + { + globalBounds = { vtkm::Vec3f{ 0.0f }, vtkm::Vec3f{ options.PerlinScale } }; + } + + // Add a small epsilon to the bounds to prevent the world annotations from being clipped + /* + vtkm::Float64 boundsEps = 0.0f; + if (options.CameraMode == CAMERA_MODE_ORBIT) + { + boundsEps = 0.2f; + } globalBounds.Include(globalBounds.MinCorner() - vtkm::Vec3f_64{ boundsEps, boundsEps, boundsEps }); globalBounds.Include(globalBounds.MaxCorner() + vtkm::Vec3f_64{ boundsEps, boundsEps, boundsEps }); + */ } void RunBenchmark(const BenchmarkOptions& options) @@ -280,28 +367,61 @@ void RunBenchmark(const BenchmarkOptions& options) vtkm::rendering::Camera camera; camera.ResetToBounds(globalBounds); - camera.Azimuth(10.0f); - camera.Elevation(20.0f); - std::vector benchmarkTimes; vtkm::rendering::CanvasRayTracer canvas(options.CanvasWidth, options.CanvasHeight); - for (int iter = 0; iter < options.NumIterations; iter++) + + if (options.CameraMode == CAMERA_MODE_STATIC) { - vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f); - vtkm::rendering::View3D view(scene, vtkm::rendering::MapperRayTracer(), canvas, camera, bg); - view.Paint(); - if (comm.rank() == 0) + camera.Azimuth(10.0f); + camera.Elevation(20.0f); + std::vector benchmarkTimes; + for (int iter = 0; iter < options.NumIterations; iter++) { - benchmarkTimes.push_back( - IterationTimes{ .RenderTime = view.GetTimes()[vtkm::rendering::RENDER_TIME_KEY], - .CompositeTime = view.GetTimes()[vtkm::rendering::COMPOSITE_TIME_KEY], - .TotalTime = view.GetTimes()[vtkm::rendering::TOTAL_TIME_KEY] }); + vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f); + vtkm::rendering::View3D view(scene, vtkm::rendering::MapperRayTracer(), canvas, camera, bg); + view.Paint(); + if (comm.rank() == 0) + { + benchmarkTimes.push_back( + IterationTimes{ .RenderTime = view.GetTimes()[vtkm::rendering::RENDER_TIME_KEY], + .CompositeTime = view.GetTimes()[vtkm::rendering::COMPOSITE_TIME_KEY], + .TotalTime = view.GetTimes()[vtkm::rendering::TOTAL_TIME_KEY] }); + } + } + SaveTimeStats(benchmarkTimes, options, mpiTopology); + if (mpiTopology.Rank == 0) + { + canvas.SaveAs(GetImageName("perlin_static", options, mpiTopology)); } } + else if (options.CameraMode == CAMERA_MODE_ORBIT) + { + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_real_distribution dist(0.0, 1.0); + vtkm::Float64 dirX = -1.0f; + for (int iter = 0; iter < options.NumIterations; iter++) + { + vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f); + vtkm::rendering::View3D view(scene, vtkm::rendering::MapperRayTracer(), canvas, camera, bg); + view.Paint(); - SaveTimeStats(benchmarkTimes, options, mpiTopology); + if (mpiTopology.Rank == 0) + { + canvas.SaveAs(GetFrameName("perlin_movie", iter, options, mpiTopology)); + } - canvas.SaveAs(GetImageName("perlin_surface", options, mpiTopology)); + vtkm::Float64 speedX = 0.01f * dirX; + vtkm::Float64 speedY = 0.0f; + camera.TrackballRotate(0.0, 0.0, speedX, speedY); + + if (mpiTopology.Rank == 0 && iter > 0 && (iter + 1) % 10 == 0) + { + std::cerr << "Frame " << (iter + 1) << " of " << options.NumIterations << " done" + << std::endl; + } + } + } } int main(int argc, char* argv[]) @@ -317,6 +437,21 @@ int main(int argc, char* argv[]) vtkm::cont::Initialize(argc, argv, vtkm::cont::InitializeOptions::None); BenchmarkOptions options(argc, argv); + if (options.ShowArgs) + { + std::cerr << std::boolalpha; + std::cerr << argv[0] << ":" << std::endl; + std::cerr << "\tPerlin Dimensions: " << options.PerlinDimensions << std::endl; + std::cerr << "\tPerlin Seed: " << options.PerlinSeed << std::endl; + std::cerr << "\tCanvas Width: " << options.CanvasWidth << std::endl; + std::cerr << "\tCanvas Height: " << options.CanvasHeight << std::endl; + std::cerr << "\tNum Iterations: " << options.NumIterations << std::endl; + std::cerr << "\tTiming File: " << options.TimingFileName << std::endl; + std::cerr << "\tCamera Mode: " << options.CameraMode << std::endl; + std::cerr << "\tShow Args: " << options.ShowArgs << std::endl; + std::cerr << std::noboolalpha; + } + RunBenchmark(options); return 0; } \ No newline at end of file diff --git a/vtkm/rendering/MapperRayTracer.cxx b/vtkm/rendering/MapperRayTracer.cxx index 8af3710d1..3eccea38b 100644 --- a/vtkm/rendering/MapperRayTracer.cxx +++ b/vtkm/rendering/MapperRayTracer.cxx @@ -149,6 +149,11 @@ void MapperRayTracer::SetShadingOn(bool on) this->Internals->Shade = on; } +void MapperRayTracer::SetLightPosition(const vtkm::Vec3f_32& lightPosition) +{ + // this->Internals->Tracer.SetLightPosition(lightPosition); +} + vtkm::rendering::Mapper* MapperRayTracer::NewCopy() const { return new vtkm::rendering::MapperRayTracer(*this); diff --git a/vtkm/rendering/MapperRayTracer.h b/vtkm/rendering/MapperRayTracer.h index a3427a6e7..dd2b5c011 100644 --- a/vtkm/rendering/MapperRayTracer.h +++ b/vtkm/rendering/MapperRayTracer.h @@ -42,6 +42,8 @@ public: vtkm::rendering::Mapper* NewCopy() const override; void SetShadingOn(bool on); + void SetLightPosition(const vtkm::Vec3f_32& lightPosition); + private: struct InternalsType; std::shared_ptr Internals; diff --git a/vtkm/rendering/View.cxx b/vtkm/rendering/View.cxx index f99e5f87e..5d84ddb96 100644 --- a/vtkm/rendering/View.cxx +++ b/vtkm/rendering/View.cxx @@ -183,9 +183,6 @@ void View::RenderAnnotations() { if (this->RenderAnnotationsEnabled) { - this->SetupForScreenSpace(); - this->RenderScreenAnnotations(); - this->GetCanvas().BeginTextRenderingBatch(); for (auto& textAnnotation : this->Internal->TextAnnotations) { @@ -203,6 +200,9 @@ void View::RenderAnnotations() { this->RenderWorldAnnotations(); } + + this->SetupForScreenSpace(); + this->RenderScreenAnnotations(); } } diff --git a/vtkm/rendering/raytracing/RayTracer.cxx b/vtkm/rendering/raytracing/RayTracer.cxx index 49b512892..3692534bf 100644 --- a/vtkm/rendering/raytracing/RayTracer.cxx +++ b/vtkm/rendering/raytracing/RayTracer.cxx @@ -56,16 +56,18 @@ public: , LookAt(lookAt) { //Set up some default lighting parameters for now - LightAbmient[0] = .5f; - LightAbmient[1] = .5f; - LightAbmient[2] = .5f; - LightDiffuse[0] = .7f; - LightDiffuse[1] = .7f; - LightDiffuse[2] = .7f; - LightSpecular[0] = .7f; - LightSpecular[1] = .7f; - LightSpecular[2] = .7f; - SpecularExponent = 20.f; + LightAbmient[0] = 0.1f; + LightAbmient[1] = 0.1f; + LightAbmient[2] = 0.1f; + + LightDiffuse[0] = 1.0f; + LightDiffuse[1] = 1.0f; + LightDiffuse[2] = 1.0f; + + LightSpecular[0] = 1.0f; + LightSpecular[1] = 1.0f; + LightSpecular[2] = 1.0f; + SpecularExponent = 50.0f; } using ControlSignature = @@ -116,14 +118,30 @@ public: // clamp color index colorIdx = vtkm::Max(0, colorIdx); colorIdx = vtkm::Min(colorMapSize - 1, colorIdx); - color = colorMap.Get(colorIdx); + vtkm::Vec diffuseColor = colorMap.Get(colorIdx); - color[0] *= vtkm::Min( - LightAbmient[0] + LightDiffuse[0] * cosTheta + LightSpecular[0] * specularConstant, one); - color[1] *= vtkm::Min( - LightAbmient[1] + LightDiffuse[1] * cosTheta + LightSpecular[1] * specularConstant, one); - color[2] *= vtkm::Min( - LightAbmient[2] + LightDiffuse[2] * cosTheta + LightSpecular[2] * specularConstant, one); + // Add ambient lighting + color[0] = LightAbmient[0]; + color[1] = LightAbmient[1]; + color[2] = LightAbmient[2]; + + // Add diffuse lighting + color[0] += LightDiffuse[0] * diffuseColor[0] * cosTheta; + color[1] += LightDiffuse[1] * diffuseColor[1] * cosTheta; + color[2] += LightDiffuse[2] * diffuseColor[2] * cosTheta; + + // Add specular lighting + color[0] += LightSpecular[0] * specularConstant; + color[1] += LightSpecular[1] * specularConstant; + color[2] += LightSpecular[2] * specularConstant; + + // Set alpha to 1.0 (opaque) + color[3] = 1.0f; + + // Clamp color values to [0,1] + color[0] = vtkm::Clamp(color[0], zero, one); + color[1] = vtkm::Clamp(color[1], zero, one); + color[2] = vtkm::Clamp(color[2], zero, one); colors.Set(offset + 0, color[0]); colors.Set(offset + 1, color[1]); diff --git a/vtkm/rendering/raytracing/RayTracer.h b/vtkm/rendering/raytracing/RayTracer.h index dffbeafae..81c6bfc18 100644 --- a/vtkm/rendering/raytracing/RayTracer.h +++ b/vtkm/rendering/raytracing/RayTracer.h @@ -34,6 +34,7 @@ protected: vtkm::cont::ArrayHandle ColorMap; vtkm::Range ScalarRange; bool Shade; + vtkm::Vec3f_32 LightPosition; template void RenderOnDevice(Ray& rays);