Commit 7de031ab authored by Michael Migliore's avatar Michael Migliore

PBR fixes

parent 2eb55b05
Pipeline #141588 failed with stage
......@@ -52,7 +52,6 @@ vtkCxxSetObjectMacro(vtkRenderer, BackgroundTexture, vtkTexture);
vtkCxxSetObjectMacro(vtkRenderer, RightBackgroundTexture, vtkTexture);
vtkCxxSetObjectMacro(vtkRenderer, Pass, vtkRenderPass);
vtkCxxSetObjectMacro(vtkRenderer, FXAAOptions, vtkFXAAOptions);
vtkCxxSetObjectMacro(vtkRenderer, EnvironmentCubeMap, vtkTexture);
//----------------------------------------------------------------------------
// Return NULL if no override is supplied.
......@@ -1866,6 +1865,13 @@ vtkAssemblyPath* vtkRenderer::PickProp(double selectionX1, double selectionY1,
return this->PickedProp; //returns an assembly path
}
//----------------------------------------------------------------------------
void vtkRenderer::SetEnvironmentCubeMap(vtkTexture* cubemap, bool vtkNotUsed(isSRGB))
{
vtkSetObjectBodyMacro(EnvironmentCubeMap, vtkTexture, cubemap);
}
//----------------------------------------------------------------------------
void vtkRenderer::ExpandBounds(double bounds[6], vtkMatrix4x4 *matrix)
{
if(!bounds)
......
......@@ -761,11 +761,12 @@ public:
/**
* Set/Get the environment cubemap used for image based lighting.
* Warning, this cubemap must be expressed in linear color space.
* Enable sRGB color space if needed.
* If the cubemap is in sRGB color space, set the color flag on the texture or
* set the argument isSRGB to true.
* @sa vtkTexture::UseSRGBColorSpaceOn
*/
vtkGetObjectMacro(EnvironmentCubeMap, vtkTexture);
virtual void SetEnvironmentCubeMap(vtkTexture*);
virtual void SetEnvironmentCubeMap(vtkTexture* cubemap, bool isSRGB = false);
//@}
protected:
......
......@@ -61,7 +61,6 @@ int TestPBRMaterials(int argc, char* argv[])
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",
......@@ -79,7 +78,7 @@ int TestPBRMaterials(int argc, char* argv[])
textureCubemap->SetInputConnection(i, flip->GetOutputPort());
}
renderer->SetEnvironmentCubeMap(textureCubemap);
renderer->SetEnvironmentCubeMap(textureCubemap, true);
renderer->UseImageBasedLightingOn();
vtkNew<vtkSphereSource> sphere;
......@@ -154,7 +153,7 @@ int TestPBRMaterials(int argc, char* argv[])
renderer->AddActor(actorSphere);
}
skybox->SetTexture(irradiance);
skybox->SetTexture(textureCubemap);
renderer->AddActor(skybox);
renWin->Render();
......
3440320155042444e9b73854a7b37f9c8348e705b28f43984c0811ff8b5f77115d8f1b0b5e53019e9fd0081f0f2d6442b9116938da2e89599bf0d7e4dcbe910c
bbe0aed9907ea5cc0ac4902fec1dcf0fc7372985a0e84769c95e672b0f7655c06ff01b2b381296f91feb96f7142fe883c5faaf1217c059d32c7745fbda42af8d
......@@ -65,14 +65,19 @@ void vtkEquirectangularToCubemapTexture::Load(vtkRenderer* ren)
if (this->GetMTime() > this->LoadTime.GetMTime() ||
this->InputTexture->GetMTime() > this->LoadTime.GetMTime())
{
this->InputTexture->Render(ren);
if (this->TextureObject == nullptr)
{
this->TextureObject = vtkTextureObject::New();
}
this->TextureObject->SetContext(renWin);
this->TextureObject->SetFormat(GL_RGB);
this->TextureObject->SetInternalFormat(GL_RGB16F);
this->TextureObject->SetDataType(GL_FLOAT);
this->TextureObject->SetFormat(
this->InputTexture->GetTextureObject()->GetFormat(VTK_FLOAT, 3, true));
this->TextureObject->SetInternalFormat(
this->InputTexture->GetTextureObject()->GetInternalFormat(VTK_FLOAT, 3, true));
this->TextureObject->SetDataType(
this->InputTexture->GetTextureObject()->GetDataType(VTK_FLOAT));
this->TextureObject->SetWrapS(vtkTextureObject::ClampToEdge);
this->TextureObject->SetWrapT(vtkTextureObject::ClampToEdge);
this->TextureObject->SetWrapR(vtkTextureObject::ClampToEdge);
......@@ -117,16 +122,15 @@ void vtkEquirectangularToCubemapTexture::Load(vtkRenderer* ren)
"//VTK::FSQ::Decl");
std::stringstream fsImpl;
fsImpl
<< " \n"
" float x = 2.0 * texCoord.x - 1.0;\n"
" float y = 1.0 - 2.0 * texCoord.y;\n"
" gl_FragData[0] = texture(equiTex, toSpherical(vec3(1, y, -x)));\n"
" gl_FragData[1] = texture(equiTex, toSpherical(vec3(-1, y, x)));\n"
" gl_FragData[2] = texture(equiTex, toSpherical(vec3(x, 1, -y)));\n"
" gl_FragData[3] = texture(equiTex, toSpherical(vec3(x, -1, y)));\n"
" gl_FragData[4] = texture(equiTex, toSpherical(vec3(x, y, 1)));\n"
" gl_FragData[5] = texture(equiTex, toSpherical(vec3(-x, y, -1)));\n";
fsImpl << " \n"
" float x = 2.0 * texCoord.x - 1.0;\n"
" float y = 1.0 - 2.0 * texCoord.y;\n"
" gl_FragData[0] = texture(equiTex, toSpherical(vec3(1, y, -x)));\n"
" gl_FragData[1] = texture(equiTex, toSpherical(vec3(-1, y, x)));\n"
" gl_FragData[2] = texture(equiTex, toSpherical(vec3(x, 1, -y)));\n"
" gl_FragData[3] = texture(equiTex, toSpherical(vec3(x, -1, y)));\n"
" gl_FragData[4] = texture(equiTex, toSpherical(vec3(x, y, 1)));\n"
" gl_FragData[5] = texture(equiTex, toSpherical(vec3(-x, y, -1)));\n";
vtkShaderProgram::Substitute(FSSource, "//VTK::FSQ::Impl", fsImpl.str());
......@@ -139,7 +143,6 @@ void vtkEquirectangularToCubemapTexture::Load(vtkRenderer* ren)
}
else
{
this->InputTexture->Render(ren);
this->InputTexture->GetTextureObject()->Activate();
quadHelper.Program->SetUniformi("equiTex", this->InputTexture->GetTextureUnit());
quadHelper.Render();
......
......@@ -794,12 +794,20 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
int lastLightComplexity = this->LastLightComplexity[this->LastBoundBO];
int lastLightCount = this->LastLightCount[this->LastBoundBO];
if (actor->GetProperty()->GetInterpolation() != VTK_PBR && lastLightCount == 0)
{
lastLightComplexity = 0;
}
bool hasIBL = false;
if (actor->GetProperty()->GetInterpolation() == VTK_PBR && lastLightComplexity > 0)
{
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Dec",
"//VTK::Light::Dec\n"
"uniform mat3 normalMatrix;\n" // move to normal code
"const float PI = 3.14159265359;\n"
"const float recPI = 0.31830988618;\n"
"uniform float metallicUniform;\n"
"uniform float roughnessUniform;\n"
"uniform vec3 emissiveFactorUniform;\n"
......@@ -811,25 +819,24 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" float d = (NdH * a2 - NdH) * NdH + 1.0;\n"
" return a2 / (PI * d * d);\n"
"}\n"
"float G_Smith(float NdV, float NdL, float roughness)\n"
"float V_SmithCorrelated(float NdV, float NdL, float roughness)\n"
"{\n"
" float k = 0.5 * (roughness + 1.0);\n" // avoid hotness
" float k2 = 0.5 * k * k;\n"
" float ggxV = NdV / (NdV * (1.0 - k2) + k2);\n"
" float ggxL = NdL / (NdL * (1.0 - k2) + k2);\n"
" return ggxL * ggxV;\n"
" float a2 = roughness * roughness;\n"
" float ggxV = NdL * sqrt(a2 + NdV * (NdV - a2 * NdV));\n"
" float ggxL = NdV * sqrt(a2 + NdL * (NdL - a2 * NdL));\n"
" return 0.5 / (ggxV + ggxL);\n"
"}\n"
"vec3 F_Schlick(float HdV, vec3 F0)\n"
"{\n"
" return F0 + (1.0 - F0) * pow(2.0, (-5.55473 * HdV - 6.98316) * HdV);\n"
" return F0 + (1.0 - F0) * pow(1.0 - HdV, 5.0);\n"
"}\n"
"vec3 F_SchlickRoughness(float HdV, vec3 F0, float roughness)\n"
"{\n"
" return F0 + (1.0 - F0) * (max(vec3(1.0 - roughness), F0) - F0) * pow(2.0, (-5.55473 * HdV - 6.98316) * HdV);\n"
" return F0 + (1.0 - F0) * (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - HdV, 5.0);\n"
"}\n"
"vec3 DiffuseLambert(vec3 albedo)\n"
"{\n"
" return albedo / PI;\n"
" return albedo * recPI;\n"
"}\n",
false);
......@@ -841,7 +848,6 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
bool albedo = false;
bool material = false;
bool emissive = false;
bool ibl = false;
toString.clear();
for (auto& t : textures)
{
......@@ -876,7 +882,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
vtkOpenGLRenderer* oglRen = vtkOpenGLRenderer::SafeDownCast(ren);
if (oglRen)
{
ibl = true;
hasIBL = true;
toString << " const float prefilterMaxLevel = float("
<< (oglRen->GetEnvMapPrefiltered()->GetPrefilterLevels() - 1) << ");\n";
}
......@@ -884,7 +890,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
if (!albedo)
{
toString << "vec3 albedo = diffuseColor;\n";
toString << "vec3 albedo = pow(diffuseColor, vec3(2.2));\n"; // to linear color space
}
if (!material)
{
......@@ -901,7 +907,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" vec3 V = normalize(-vertexVC.xyz);\n"
" float NdV = clamp(dot(N, V), 1e-5, 1.0);\n";
if (ibl)
if (hasIBL)
{
toString << " vec3 irradiance = texture(irradianceTex, inverse(normalMatrix)*N).rgb;\n";
toString << " vec3 worldReflect = normalize(inverse(normalMatrix)*reflect(-V, N));\n"
......@@ -922,7 +928,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
{
toString << " vec3 F0 = mix(vec3(0.04), albedo, metallic);\n"
" vec3 L, H, radiance, F, specular, diffuse;\n"
" float NdL, NdH, HdV, distanceVC, attenuation, D, G;\n\n";
" float NdL, NdH, HdV, distanceVC, attenuation, D, Vis;\n\n";
}
toString << "//VTK::Light::Impl\n";
......@@ -932,7 +938,7 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
toString.clear();
toString.str("");
if (ibl)
if (hasIBL)
{
// add uniforms
vtkShaderProgram::Substitute(FSSource,"//VTK::Light::Dec",
......@@ -963,10 +969,10 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
// L = V = H for headlights
toString << " NdV = clamp(dot(N, V), 1e-5, 1.0);\n"
" D = D_GGX(NdV, roughness);\n"
" G = G_Smith(NdV, NdV, roughness);\n"
" Vis = V_SmithCorrelated(NdV, NdV, roughness);\n"
" F = F_Schlick(1.0, F0);\n"
" specular = D * G * F / (4.0 * NdV * NdV);\n"
" diffuse = (1.0 - F) * DiffuseLambert(albedo);\n"
" specular = D * Vis * F;\n"
" diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n"
" Lo += (diffuse + specular) * lightColor0 * NdV;\n\n"
"//VTK::Light::Impl\n";
}
......@@ -1000,10 +1006,10 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" HdV = clamp(dot(H, V), 1e-5, 1.0);\n"
" radiance = lightColor" << i << ";\n"
" D = D_GGX(NdH, roughness);\n"
" G = G_Smith(NdV, NdL, roughness);\n"
" Vis = V_SmithCorrelated(NdV, NdL, roughness);\n"
" F = F_Schlick(HdV, F0);\n"
" specular = D * G * F / (4.0 * NdV * NdL);\n"
" diffuse = (1.0 - F) * DiffuseLambert(albedo);\n"
" specular = D * Vis * F;\n"
" diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n"
" Lo += (diffuse + specular) * radiance * NdL;\n";
}
toString << "//VTK::Light::Impl\n";
......@@ -1056,10 +1062,10 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
" + lightAttenuation" << i << ".z * distanceVC * distanceVC);\n"
" radiance = lightColor" << i << " * attenuation;\n"
" D = D_GGX(NdH, roughness);\n"
" G = G_Smith(NdV, NdL, roughness);\n"
" Vis = V_SmithCorrelated(NdV, NdL, roughness);\n"
" F = F_Schlick(HdV, F0);\n"
" specular = D * G * F / (4.0 * NdV * NdL);\n"
" diffuse = (1.0 - F) * DiffuseLambert(albedo);\n"
" specular = D * Vis * F;\n"
" diffuse = (1.0 - metallic) * (1.0 - F) * DiffuseLambert(albedo);\n"
" Lo += (diffuse + specular) * radiance * NdL;\n\n";
}
toString << "//VTK::Light::Impl\n";
......@@ -1121,11 +1127,12 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderLight(
vtkShaderProgram::Substitute(FSSource, "//VTK::Light::Impl",
" vec3 kS = F_SchlickRoughness(max(NdV, 0.0), F0, roughness);\n"
" vec3 kD = 1.0 - kS;\n"
" kD *= 1.0 - metallic;\n" // no diffuse for metals
" vec3 ambient = (kD * irradiance * albedo + prefilteredColor * (kS * brdf.r + brdf.g));\n"
" vec3 color = ambient + Lo;\n"
" color = mix(color, color * ao, aoStrengthUniform);\n" // ambient occlusion
" color += emissiveColor;\n" // emissive
" color = pow(color, vec3(1.0/2.2));\n"
" color = pow(color, vec3(1.0/2.2));\n" // to sRGB color space
" gl_FragData[0] = vec4(color, opacity);\n"
" //VTK::Light::Impl", false);
}
......@@ -2815,6 +2822,14 @@ void vtkOpenGLPolyDataMapper::RenderPieceDraw(vtkRenderer* ren, vtkActor *actor)
pointPicking = true;
}
// when using IBL, we need seamless cubemaps to avoid artifacts
if (ren->GetUseImageBasedLighting() && ren->GetEnvironmentCubeMap())
{
vtkOpenGLRenderWindow* renWin = vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow());
vtkOpenGLState* ostate = renWin->GetState();
ostate->vtkglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
bool draw_surface_with_edges =
(actor->GetProperty()->GetEdgeVisibility() && representation == VTK_SURFACE) && !selector;
int numVerts = this->VBOs->GetNumberOfTuples("vertexMC");
......
......@@ -127,6 +127,11 @@ int vtkOpenGLRenderer::UpdateLights ()
}
}
if (this->GetUseImageBasedLighting() && this->GetEnvironmentCubeMap() && lightingComplexity == 0)
{
lightingComplexity = 1;
}
// create alight if needed
if( !lightingCount )
{
......@@ -1020,7 +1025,7 @@ void vtkOpenGLRenderer::SetUserLightTransform(vtkTransform* transform)
this->UserLightTransform = transform;
}
void vtkOpenGLRenderer::SetEnvironmentCubeMap(vtkTexture* cubemap)
void vtkOpenGLRenderer::SetEnvironmentCubeMap(vtkTexture* cubemap, bool isSRGB)
{
this->Superclass::SetEnvironmentCubeMap(cubemap);
......@@ -1032,6 +1037,9 @@ void vtkOpenGLRenderer::SetEnvironmentCubeMap(vtkTexture* cubemap)
{
this->GetEnvMapIrradiance()->SetInputCubeMap(oglCubemap);
this->GetEnvMapPrefiltered()->SetInputCubeMap(oglCubemap);
this->GetEnvMapIrradiance()->SetConvertToLinear(isSRGB);
this->GetEnvMapPrefiltered()->SetConvertToLinear(isSRGB);
}
else
{
......
......@@ -149,7 +149,7 @@ public:
/**
* Overriden in order to connect the cubemap to the environment map textures.
*/
void SetEnvironmentCubeMap(vtkTexture*) override;
void SetEnvironmentCubeMap(vtkTexture* cubemap, bool isSRGB = false) override;
protected:
vtkOpenGLRenderer();
......
......@@ -108,7 +108,19 @@ void vtkPBRIrradianceTexture::Load(vtkRenderer* ren)
vtkShaderProgram::Substitute(FSSource, "//VTK::FSQ::Decl",
"uniform samplerCube cubeMap;\n"
"const float PI = 3.14159265359;\n"
"//VTK::FSQ::Decl");
"vec3 ColorSpaceConvert(vec3 col)\n"
"{\n"
" //VTK::COLORSPACE::Decl\n"
"}\n");
if (this->ConvertToLinear)
{
vtkShaderProgram::Substitute(FSSource, "//VTK::COLORSPACE::Decl", "return pow(col, vec3(2.2));");
}
else
{
vtkShaderProgram::Substitute(FSSource, "//VTK::COLORSPACE::Decl", "return col;");
}
std::stringstream fsImpl;
fsImpl
......@@ -149,12 +161,12 @@ void vtkPBRIrradianceTexture::Load(vtkRenderer* ren)
" {\n"
" vec3 sample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));\n"
" float factor = cos(theta) * sin(theta);\n"
" i_px += texture(cubeMap, m_px * sample).rgb * factor;\n"
" i_nx += texture(cubeMap, m_nx * sample).rgb * factor;\n"
" i_py += texture(cubeMap, m_py * sample).rgb * factor;\n"
" i_ny += texture(cubeMap, m_ny * sample).rgb * factor;\n"
" i_pz += texture(cubeMap, m_pz * sample).rgb * factor;\n"
" i_nz += texture(cubeMap, m_nz * sample).rgb * factor;\n"
" i_px += ColorSpaceConvert(texture(cubeMap, m_px * sample).rgb) * factor;\n"
" i_nx += ColorSpaceConvert(texture(cubeMap, m_nx * sample).rgb) * factor;\n"
" i_py += ColorSpaceConvert(texture(cubeMap, m_py * sample).rgb) * factor;\n"
" i_ny += ColorSpaceConvert(texture(cubeMap, m_ny * sample).rgb) * factor;\n"
" i_pz += ColorSpaceConvert(texture(cubeMap, m_pz * sample).rgb) * factor;\n"
" i_nz += ColorSpaceConvert(texture(cubeMap, m_nz * sample).rgb) * factor;\n"
" nSamples = nSamples + 1.0;\n"
" }\n"
" }\n"
......
......@@ -59,7 +59,7 @@ public:
//@{
/**
* Set/Get size of texture.
* Default is 512.
* Default is 256.
*/
vtkGetMacro(IrradianceSize, unsigned int);
vtkSetMacro(IrradianceSize, unsigned int);
......@@ -69,20 +69,32 @@ public:
/**
* Set/Get the size of steps in radians used to sample hemisphere.
* Default is (pi/64).
* In some OpenGL drivers (OSMesa, old OSX), the default value might be too high leading to
* In some OpenGL drivers (OSMesa, old OSX), the default value might be too low leading to
* artifacts.
*/
vtkGetMacro(IrradianceStep, float);
vtkSetMacro(IrradianceStep, float);
//@}
//@{
/**
* Set/Get the conversion to linear color space.
* If the input cubemap is in sRGB color space and the conversion is not done by OpenGL
* directly with the texture format, the conversion can be done in the shader with this flag.
*/
vtkGetMacro(ConvertToLinear, bool);
vtkSetMacro(ConvertToLinear, bool);
vtkBooleanMacro(ConvertToLinear, bool);
//@}
protected:
vtkPBRIrradianceTexture() = default;
~vtkPBRIrradianceTexture() override;
float IrradianceStep = 0.04908738521; // pi / 64
unsigned int IrradianceSize = 512;
unsigned int IrradianceSize = 256;
vtkOpenGLTexture* InputCubeMap = nullptr;
bool ConvertToLinear = false;
private:
vtkPBRIrradianceTexture(const vtkPBRIrradianceTexture&) = delete;
......
......@@ -100,6 +100,10 @@ void vtkPBRPrefilterTexture::Load(vtkRenderer* ren)
"uniform samplerCube cubeMap;\n"
"uniform float roughness;\n"
"const float PI = 3.14159265359;\n"
"vec3 ColorSpaceConvert(vec3 col)\n"
"{\n"
" //VTK::COLORSPACE::Decl\n"
"}\n"
"float RadicalInverse_VdC(uint bits)\n"
"{\n"
" bits = (bits << 16u) | (bits >> 16u);\n"
......@@ -130,6 +134,15 @@ void vtkPBRPrefilterTexture::Load(vtkRenderer* ren)
" return normalize(sampleVec);\n"
"}\n");
if (this->ConvertToLinear)
{
vtkShaderProgram::Substitute(FSSource, "//VTK::COLORSPACE::Decl", "return pow(col, vec3(2.2));");
}
else
{
vtkShaderProgram::Substitute(FSSource, "//VTK::COLORSPACE::Decl", "return col;");
}
std::stringstream fsImpl;
fsImpl
<< "vec3 n_px = normalize(vec3(1.0, 1.0 - 2.0 * texCoord.y, 1.0 - 2.0 * texCoord.x));\n"
......@@ -175,12 +188,12 @@ void vtkPBRPrefilterTexture::Load(vtkRenderer* ren)
" float d_ny = max(dot(n_ny, l_ny), 0.0);\n"
" float d_pz = max(dot(n_pz, l_pz), 0.0);\n"
" float d_nz = max(dot(n_nz, l_nz), 0.0);\n"
" p_px += texture(cubeMap, l_px).rgb * d_px;\n"
" p_nx += texture(cubeMap, l_nx).rgb * d_nx;\n"
" p_py += texture(cubeMap, l_py).rgb * d_py;\n"
" p_ny += texture(cubeMap, l_ny).rgb * d_ny;\n"
" p_pz += texture(cubeMap, l_pz).rgb * d_pz;\n"
" p_nz += texture(cubeMap, l_nz).rgb * d_nz;\n"
" p_px += ColorSpaceConvert(texture(cubeMap, l_px).rgb) * d_px;\n"
" p_nx += ColorSpaceConvert(texture(cubeMap, l_nx).rgb) * d_nx;\n"
" p_py += ColorSpaceConvert(texture(cubeMap, l_py).rgb) * d_py;\n"
" p_ny += ColorSpaceConvert(texture(cubeMap, l_ny).rgb) * d_ny;\n"
" p_pz += ColorSpaceConvert(texture(cubeMap, l_pz).rgb) * d_pz;\n"
" p_nz += ColorSpaceConvert(texture(cubeMap, l_nz).rgb) * d_nz;\n"
" w_px += d_px;\n"
" w_nx += d_nx;\n"
" w_py += d_py;\n"
......
......@@ -89,6 +89,17 @@ public:
vtkSetMacro(PrefilterLevels, unsigned int);
//@}
//@{
/**
* Set/Get the conversion to linear color space.
* If the input cubemap is in sRGB color space and the conversion is not done by OpenGL
* directly with the texture format, the conversion can be done in the shader with this flag.
*/
vtkGetMacro(ConvertToLinear, bool);
vtkSetMacro(ConvertToLinear, bool);
vtkBooleanMacro(ConvertToLinear, bool);
//@}
protected:
vtkPBRPrefilterTexture() = default;
~vtkPBRPrefilterTexture() override;
......@@ -97,6 +108,7 @@ protected:
unsigned int PrefilterLevels = 5;
unsigned int PrefilterSamples = 1024;
vtkOpenGLTexture* InputCubeMap = nullptr;
bool ConvertToLinear = false;
private:
vtkPBRPrefilterTexture(const vtkPBRPrefilterTexture&) = delete;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment