# Shading a torus in TikZ

I would like to be able to shade a torus in TikZ to make it look like a surface in 3D, similarly to how the sphere in this code is shaded to give it a 3D feel but the opacity is such that it does not look like a solid ball:

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw (0,0) circle (1cm);
\draw (-1,0) arc (180:360:1cm and 0.5cm);
\draw[dashed] (1,0) arc (0:180:1cm and 0.5cm);
\shade[ball color=blue!10!white,opacity=0.50] (0,0) circle (1cm);
\end{tikzpicture}
\end{document}


Here is my attempt with the torus:

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
%Torus
\draw (0,0) ellipse (1.6 and .9);
\shade[ball color = blue!10!white, opacity=0.5] (0,0) ellipse (1.6 and .9);
%Hole
\begin{scope}[scale=.8]
\clip (0,1.3) circle (1.55);
\fill[white] (0,-1.27) circle (1.55);
\end{scope}
\begin{scope}[scale=.8]
\path[rounded corners=24pt] (-.9,0)--(0,.6)--(.9,0) (-.9,0)--(0,-.56)--(.9,0);
\draw[rounded corners=28pt] (-1.1,.1)--(0,-.6)--(1.1,.1);
\draw[rounded corners=24pt] (-.9,0)--(0,.6)--(.9,0);
\end{scope}
%Cut
\draw[dashed] (0,-.9) arc (270:90:.2 and .365);
\draw (0,-.9) arc (-90:90:.2 and .365);
\end{tikzpicture}
\end{document}


This is naive, since I'm using the same shading as for a ball, and I'm using clipping hacks to remove the shading from the hole. My attempt looks bad because it does not accurately reflect how light would hit the surface of a torus. Any tips for producing a realistically shaded torus would be greatly appreciated.

• Render it using a proper 3D programme - TikZ is not designed for this. Also, please post compilable code rather than mere fragments. – cfr Apr 25 '18 at 2:04
• – John Kormylo Apr 25 '18 at 3:05
• ... and here are some more, just drop the helix ... – user121799 Apr 25 '18 at 3:23
• I have seen both of these posts, but they are not helpful for me - either because I don't like how they look or because I don't understand how sketch works. I'm not something that looks truly 3D, I would only like to add an extra light spot onto the torus to make it look better than what I currently have. – rosterherik Apr 25 '18 at 3:40

That's not a too serious answer, but just to tell you that if you have an idea how the shading should look like, you can reverse engineer it with pgfplots. Here is an example.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}
\begin{document}
\begin{tikzpicture}
\begin{axis}[colormap/blackwhite,
view={30}{60},axis lines=none
]
samples=60, point meta=x+3*z*z-0.25*y,
domain=0:2*pi,y domain=0:2*pi,
z buffer=sort]
({(2+cos(deg(x)))*cos(deg(y))},
{(2+cos(deg(x)))*sin(deg(y))},
{sin(deg(x))});
\end{axis}
\end{tikzpicture}
\end{document}


The trick is to play with point meta. Is this shading realistic? Certainly not (unless you have some crazy light sources). Could you make it realistic? Yes, if you know what you're doing or study the asymptote manual long enough. So if you want something realistic, use asymptote. If you want a cartoon and like to play with pgfplots, you may potentially find this useful.

• Thank you for being so helpful marmot. This is closer to what I want than what I have, so it is useful. Is there a way to make this picture translucent? – rosterherik Apr 25 '18 at 3:43
• @rosterherik I am not sure I understand "translucent". Do you mean transparent? – user121799 Apr 25 '18 at 3:57
• @rosterherik To best way to thank on TeX.SX is to up-vote and award green ticks to what you think is the best answer :) – Andrew Apr 25 '18 at 4:27
• @rosterherik I agree that it is good to wait before accepting an answer but there is no reason why you cannot up-vote marmot's nice answer now: currently only one person has voted for the TeX.SX rodent and it is not you! – Andrew Apr 25 '18 at 10:52
• @rosterherik :) – Andrew Apr 26 '18 at 7:52

Not an answer just an explanation of a setting or two available in @marmot 's excellent answer that may answer your question of translucency to an acceptable level (marmots that is) so if we take the above answer and tweak the one line (I found 50 to be a safer memory value than 60) the Opacity looks better around 7.5 where the far walls are ghosted through the surface materials, personally think this is more understandable than covering with broken lines see Drawing Torus with semi-dashed line on it

   \addplot3[surf,opacity=0.7,
samples=50, point meta=x+3*z*z-0.25*y,


And the main collection of toroidal answers are at How to draw a torus

• Looks great!!!! P.S. the normal at a given point is given by n={cos(\u)*cos(\v), cos(\v)*sin(\u),sin(\v)}. Playing with this one may obtain a realistic shading (point meta = vector of light source . normal). – user121799 Mar 10 at 3:51