diff --git a/Documentation/release/dev/AnisotropyPBR.md b/Documentation/release/dev/AnisotropyPBR.md new file mode 100644 index 0000000000000000000000000000000000000000..1bb80832ea09a1d7b7f15bdaa996f8f6c5a264fb --- /dev/null +++ b/Documentation/release/dev/AnisotropyPBR.md @@ -0,0 +1,7 @@ +# Anisotropy in the PBR shader + +The PBR shader now supports anisotropic materials. This adds two parameters +to the vtkProperty : Anisotropy (strength of the anisotropy, 1.0 means fully +anisotropic), and AnisotropyRotation (rotate the direction of anisotropy +counter-clockwise). It can also be textured with anisotropy strength in the +red channel and anisotropy rotation in the green. diff --git a/Rendering/Core/vtkProperty.cxx b/Rendering/Core/vtkProperty.cxx index 2a77d121b9da43d8e7c51d70b441ac714346afa3..1cfae1d8cd710a1a4bcc155cde60d93703eb9388 100644 --- a/Rendering/Core/vtkProperty.cxx +++ b/Rendering/Core/vtkProperty.cxx @@ -76,6 +76,8 @@ vtkProperty::vtkProperty() this->OcclusionStrength = 1.0; this->Metallic = 0.0; this->Roughness = 0.5; + this->Anisotropy = 0.0; + this->AnisotropyRotation = 0.0; this->Ambient = 0.0; this->Diffuse = 1.0; this->Specular = 0.0; @@ -143,6 +145,12 @@ void vtkProperty::DeepCopy(vtkProperty* p) this->SetRenderPointsAsSpheres(p->GetRenderPointsAsSpheres()); this->SetRenderLinesAsTubes(p->GetRenderLinesAsTubes()); this->SetShading(p->GetShading()); + this->SetNormalScale(p->GetNormalScale()); + this->SetOcclusionStrength(p->GetOcclusionStrength()); + this->SetMetallic(p->GetMetallic()); + this->SetRoughness(p->GetRoughness()); + this->SetAnisotropy(p->GetAnisotropy()); + this->SetAnisotropyRotation(p->GetAnisotropyRotation()); this->RemoveAllTextures(); auto iter = p->Textures.begin(); @@ -253,8 +261,9 @@ void vtkProperty::SetTexture(const char* name, vtkTexture* tex) vtkErrorMacro("The " << name << " texture is not in sRGB color space."); return; } - if ((strcmp(name, "materialTex") == 0 || strcmp(name, "normalTex") == 0) && - tex->GetUseSRGBColorSpace()) + const bool texNeedLinear = strcmp(name, "materialTex") == 0 || strcmp(name, "normalTex") == 0 || + strcmp(name, "anisotropyTex") == 0; + if (texNeedLinear && tex->GetUseSRGBColorSpace()) { vtkErrorMacro("The " << name << " texture is not in linear color space."); return; diff --git a/Rendering/Core/vtkProperty.h b/Rendering/Core/vtkProperty.h index 663afe44f139a2e25cfda70e695391440a52d463..a986f771205c9186890ec422789b0375d4673737 100644 --- a/Rendering/Core/vtkProperty.h +++ b/Rendering/Core/vtkProperty.h @@ -196,6 +196,28 @@ public: vtkGetMacro(Roughness, double); //@} + //@{ + /** + * Set/Get the anisotropy coefficient. + * This value controls the anisotropy of the material (0.0 means isotropic) + * This parameter is only used by PBR Interpolation. + * Default value is 0.0 + */ + vtkSetClampMacro(Anisotropy, double, 0.0, 1.0); + vtkGetMacro(Anisotropy, double); + //@} + + //@{ + /** + * Set/Get the anisotropy rotation coefficient. + * This value controls the rotation of the direction of the anisotropy. + * This parameter is only used by PBR Interpolation. + * Default value is 0.0 + */ + vtkSetClampMacro(AnisotropyRotation, double, 0.0, 1.0); + vtkGetMacro(AnisotropyRotation, double); + //@} + //@{ /** * Set/Get the normal scale coefficient. @@ -512,10 +534,10 @@ public: * must be assigned unique names. Note that for texture blending the * textures will be rendering is alphabetical order and after any texture * defined in the actor. - * There exists 4 special textures with reserved names: "albedoTex", "materialTex", "normalTex" - * and "emissiveTex". While these textures can be added with the regular SetTexture method, it is - * prefered to use to method SetBaseColorTexture, SetORMTexture, SetNormalTexture and - * SetEmissiveTexture respectively. + * There exists 4 special textures with reserved names: "albedoTex", "materialTex", "normalTex", + * "emissiveTex" and "anisotropyTex". While these textures can be added with the regular + * SetTexture method, it is preferred to use the methods SetBaseColorTexture, SetORMTexture, + * SetNormalTexture, SetEmissiveTexture and SetAnisotropyTexture respectively. */ void SetTexture(const char* name, vtkTexture* texture); vtkTexture* GetTexture(const char* name); @@ -540,6 +562,18 @@ public: */ void SetORMTexture(vtkTexture* texture) { this->SetTexture("materialTex", texture); } + /** + * Set the anisotropy texture. This texture contains two independent components corresponding to + * the anisotropy value and anisotropy rotation. The last component (blue channel) is discarded. + * The anisotropy value is scaled by the anisotropy coefficient of the material. The anisotropy + * rotation rotates the direction of the anisotropy (ie. the tangent) around the normal and is not + * scaled by the anisotropy rotation coefficient. + * This texture must be in linear color space. + * This is only used by the PBR shading model. + * @sa SetInterpolationToPBR SetAnisotropy + */ + void SetAnisotropyTexture(vtkTexture* texture) { this->SetTexture("anisotropyTex", texture); } + /** * Set the normal texture. This texture is required for normal mapping. It is valid for both PBR * and Phong interpolation. @@ -615,6 +649,8 @@ protected: double Diffuse; double Metallic; double Roughness; + double Anisotropy; + double AnisotropyRotation; double NormalScale; double OcclusionStrength; double EmissiveFactor[3]; diff --git a/Rendering/OpenGL2/Testing/CMakeLists.txt b/Rendering/OpenGL2/Testing/CMakeLists.txt index cd4adb399dcf870561fd5504748a555f3ce6b17e..b0fd0c0ad0cf90aba0e5c6e3b84a00f8b077a881 100644 --- a/Rendering/OpenGL2/Testing/CMakeLists.txt +++ b/Rendering/OpenGL2/Testing/CMakeLists.txt @@ -1,6 +1,7 @@ vtk_module_test_data( Data/GIS/raster.tif Data/autoshop.jpg + Data/anisotropyTex.png Data/bunny.ply Data/clouds.jpeg Data/dragon.ply diff --git a/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt b/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt index 437ce4fb6b5cf334b98efad46e021789ddc75a36..f4e73e6381d9f78257899f7e7b4d828cf95516cc 100644 --- a/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt +++ b/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt @@ -49,6 +49,7 @@ vtk_add_test_cxx(vtkRenderingOpenGL2CxxTests tests TestPanoramicProjectionPass.cxx,NO_DATA TestPBREdgeTint.cxx TestPBRHdrEnvironment.cxx + TestPBRAnisotropy.cxx TestPBRIrradianceHDR.cxx TestPBRMapping.cxx TestPBRMaterials.cxx diff --git a/Rendering/OpenGL2/Testing/Cxx/TestPBRAnisotropy.cxx b/Rendering/OpenGL2/Testing/Cxx/TestPBRAnisotropy.cxx new file mode 100644 index 0000000000000000000000000000000000000000..203fe820f11ac5e73fa06e43db583b81a17b5e3b --- /dev/null +++ b/Rendering/OpenGL2/Testing/Cxx/TestPBRAnisotropy.cxx @@ -0,0 +1,155 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestPBRAnisotropy.cxx + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +// This test covers the PBR Anisotropy feature +// It renders spheres with different anisotropy values + +#include "vtkActor.h" +#include "vtkActorCollection.h" +#include "vtkCamera.h" +#include "vtkGenericOpenGLRenderWindow.h" +#include "vtkImageData.h" +#include "vtkImageFlip.h" +#include "vtkInteractorStyleTrackballCamera.h" +#include "vtkJPEGReader.h" +#include "vtkLight.h" +#include "vtkNew.h" +#include "vtkOpenGLPolyDataMapper.h" +#include "vtkOpenGLRenderer.h" +#include "vtkOpenGLSkybox.h" +#include "vtkOpenGLTexture.h" +#include "vtkPBRIrradianceTexture.h" +#include "vtkPBRPrefilterTexture.h" +#include "vtkPNGReader.h" +#include "vtkPolyDataTangents.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRendererCollection.h" +#include "vtkSphereSource.h" +#include "vtkTestUtilities.h" +#include "vtkTexture.h" +#include "vtkTextureMapToSphere.h" + +//---------------------------------------------------------------------------- +int TestPBRAnisotropy(int argc, char* argv[]) +{ + vtkNew<vtkOpenGLRenderer> renderer; + + vtkNew<vtkRenderWindow> renWin; + renWin->SetSize(600, 600); + renWin->AddRenderer(renderer); + + vtkNew<vtkRenderWindowInteractor> iren; + iren->SetRenderWindow(renWin); + + vtkSmartPointer<vtkPBRIrradianceTexture> irradiance = renderer->GetEnvMapIrradiance(); + irradiance->SetIrradianceStep(0.3); + renderer->UseSphericalHarmonicsOff(); + + vtkNew<vtkOpenGLTexture> textureCubemap; + textureCubemap->CubeMapOn(); + textureCubemap->UseSRGBColorSpaceOn(); + + std::string pathSkybox[6] = { "Data/skybox/posx.jpg", "Data/skybox/negx.jpg", + "Data/skybox/posy.jpg", "Data/skybox/negy.jpg", "Data/skybox/posz.jpg", + "Data/skybox/negz.jpg" }; + + for (int i = 0; i < 6; i++) + { + vtkNew<vtkJPEGReader> jpg; + char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, pathSkybox[i].c_str()); + jpg->SetFileName(fname); + delete[] fname; + vtkNew<vtkImageFlip> flip; + flip->SetInputConnection(jpg->GetOutputPort()); + flip->SetFilteredAxis(1); // flip y axis + textureCubemap->SetInputConnection(i, flip->GetOutputPort()); + } + + renderer->SetEnvironmentTexture(textureCubemap); + renderer->UseImageBasedLightingOn(); + + vtkNew<vtkSphereSource> sphere; + sphere->SetThetaResolution(75); + sphere->SetPhiResolution(75); + + vtkNew<vtkTextureMapToSphere> textureMap; + textureMap->SetInputConnection(sphere->GetOutputPort()); + textureMap->PreventSeamOff(); + + vtkNew<vtkPolyDataTangents> tangents; + tangents->SetInputConnection(textureMap->GetOutputPort()); + + vtkNew<vtkPolyDataMapper> mapper; + mapper->SetInputConnection(tangents->GetOutputPort()); + + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + actor->GetProperty()->SetInterpolationToPBR(); + + for (int i = 0; i < 6; i++) + { + vtkNew<vtkActor> actorSphere; + actorSphere->SetPosition(i, 0.0, 0.0); + actorSphere->RotateX(20); + actorSphere->RotateY(20); + actorSphere->SetMapper(mapper); + actorSphere->GetProperty()->SetInterpolationToPBR(); + actorSphere->GetProperty()->SetMetallic(1.0); + actorSphere->GetProperty()->SetAnisotropy(1.0); + actorSphere->GetProperty()->SetRoughness(i / 5.0); + renderer->AddActor(actorSphere); + } + + for (int i = 0; i < 6; i++) + { + vtkNew<vtkActor> actorSphere; + actorSphere->SetPosition(i, 1.0, 0.0); + actorSphere->RotateX(20); + actorSphere->RotateY(20); + actorSphere->SetMapper(mapper); + actorSphere->GetProperty()->SetInterpolationToPBR(); + actorSphere->GetProperty()->SetMetallic(1.0); + actorSphere->GetProperty()->SetRoughness(0.1); + actorSphere->GetProperty()->SetAnisotropy(i / 5.0); + renderer->AddActor(actorSphere); + } + + for (int i = 0; i < 6; i++) + { + vtkNew<vtkActor> actorSphere; + actorSphere->SetPosition(i, 2.0, 0.0); + actorSphere->RotateX(20); + actorSphere->RotateY(20); + actorSphere->SetMapper(mapper); + actorSphere->GetProperty()->SetInterpolationToPBR(); + actorSphere->GetProperty()->SetMetallic(1.0); + actorSphere->GetProperty()->SetRoughness(0.1); + actorSphere->GetProperty()->SetAnisotropy(1.0); + actorSphere->GetProperty()->SetAnisotropyRotation(i / 5.0); + renderer->AddActor(actorSphere); + } + + renWin->Render(); + + int retVal = vtkRegressionTestImage(renWin); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + + return !retVal; +} diff --git a/Rendering/OpenGL2/Testing/Cxx/TestPBRMapping.cxx b/Rendering/OpenGL2/Testing/Cxx/TestPBRMapping.cxx index 710c89f03b900100b0cd236efb7b7109b5ec040f..9a3ea11a3c7cff18296fab8c1e45a8c9b3f049c6 100644 --- a/Rendering/OpenGL2/Testing/Cxx/TestPBRMapping.cxx +++ b/Rendering/OpenGL2/Testing/Cxx/TestPBRMapping.cxx @@ -128,18 +128,32 @@ int TestPBRMapping(int argc, char* argv[]) normal->InterpolateOn(); normal->SetInputConnection(normalReader->GetOutputPort()); + vtkNew<vtkPNGReader> anisotropyReader; + char* anisotropyname = + vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/vtk_Anisotropy.png"); + anisotropyReader->SetFileName(anisotropyname); + delete[] anisotropyname; + + vtkNew<vtkTexture> anisotropy; + anisotropy->InterpolateOn(); + anisotropy->SetInputConnection(anisotropyReader->GetOutputPort()); + vtkNew<vtkActor> actor; actor->SetOrientation(0.0, 25.0, 0.0); actor->SetMapper(mapper); actor->GetProperty()->SetInterpolationToPBR(); - // set metallic and roughness to 1.0 as they act as multipliers with texture value + // set metallic, roughness, anisotropy and anisotropyRotation + // to 1.0 as they act as multipliers with texture value actor->GetProperty()->SetMetallic(1.0); actor->GetProperty()->SetRoughness(1.0); + actor->GetProperty()->SetAnisotropy(1.0); + actor->GetProperty()->SetAnisotropyRotation(1.0); actor->GetProperty()->SetBaseColorTexture(albedo); actor->GetProperty()->SetORMTexture(material); actor->GetProperty()->SetNormalTexture(normal); + actor->GetProperty()->SetAnisotropyTexture(anisotropy); renderer->AddActor(actor); diff --git a/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRAnisotropy.png.sha512 b/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRAnisotropy.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..c50fffeb09df9591fe856062d703faccb15077cd --- /dev/null +++ b/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRAnisotropy.png.sha512 @@ -0,0 +1 @@ +c084c3f1cf66f2ff25b7560e13c61b76cb541b2e9572410fc9ff3386dcee63c571c7d716d8928f2f6880a3c0162235435cc6e49c836255a748ad7681d2ba6e34 diff --git a/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRMapping.png.sha512 b/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRMapping.png.sha512 index cfc01009f6e6910d85633754cb9fee73d7c1ebbb..398aebb30a4b5f7552adf5ae6f2562be5c39dc55 100644 --- a/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRMapping.png.sha512 +++ b/Rendering/OpenGL2/Testing/Data/Baseline/TestPBRMapping.png.sha512 @@ -1 +1 @@ -d52f17c7322a3f6cf4e88f68fb61c90c3789f5ab1530a253343edad8d6bbd8844f0a7885b5a85094d221803e4a229891fc6bd3c29b72b02e841d578de4247bc9 +9015c94269f3c4d7e3a9479b770088e517c6f6806edb9d661235ebd1e88ad4e314a8aac2e46cd86519be3a34cfeb4a71bd15c11565b369060f511bc1084200ca diff --git a/Rendering/OpenGL2/vtk.module b/Rendering/OpenGL2/vtk.module index fe92b86208cecfe9af426569a78caf0f9b8f4170..04949608247e85080ff70dcf94e8d8001140190b 100644 --- a/Rendering/OpenGL2/vtk.module +++ b/Rendering/OpenGL2/vtk.module @@ -28,6 +28,7 @@ TEST_DEPENDS VTK::FiltersGeometry VTK::FiltersProgrammable VTK::FiltersSources + VTK::FiltersTexture VTK::IOExodus VTK::IOExport VTK::IOImage diff --git a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx index c59e512dc2e1eec851a24fa27f5b24bddb1f4da0..25da8348cfe317a5d47d84a5840a695b47336fb7 100644 --- a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx +++ b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx @@ -915,6 +915,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( } bool hasIBL = false; + bool hasAnisotropy = false; if (actor->GetProperty()->GetInterpolation() == VTK_PBR && lastLightComplexity > 0) { @@ -927,6 +928,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( "uniform vec3 emissiveFactorUniform;\n" "uniform float aoStrengthUniform;\n" "uniform vec3 edgeTintUniform;\n" + "uniform float anisotropyUniform;\n\n" "float D_GGX(float NdH, float roughness)\n" "{\n" " float a = roughness * roughness;\n" @@ -941,14 +943,23 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( " float ggxL = NdV * sqrt(a2 + NdL * (NdL - a2 * NdL));\n" " return 0.5 / (ggxV + ggxL);\n" "}\n" - "vec3 F_Schlick(vec3 F0, vec3 F90, float HdV)\n" + "vec3 F_Schlick(vec3 F0, vec3 F90, float HdL)\n" "{\n" - " return F0 + (F90 - F0) * pow(1.0 - HdV, 5.0);\n" + " return F0 + (F90 - F0) * pow(1.0 - HdL, 5.0);\n" "}\n" "vec3 DiffuseLambert(vec3 albedo)\n" "{\n" " return albedo * recPI;\n" - "}\n", + "}\n" + "vec3 SpecularIsotropic(float NdH, float NdV, float NdL, float HdL, float roughness, vec3 " + "F0, vec3 F90, out vec3 F)\n" + "{\n" + " float D = D_GGX(NdH, roughness);\n" + " float V = V_SmithCorrelated(NdV, NdL, roughness);\n" + " F = F_Schlick(F0, F90, HdL);\n" + " return (D * V) * F;\n" + "}\n" + "//VTK::Anisotropy::Dec\n", false); // disable default behavior with textures @@ -988,6 +999,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( toString << " vec3 emissiveColor = texture(emissiveTex, tcoordVCVSOutput).rgb;\n" " emissiveColor = emissiveColor * emissiveFactorUniform;\n"; } + // Anisotropy texture is sampled in ReplaceShaderNormal } } @@ -1020,6 +1032,59 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( " vec3 V = normalize(-vertexVC.xyz);\n" " float NdV = clamp(dot(N, V), 1e-5, 1.0);\n"; + if (actor->GetProperty()->GetAnisotropy() != 0.0 && + this->VBOs->GetNumberOfComponents("normalMC") == 3 && + this->VBOs->GetNumberOfComponents("tangentMC") == 3) + { + // anisotropy, tangentVC and bitangentVC are defined + hasAnisotropy = true; + + // Add functions to handle specular and anisotropic lobe + vtkShaderProgram::Substitute(FSSource, "//VTK::Anisotropy::Dec\n", + "// Anisotropy functions\n" + "float D_GGX_Anisotropic(float at, float ab, float TdH, float BdH, float NdH)\n" + "{\n" + " float a2 = at * ab;\n" + " vec3 d = vec3(ab * TdH, at * BdH, a2 * NdH);\n" + " float d2 = dot(d, d);\n" + " float b2 = a2 / d2;\n" + " return a2 * b2 * b2 * recPI;\n" + "}\n" + "float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float TdV, float BdV, float " + "TdL, float BdL, float NdV, float NdL)\n" + "{\n" + " float lambdaV = NdL * length(vec3(at * TdV, ab * BdV, NdV));\n" + " float lambdaL = NdV * length(vec3(at * TdL, ab * BdL, NdL));\n" + " return 0.5 / (lambdaV + lambdaL);\n" + "}\n" + "vec3 SpecularAnisotropic(float at, float ab, vec3 l, vec3 t, vec3 b, vec3 h, float TdV, " + "float BdV, float NdH, float NdV, float NdL,\n" + "float HdL, float roughness, float anisotropy, vec3 F0, vec3 F90, out vec3 F)\n" + "{\n" + " float TdL = dot(t, l);\n" + " float BdL = dot(b, l);\n" + " float TdH = dot(t, h);\n" + " float BdH = dot(b, h);\n" + " // specular anisotropic BRDF\n" + " float D = D_GGX_Anisotropic(at, ab, TdH, BdH, NdH);\n" + " float V = V_SmithGGXCorrelated_Anisotropic(at, ab, TdV, BdV, TdL, BdL, NdV, NdL);\n" + " F = F_Schlick(F0, F90, HdL);\n" + " return (D * V) * F;\n" + "}\n\n\n", + false); + + // Precompute anisotropic parameters + // at and ab are the roughness along the tangent and bitangent + // Disney, as in OSPray + toString << " float r2 = roughness * roughness;\n" + " float aspect = sqrt(1.0 - 0.9 * anisotropy);\n"; + toString << " float at = max(r2 / aspect, 0.001);\n" + " float ab = max(r2 * aspect, 0.001);\n"; + + toString << " float TdV = dot(tangentVC, V);\n" + " float BdV = dot(bitangentVC, V);\n"; + } + if (hasIBL) { if (!oglRen->GetUseSphericalHarmonics()) @@ -1032,8 +1097,20 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( toString << " vec3 irradiance = vec3(ComputeSH(rotN, shRed), ComputeSH(rotN, shGreen), " "ComputeSH(rotN, shBlue));\n"; } - toString << " vec3 worldReflect = normalize(envMatrix*reflect(-V, N));\n" - " vec3 prefilteredColor = textureLod(prefilterTex, worldReflect," + + if (hasAnisotropy) + { + toString << " vec3 anisotropicTangent = cross(bitangentVC, V);\n" + " vec3 anisotropicNormal = cross(anisotropicTangent, bitangentVC);\n" + " vec3 bentNormal = normalize(mix(N, anisotropicNormal, anisotropy));\n" + " vec3 worldReflect = normalize(envMatrix*reflect(-V, bentNormal));\n"; + } + else + { + toString << " vec3 worldReflect = normalize(envMatrix*reflect(-V, N));\n"; + } + + toString << " vec3 prefilteredColor = textureLod(prefilterTex, worldReflect," " roughness * prefilterMaxLevel).rgb;\n"; toString << " vec2 brdf = texture(brdfTex, vec2(NdV, roughness)).rg;\n"; } @@ -1054,7 +1131,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( " float f90 = clamp(dot(F0, vec3(50.0 * 0.33)), 0.0, 1.0);\n" " vec3 F90 = mix(vec3(f90), edgeTintUniform, metallic);\n" " vec3 L, H, radiance, F, specular, diffuse;\n" - " float NdL, NdH, HdV, distanceVC, attenuation, D, Vis;\n\n"; + " float NdL, NdH, HdL, distanceVC, attenuation, D, Vis;\n\n"; } toString << "//VTK::Light::Impl\n"; @@ -1119,13 +1196,20 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( if (actor->GetProperty()->GetInterpolation() == VTK_PBR) { // L = V = H for headlights - toString << " NdV = clamp(dot(N, V), 1e-5, 1.0);\n" - " D = D_GGX(NdV, roughness);\n" - " Vis = V_SmithCorrelated(NdV, NdV, roughness);\n" - " F = F_Schlick(F0, F90, 1.0);\n" - " specular = D * Vis * F;\n" - " diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n" - " Lo += (diffuse + specular) * lightColor0 * NdV;\n\n" + if (hasAnisotropy) + { + // When V=H, maybe can be optimised + toString << "specular = SpecularAnisotropic(at, ab, V, tangentVC, bitangentVC, V, TdV, " + "BdV, NdV, NdV, NdV,\n" + "1.0, roughness, anisotropy, F0, F90, F);\n"; + } + else + { + toString << "specular = SpecularIsotropic(NdV, NdV, NdV, 1.0, roughness, F0, F90, F);\n"; + } + toString << " diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n" + " \n\n" + " Lo += lightColor0 * ((diffuse + specular) * NdV);\n" "//VTK::Light::Impl\n"; } else @@ -1152,18 +1236,24 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( toString << " L = normalize(-lightDirectionVC" << i << ");\n" " H = normalize(V + L);\n" + " HdL = clamp(dot(H, L), 1e-5, 1.0);\n" " NdL = clamp(dot(N, L), 1e-5, 1.0);\n" " NdH = clamp(dot(N, H), 1e-5, 1.0);\n" - " HdV = clamp(dot(H, V), 1e-5, 1.0);\n" " radiance = lightColor" - << i - << ";\n" - " D = D_GGX(NdH, roughness);\n" - " Vis = V_SmithCorrelated(NdV, NdL, roughness);\n" - " F = F_Schlick(F0, F90, HdV);\n" - " specular = D * Vis * F;\n" - " diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n" - " Lo += (diffuse + specular) * radiance * NdL;\n"; + << i << ";\n"; + + if (hasAnisotropy) + { + toString << " specular = SpecularAnisotropic(at, ab, L, tangentVC, bitangentVC, H, " + "TdV, BdV, NdH, NdV, NdL, HdL, roughness, anisotropy, F0, F90, F);\n"; + } + else + { + toString + << " specular = SpecularIsotropic(NdH, NdV, NdL, HdL, roughness, F0, F90, F);\n"; + } + toString << " diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n" + " Lo += (diffuse + specular) * NdL * radiance;\n"; } toString << "//VTK::Light::Impl\n"; } @@ -1210,7 +1300,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( " H = normalize(V + L);\n" " NdL = clamp(dot(N, L), 1e-5, 1.0);\n" " NdH = clamp(dot(N, H), 1e-5, 1.0);\n" - " HdV = clamp(dot(H, V), 1e-5, 1.0);\n" + " HdL = clamp(dot(H, L), 1e-5, 1.0);\n" " if (lightPositional" << i << " == 0)\n" @@ -1251,13 +1341,20 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight( " }\n" " }\n" " radiance = lightColor" - << i - << " * attenuation;\n" - " D = D_GGX(NdH, roughness);\n" - " Vis = V_SmithCorrelated(NdV, NdL, roughness);\n" - " F = F_Schlick(F0, F90, HdV);\n" - " specular = D * Vis * F;\n" - " diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n" + << i << " * attenuation;\n"; + + if (hasAnisotropy) + { + toString << " specular = SpecularAnisotropic(at, ab, L, tangentVC, bitangentVC, H, " + "TdV, BdV, NdH, NdV, NdL, HdL, roughness, anisotropy, F0, F90, F);\n"; + } + else + { + toString + << " specular = SpecularIsotropic(NdH, NdV, NdL, HdL, roughness, F0, F90, F);\n"; + } + + toString << " diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n" " Lo += (diffuse + specular) * radiance * NdL;\n\n"; } toString << "//VTK::Light::Impl\n"; @@ -1559,7 +1656,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderTCoord( // ignore special textures if (textures[i].second == "albedoTex" || textures[i].second == "normalTex" || textures[i].second == "materialTex" || textures[i].second == "brdfTex" || - textures[i].second == "emissiveTex") + textures[i].second == "emissiveTex" || textures[i].second == "anisotropyTex") { continue; } @@ -1948,53 +2045,34 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderNormal( std::string VSSource = shaders[vtkShader::Vertex]->GetSource(); std::string GSSource = shaders[vtkShader::Geometry]->GetSource(); - // if we have point normals provided + // normal mapping + std::vector<texinfo> textures = this->GetTextures(actor); + bool normalMapping = std::find_if(textures.begin(), textures.end(), [](const texinfo& tex) { + return tex.second == "normalTex"; + }) != textures.end(); + bool rotationMap = std::find_if(textures.begin(), textures.end(), [](const texinfo& tex) { + return tex.second == "anisotropyTex"; + }) != textures.end(); + if (this->VBOs->GetNumberOfComponents("normalMC") == 3) { - // normal mapping - std::vector<texinfo> textures = this->GetTextures(actor); - bool normalTex = std::find_if(textures.begin(), textures.end(), [](const texinfo& tex) { - return tex.second == "normalTex"; - }) != textures.end(); - if (normalTex && this->VBOs->GetNumberOfComponents("tangentMC") == 3 && - !this->DrawingVertices) - { - vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Dec", - "//VTK::Normal::Dec\n" - "in vec3 tangentMC;\n" - "out vec3 tangentVCVSOutput;\n"); - - vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Impl", - "//VTK::Normal::Impl\n" - " tangentVCVSOutput = normalMatrix * tangentMC;\n"); - - vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Dec", - "//VTK::Normal::Dec\n" - "uniform float normalScaleUniform;\n" - "in vec3 tangentVCVSOutput;"); - - vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", - "//VTK::Normal::Impl\n" - " vec3 normalTS = texture(normalTex, tcoordVCVSOutput).xyz * 2.0 - 1.0;\n" - " normalTS = normalize(normalTS * vec3(normalScaleUniform, normalScaleUniform, 1.0));\n" - " vec3 tangentVC = normalize(tangentVCVSOutput - dot(tangentVCVSOutput, " - "normalVCVSOutput) * normalVCVSOutput);\n" - " vec3 bitangentVC = cross(normalVCVSOutput, tangentVC);\n" - " mat3 tbn = mat3(tangentVC, bitangentVC, normalVCVSOutput);\n" - " normalVCVSOutput = normalize(tbn * normalTS);\n"); - } vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" "in vec3 normalMC;\n" "uniform mat3 normalMatrix;\n" "out vec3 normalVCVSOutput;"); - vtkShaderProgram::Substitute( - VSSource, "//VTK::Normal::Impl", "normalVCVSOutput = normalMatrix * normalMC;"); + vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Impl", + "normalVCVSOutput = normalMatrix * normalMC;\n" + "//VTK::Normal::Impl"); vtkShaderProgram::Substitute(GSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" "in vec3 normalVCVSOutput[];\n" "out vec3 normalVCGSOutput;"); - vtkShaderProgram::Substitute( - GSSource, "//VTK::Normal::Impl", "normalVCGSOutput = normalVCVSOutput[i];"); + vtkShaderProgram::Substitute(GSSource, "//VTK::Normal::Impl", + "//VTK::Normal::Impl\n" + "normalVCGSOutput = normalVCVSOutput[i];"); vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" "uniform mat3 normalMatrix;\n" "in vec3 normalVCVSOutput;"); vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", @@ -2003,7 +2081,89 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderNormal( // if (int(gl_FrontFacing) == 0) does not work on mesa " if (gl_FrontFacing == false) { normalVCVSOutput = -normalVCVSOutput; }\n" //"normalVC = normalVCVarying;" - ); + "//VTK::Normal::Impl"); + + if ((normalMapping || actor->GetProperty()->GetAnisotropy() != 0.0) && + this->VBOs->GetNumberOfComponents("tangentMC") == 3 && !this->DrawingVertices) + { + vtkShaderProgram::Substitute(GSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" + "in vec3 tangentVCVSOutput[];\n" + "out vec3 tangentVCGSOutput;"); + vtkShaderProgram::Substitute(GSSource, "//VTK::Normal::Impl", + "//VTK::Normal::Impl\n" + "tangentVCGSOutput = tangentVCVSOutput[i];"); + vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" + "in vec3 tangentMC;\n" + "out vec3 tangentVCVSOutput;\n"); + vtkShaderProgram::Substitute(VSSource, "//VTK::Normal::Impl", + "//VTK::Normal::Impl\n" + " tangentVCVSOutput = normalMatrix * tangentMC;\n"); + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" + "in vec3 tangentVCVSOutput;\n"); + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", + " vec3 tangentVC = tangentVCVSOutput;\n" + "//VTK::Normal::Impl"); + + if (actor->GetProperty()->GetAnisotropy() != 0.0) + { + // We need to rotate the anisotropy direction (the tangent) by anisotropyRotation * 2 * + // PI + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" + "uniform float anisotropyRotationUniform;\n"); + if (rotationMap) + { + // Sample the texture + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", + " vec2 anisotropySample = texture(anisotropyTex, tcoordVCVSOutput).rg;\n" + " float anisotropy = anisotropySample.x * anisotropyUniform;\n" + " float anisotropyRotation = anisotropySample.y * anisotropyRotationUniform;\n" + "//VTK::Normal::Impl"); + } + else + { + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", + " float anisotropy = anisotropyUniform;\n" + " float anisotropyRotation = anisotropyRotationUniform;\n" + "//VTK::Normal::Impl"); + } + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", + " // Rotate the anisotropy direction (tangent) around the normal with a rotation " + "factor\n" + " float r2pi = anisotropyRotation * 2 * PI;\n" + " float s = - sin(r2pi);\n" // Counter clockwise (as in + // OSPray) + " float c = cos(r2pi);\n" + " vec3 Nn = normalize(normalVCVSOutput);\n" + " tangentVC = (1.0-c) * dot(tangentVCVSOutput,Nn) * Nn\n" + "+ c * tangentVCVSOutput - s * cross(Nn, tangentVCVSOutput);\n" + "//VTK::Normal::Impl"); + } + + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", + " tangentVC = normalize(tangentVC - dot(tangentVC, " + "normalVCVSOutput) * normalVCVSOutput);\n" + " vec3 bitangentVC = cross(normalVCVSOutput, tangentVC);\n" + "//VTK::Normal::Impl"); + + if (normalMapping) + { + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Dec", + "//VTK::Normal::Dec\n" + "uniform float normalScaleUniform;\n"); + + vtkShaderProgram::Substitute(FSSource, "//VTK::Normal::Impl", + " vec3 normalTS = texture(normalTex, tcoordVCVSOutput).xyz * 2.0 - 1.0;\n" + " normalTS = normalize(normalTS * vec3(normalScaleUniform, normalScaleUniform, " + "1.0));\n" + " mat3 tbn = mat3(tangentVC, bitangentVC, normalVCVSOutput);\n" + " normalVCVSOutput = normalize(tbn * normalTS);\n" + "//VTK::Normal::Impl"); + } + } shaders[vtkShader::Vertex]->SetSource(VSSource); shaders[vtkShader::Geometry]->SetSource(GSSource); @@ -2895,6 +3055,9 @@ void vtkOpenGLPolyDataMapper::SetPropertyShaderParameters( program->SetUniformf("aoStrengthUniform", static_cast<float>(ppty->GetOcclusionStrength())); program->SetUniform3f("emissiveFactorUniform", ppty->GetEmissiveFactor()); program->SetUniform3f("edgeTintUniform", ppty->GetEdgeTint()); + program->SetUniformf("anisotropyUniform", static_cast<float>(ppty->GetAnisotropy())); + program->SetUniformf( + "anisotropyRotationUniform", static_cast<float>(ppty->GetAnisotropyRotation())); } // handle specular diff --git a/Rendering/OpenGL2/vtkToneMappingPass.h b/Rendering/OpenGL2/vtkToneMappingPass.h index d5348ad939be97955232ce574f9a8c5f6e9b6900..6ce55a98f70b29d311d02d95b2d22752b4444c26 100644 --- a/Rendering/OpenGL2/vtkToneMappingPass.h +++ b/Rendering/OpenGL2/vtkToneMappingPass.h @@ -139,7 +139,7 @@ public: //@{ /** * Maximum HDR input that is not clipped. - * Defalut is 11.0785 + * Default is 11.0785 */ vtkSetClampMacro(HdrMax, float, 1.f, VTK_FLOAT_MAX); vtkGetMacro(HdrMax, float); diff --git a/Rendering/RayTracing/vtkOSPRayPolyDataMapperNode.cxx b/Rendering/RayTracing/vtkOSPRayPolyDataMapperNode.cxx index 1175cb9260ac8b616dfdb5c97e0ec0ebc4c5de34..ac307110b0813a3be7c0946fd08f9fa391227b49 100644 --- a/Rendering/RayTracing/vtkOSPRayPolyDataMapperNode.cxx +++ b/Rendering/RayTracing/vtkOSPRayPolyDataMapperNode.cxx @@ -459,10 +459,10 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>& std::vector<unsigned int>& rIndexArray, bool useCustomMaterial, OSPMaterial actorMaterial, int numNormals, const std::vector<osp::vec3f>& normals, int interpolationType, vtkImageData* vColorTextureMap, vtkImageData* vNormalTextureMap, - vtkImageData* vMaterialTextureMap, int numTextureCoordinates, float* textureCoordinates, - const osp::vec4f& textureTransform, int numCellMaterials, std::vector<OSPMaterial>& CellMaterials, - int numPointColors, osp::vec4f* PointColors, int numPointValueTextureCoords, - float* pointValueTextureCoords, RTW::Backend* backend) + vtkImageData* vMaterialTextureMap, vtkImageData* vAnisotropyTextureMap, int numTextureCoordinates, + float* textureCoordinates, const osp::vec4f& textureTransform, int numCellMaterials, + std::vector<OSPMaterial>& CellMaterials, int numPointColors, osp::vec4f* PointColors, + int numPointValueTextureCoords, float* pointValueTextureCoords, RTW::Backend* backend) { if (backend == nullptr) return OSPGeometry(); @@ -561,34 +561,70 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>& ospCommit(actorMaterial); } - if (interpolationType == VTK_PBR && vMaterialTextureMap && _hastm) + if (interpolationType == VTK_PBR && _hastm) { - vtkNew<vtkImageExtractComponents> extractRoughness; - extractRoughness->SetInputData(vMaterialTextureMap); - extractRoughness->SetComponents(1); - extractRoughness->Update(); - - vtkNew<vtkImageExtractComponents> extractMetallic; - extractMetallic->SetInputData(vMaterialTextureMap); - extractMetallic->SetComponents(2); - extractMetallic->Update(); - - vtkImageData* vRoughnessTextureMap = extractRoughness->GetOutput(); - vtkImageData* vMetallicTextureMap = extractMetallic->GetOutput(); - - OSPTexture t2dR = vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vRoughnessTextureMap); - ospSetObject(actorMaterial, "roughnessMap", t2dR); - ospSetVec4f(actorMaterial, "roughnessMap.transform", textureTransform.x, textureTransform.y, - textureTransform.z, textureTransform.w); - ospRelease(t2dR); - - OSPTexture t2dM = vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vMetallicTextureMap); - ospSetObject(actorMaterial, "metallicMap", t2dM); - ospSetVec4f(actorMaterial, "metallicMap.transform", textureTransform.x, textureTransform.y, - textureTransform.z, textureTransform.w); - ospRelease(t2dM); - ospCommit(actorMaterial); + if (vMaterialTextureMap) + { + vtkNew<vtkImageExtractComponents> extractRoughness; + extractRoughness->SetInputData(vMaterialTextureMap); + extractRoughness->SetComponents(1); + extractRoughness->Update(); + + vtkNew<vtkImageExtractComponents> extractMetallic; + extractMetallic->SetInputData(vMaterialTextureMap); + extractMetallic->SetComponents(2); + extractMetallic->Update(); + + vtkImageData* vRoughnessTextureMap = extractRoughness->GetOutput(); + vtkImageData* vMetallicTextureMap = extractMetallic->GetOutput(); + + OSPTexture t2dR = vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vRoughnessTextureMap); + ospSetObject(actorMaterial, "roughnessMap", t2dR); + ospSetVec4f(actorMaterial, "roughnessMap.transform", textureTransform.x, textureTransform.y, + textureTransform.z, textureTransform.w); + ospRelease(t2dR); + + OSPTexture t2dM = vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vMetallicTextureMap); + ospSetObject(actorMaterial, "metallicMap", t2dM); + ospSetVec4f(actorMaterial, "metallicMap.transform", textureTransform.x, textureTransform.y, + textureTransform.z, textureTransform.w); + ospRelease(t2dM); + + ospCommit(actorMaterial); + } + + if (vAnisotropyTextureMap) + { + vtkNew<vtkImageExtractComponents> extractAnisotropyValue; + extractAnisotropyValue->SetInputData(vAnisotropyTextureMap); + extractAnisotropyValue->SetComponents(0); + extractAnisotropyValue->Update(); + + vtkNew<vtkImageExtractComponents> extractAnisotropyRotation; + extractAnisotropyRotation->SetInputData(vAnisotropyTextureMap); + extractAnisotropyRotation->SetComponents(1); + extractAnisotropyRotation->Update(); + + vtkImageData* vAnisotropyValueTextureMap = extractAnisotropyValue->GetOutput(); + vtkImageData* vAnisotropyRotationTextureMap = extractAnisotropyRotation->GetOutput(); + + OSPTexture t2dA = + vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vAnisotropyValueTextureMap); + ospSetObject(actorMaterial, "anisotropyMap", t2dA); + ospSetVec4f(actorMaterial, "anisotropyMap.transform", textureTransform.x, + textureTransform.y, textureTransform.z, textureTransform.w); + ospRelease(t2dA); + + OSPTexture t2dR = + vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vAnisotropyRotationTextureMap); + ospSetObject(actorMaterial, "rotationMap", t2dR); + ospSetVec4f(actorMaterial, "rotationMap.transform", textureTransform.x, textureTransform.y, + textureTransform.z, textureTransform.w); + ospRelease(t2dR); + + ospCommit(actorMaterial); + } } if (vColorTextureMap && _hastm) @@ -702,6 +738,8 @@ OSPMaterial MakeActorMaterial(vtkOSPRayRendererNode* orn, OSPRenderer oRenderer, static_cast<float>(property->GetEdgeTint()[1]), static_cast<float>(property->GetEdgeTint()[2]) }; ospSetVec3f(oMaterial, "edgeColor", edgeColor[0], edgeColor[1], edgeColor[2]); + ospSetFloat(oMaterial, "anisotropy", static_cast<float>(property->GetAnisotropy())); + ospSetFloat(oMaterial, "rotation", static_cast<float>(property->GetAnisotropyRotation())); } else { @@ -899,6 +937,7 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode vtkImageData* vColorTextureMap = nullptr; vtkImageData* vNormalTextureMap = nullptr; vtkImageData* vMaterialTextureMap = nullptr; + vtkImageData* vAnisotropyTextureMap = nullptr; if (texture) { @@ -1123,14 +1162,20 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode { vMaterialTextureMap = texture->GetInput(); } + + texture = property->GetTexture("anisotropyTex"); + if (texture) + { + vAnisotropyTextureMap = texture->GetInput(); + } } this->GeometricModels.emplace_back(vtkosp::RenderAsTriangles(position, conn.triangle_index, conn.triangle_reverse, useCustomMaterial, oMaterial, numNormals, normals, property->GetInterpolation(), vColorTextureMap, vNormalTextureMap, vMaterialTextureMap, - numTextureCoordinates, (float*)textureCoordinates.data(), texTransform, numCellMaterials, - cellMaterials, numPointColors, pointColors.data(), numPointValueTextureCoords, - (float*)pointValueTextureCoords.data(), backend)); + vAnisotropyTextureMap, numTextureCoordinates, (float*)textureCoordinates.data(), + texTransform, numCellMaterials, cellMaterials, numPointColors, pointColors.data(), + numPointValueTextureCoords, (float*)pointValueTextureCoords.data(), backend)); } } } @@ -1207,9 +1252,9 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode this->GeometricModels.emplace_back(vtkosp::RenderAsTriangles(position, conn.strip_index, conn.strip_reverse, useCustomMaterial, oMaterial, numNormals, normals, property->GetInterpolation(), vColorTextureMap, vNormalTextureMap, vMaterialTextureMap, - numTextureCoordinates, (float*)textureCoordinates.data(), texTransform, numCellMaterials, - cellMaterials, numPointColors, pointColors.data(), numPointValueTextureCoords, - (float*)pointValueTextureCoords.data(), backend)); + vAnisotropyTextureMap, numTextureCoordinates, (float*)textureCoordinates.data(), + texTransform, numCellMaterials, cellMaterials, numPointColors, pointColors.data(), + numPointValueTextureCoords, (float*)pointValueTextureCoords.data(), backend)); } } } diff --git a/Testing/Data/anisotropyTex.png.sha512 b/Testing/Data/anisotropyTex.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..9b4acde0120698c5a32a5004ef4ce2e85b32c92a --- /dev/null +++ b/Testing/Data/anisotropyTex.png.sha512 @@ -0,0 +1 @@ +1d9a36cbfd4d181f78d9213a5f283872cffffdf64d11a8b989da08e355d7d6a961d1e2813ca79df140c91c2e84c766efe2c9cfe374c1bf3a594b365053733753 diff --git a/Testing/Data/vtk_Anisotropy.png.sha512 b/Testing/Data/vtk_Anisotropy.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..a865efedb1c8ba794ed5b49cc63ddf7e084f9433 --- /dev/null +++ b/Testing/Data/vtk_Anisotropy.png.sha512 @@ -0,0 +1 @@ +18cce1f08f522172d430912eb14502928aa4783bc45b593949a05b8a313cf5d051d32a5b49dc2a439b5a86597c3afce3bd6f0a64fac08494bc2aa6ef69d2c72b