diff --git a/docs/notes/renderer_getting_started.md b/docs/notes/renderer_getting_started.md index 633e9529..615d23f2 100644 --- a/docs/notes/renderer_getting_started.md +++ b/docs/notes/renderer_getting_started.md @@ -91,18 +91,18 @@ Shaders are the most flexible part of the PyTorch3D rendering API. We have creat A shader can incorporate several steps: - **texturing** (e.g interpolation of vertex RGB colors or interpolation of vertex UV coordinates followed by sampling from a texture map (interpolation uses barycentric coordinates output from rasterization)) -- **lighting/shading** (e.g. ambient, diffuse, specular lighting, Phong, Gourad, Flat) +- **lighting/shading** (e.g. ambient, diffuse, specular lighting, Phong, Gouraud, Flat) - **blending** (e.g. hard blending using only the closest face for each pixel, or soft blending using a weighted sum of the top K faces per pixel) We have examples of several combinations of these functions based on the texturing/shading/blending support we have currently. These are summarised in this table below. Many other combinations are possible and we plan to expand the options available for texturing, shading and blending. -|Example Shaders | Vertex Textures| Texture Map| Flat Shading| Gourad Shading| Phong Shading | Hard blending | Soft Blending | +|Example Shaders | Vertex Textures| Texture Map| Flat Shading| Gouraud Shading| Phong Shading | Hard blending | Soft Blending | | ------------- |:-------------: | :--------------:| :--------------:| :--------------:| :--------------:|:--------------:|:--------------:| | HardPhongShader | :heavy_check_mark: |||| :heavy_check_mark: | :heavy_check_mark:|| | SoftPhongShader | :heavy_check_mark: |||| :heavy_check_mark: | | :heavy_check_mark:| -| HardGouradShader | :heavy_check_mark: ||| :heavy_check_mark: || :heavy_check_mark:|| -| SoftGouradShader | :heavy_check_mark: ||| :heavy_check_mark: ||| :heavy_check_mark:| +| HardGouraudShader | :heavy_check_mark: ||| :heavy_check_mark: || :heavy_check_mark:|| +| SoftGouraudShader | :heavy_check_mark: ||| :heavy_check_mark: ||| :heavy_check_mark:| | TexturedSoftPhongShader || :heavy_check_mark: ||| :heavy_check_mark: || :heavy_check_mark:| | HardFlatShader | :heavy_check_mark: || :heavy_check_mark: ||| :heavy_check_mark:|| | SoftSilhouetteShader ||||||| :heavy_check_mark:| diff --git a/pytorch3d/renderer/__init__.py b/pytorch3d/renderer/__init__.py index 3303c34c..e020dfbe 100644 --- a/pytorch3d/renderer/__init__.py +++ b/pytorch3d/renderer/__init__.py @@ -18,16 +18,16 @@ from .lighting import DirectionalLights, PointLights, diffuse, specular from .materials import Materials from .mesh import ( HardFlatShader, - HardGouradShader, + HardGouraudShader, HardPhongShader, MeshRasterizer, MeshRenderer, RasterizationSettings, - SoftGouradShader, + SoftGouraudShader, SoftPhongShader, SoftSilhouetteShader, TexturedSoftPhongShader, - gourad_shading, + gouraud_shading, interpolate_face_attributes, interpolate_texture_map, interpolate_vertex_colors, diff --git a/pytorch3d/renderer/mesh/__init__.py b/pytorch3d/renderer/mesh/__init__.py index cb890867..32e431e5 100644 --- a/pytorch3d/renderer/mesh/__init__.py +++ b/pytorch3d/renderer/mesh/__init__.py @@ -5,14 +5,14 @@ from .rasterizer import MeshRasterizer, RasterizationSettings from .renderer import MeshRenderer from .shader import ( HardFlatShader, - HardGouradShader, + HardGouraudShader, HardPhongShader, - SoftGouradShader, + SoftGouraudShader, SoftPhongShader, SoftSilhouetteShader, TexturedSoftPhongShader, ) -from .shading import gourad_shading, phong_shading +from .shading import gouraud_shading, phong_shading from .texturing import ( # isort: skip interpolate_face_attributes, interpolate_texture_map, diff --git a/pytorch3d/renderer/mesh/shader.py b/pytorch3d/renderer/mesh/shader.py index 45c75d95..1fbae6a6 100644 --- a/pytorch3d/renderer/mesh/shader.py +++ b/pytorch3d/renderer/mesh/shader.py @@ -14,7 +14,7 @@ from ..blending import ( from ..cameras import OpenGLPerspectiveCameras from ..lighting import PointLights from ..materials import Materials -from .shading import flat_shading, gourad_shading, phong_shading +from .shading import flat_shading, gouraud_shading, phong_shading from .texturing import interpolate_texture_map, interpolate_vertex_colors # A Shader should take as input fragments from the output of rasterization @@ -126,7 +126,7 @@ class SoftPhongShader(nn.Module): return images -class HardGouradShader(nn.Module): +class HardGouraudShader(nn.Module): """ Per vertex lighting - the lighting model is applied to the vertex colors and the colors are then interpolated using the barycentric coordinates to @@ -138,7 +138,7 @@ class HardGouradShader(nn.Module): .. code-block:: - shader = HardGouradShader(device=torch.device("cuda:0")) + shader = HardGouraudShader(device=torch.device("cuda:0")) """ def __init__(self, device="cpu", cameras=None, lights=None, materials=None): @@ -159,7 +159,7 @@ class HardGouradShader(nn.Module): cameras = kwargs.get("cameras", self.cameras) lights = kwargs.get("lights", self.lights) materials = kwargs.get("materials", self.materials) - pixel_colors = gourad_shading( + pixel_colors = gouraud_shading( meshes=meshes, fragments=fragments, lights=lights, @@ -170,7 +170,7 @@ class HardGouradShader(nn.Module): return images -class SoftGouradShader(nn.Module): +class SoftGouraudShader(nn.Module): """ Per vertex lighting - the lighting model is applied to the vertex colors and the colors are then interpolated using the barycentric coordinates to @@ -182,7 +182,7 @@ class SoftGouradShader(nn.Module): .. code-block:: - shader = SoftGouradShader(device=torch.device("cuda:0")) + shader = SoftGouraudShader(device=torch.device("cuda:0")) """ def __init__( @@ -213,7 +213,7 @@ class SoftGouradShader(nn.Module): cameras = kwargs.get("cameras", self.cameras) lights = kwargs.get("lights", self.lights) materials = kwargs.get("materials", self.materials) - pixel_colors = gourad_shading( + pixel_colors = gouraud_shading( meshes=meshes, fragments=fragments, lights=lights, diff --git a/pytorch3d/renderer/mesh/shading.py b/pytorch3d/renderer/mesh/shading.py index a6c451db..69d1e305 100644 --- a/pytorch3d/renderer/mesh/shading.py +++ b/pytorch3d/renderer/mesh/shading.py @@ -79,7 +79,7 @@ def phong_shading( return colors -def gourad_shading( +def gouraud_shading( meshes, fragments, lights, cameras, materials ) -> torch.Tensor: """ diff --git a/tests/data/test_simple_sphere_light_gourad.png b/tests/data/test_simple_sphere_light_gouraud.png similarity index 100% rename from tests/data/test_simple_sphere_light_gourad.png rename to tests/data/test_simple_sphere_light_gouraud.png diff --git a/tests/data/test_simple_sphere_light_gourad_elevated_camera.png b/tests/data/test_simple_sphere_light_gouraud_elevated_camera.png similarity index 100% rename from tests/data/test_simple_sphere_light_gourad_elevated_camera.png rename to tests/data/test_simple_sphere_light_gouraud_elevated_camera.png diff --git a/tests/test_rendering_meshes.py b/tests/test_rendering_meshes.py index e88b9c71..e6c782d2 100644 --- a/tests/test_rendering_meshes.py +++ b/tests/test_rendering_meshes.py @@ -25,7 +25,7 @@ from pytorch3d.renderer.mesh.rasterizer import ( from pytorch3d.renderer.mesh.renderer import MeshRenderer from pytorch3d.renderer.mesh.shader import ( BlendParams, - HardGouradShader, + HardGouraudShader, HardPhongShader, SoftSilhouetteShader, TexturedSoftPhongShader, @@ -51,7 +51,7 @@ def load_rgb_image(filename, data_dir=DATA_DIR): class TestRenderingMeshes(unittest.TestCase): def test_simple_sphere(self, elevated_camera=False): """ - Test output of phong and gourad shading matches a reference image using + Test output of phong and gouraud shading matches a reference image using the default values for the light sources. Args: @@ -128,12 +128,12 @@ class TestRenderingMeshes(unittest.TestCase): self.assertTrue(torch.allclose(rgb, image_ref_phong_dark, atol=0.05)) ###################################### - # Change the shader to a GouradShader + # Change the shader to a GouraudShader ###################################### lights.location = torch.tensor([0.0, 0.0, -2.0], device=device)[None] renderer = MeshRenderer( rasterizer=rasterizer, - shader=HardGouradShader( + shader=HardGouraudShader( lights=lights, cameras=cameras, materials=materials ), ) @@ -141,19 +141,19 @@ class TestRenderingMeshes(unittest.TestCase): rgb = images[0, ..., :3].squeeze().cpu() if DEBUG: Image.fromarray((rgb.numpy() * 255).astype(np.uint8)).save( - DATA_DIR / "DEBUG_simple_sphere_light_gourad%s.png" % postfix + DATA_DIR / "DEBUG_simple_sphere_light_gouraud%s.png" % postfix ) # Load reference image - image_ref_gourad = load_rgb_image( - "test_simple_sphere_light_gourad%s.png" % postfix + image_ref_gouraud = load_rgb_image( + "test_simple_sphere_light_gouraud%s.png" % postfix ) - self.assertTrue(torch.allclose(rgb, image_ref_gourad, atol=0.005)) + self.assertTrue(torch.allclose(rgb, image_ref_gouraud, atol=0.005)) self.assertFalse(torch.allclose(rgb, image_ref_phong, atol=0.005)) def test_simple_sphere_elevated_camera(self): """ - Test output of phong and gourad shading matches a reference image using + Test output of phong and gouraud shading matches a reference image using the default values for the light sources. The rendering is performed with a camera that has non-zero elevation.