Why does EdgeLighting on patches not work?

조회 수: 1 (최근 30일)
Theo
Theo 2011년 10월 21일
편집: Will 2019년 7월 29일
I'm trying to create a line on a surface with the EdgeLighting property set to phong (for example). An example code would be
[x,y,z] = sphere(40);
S = surf(x,y,z);
P = patch(x(32,:), y(32,:), z(32,:), 'k');
set(S, 'FaceLighting', 'phong', 'EdgeColor', 'none', 'FaceColor', 'inter');
set(P, 'EdgeLighting', 'phong', 'EdgeColor', 'k', 'FaceColor', 'none');
light
However, the line (patch) is not lit. In other words, replacing the ('EdgeLighting', 'phong') option to 'none' does not affect the figure. Does anybody spot the problem?
  댓글 수: 1
Theo
Theo 2011년 10월 26일
Bumping this up, as it seems to be a fairly elementary issue. Any comments?

댓글을 달려면 로그인하십시오.

채택된 답변

Patrick Kalita
Patrick Kalita 2011년 10월 26일
It is being lit, just not the way you're expecting based on how the patch was created.
For example, after doing this...
[x,y,z] = sphere(40);
S = surf(x,y,z);
P = patch(x(32,:), y(32,:), z(32,:), 'k');
set(S, 'FaceLighting', 'phong', 'EdgeColor', 'none', 'FaceColor', 'inter');
set(P, 'EdgeLighting', 'phong', 'EdgeColor', 'k', 'FaceColor', 'none');
light
... view it from this angle ...
view(0, 50)
... now from this angle...
view(-90, 50)
The patch's edge certainly does change color based on its orientation relative to the light. I'm guessing you were expecting the patch to be lit similar to the surface, which obviously is not what's happening now. Right now, the light seems to affect the entire edge uniformly. That's because the patch is using automatically calculated normals:
get( P, 'VertexNormals' )
You can see all the normals are pointing the same direction, namely down. Hence the light has the same effect on each vertex. Using the one-dimensional X, Y, and Z data that you gave to the patch, the normal calculator couldn't have possibly know that the data represented part of a sphere -- so it did the best it could. But you can tell the patch to use normals more appropriate for this situation. The normals of a spherical surface are trivial:
N = [ get(P, 'XData') get(P, 'YData') get(P, 'ZData') ]; % Caution! this only works for a sphere!!!
set( P, 'VertexNormals', N )
view(180, 40)
Now the patch edge is lit as I think you were expecting.
  댓글 수: 2
Theo
Theo 2011년 10월 26일
Perfect! Thanks. I also add that the surfnorm command will allow the normals to be computed from a given surface data. So that can be combined to define the lighting on the patches.
If anybody is wondering why we should bother with this, we can now modify the wireframe code by Ennis on the file exchange to use patches. This allows us to plot surfaces with dense meshes, but a less dense distribution of edges. However, the wireframe code previously used lines instead of patches, so one was unable to light the edges correctly.
Will
Will 2019년 7월 29일
편집: Will 2019년 7월 29일
For the record, the approach using surfnorm for any surface, not just the spherical example case, would be:
[nx, ny, nz] = surfnorm(x, y, z);
N = [nx(32,:); ny(32,:); nz(32,:)]';
set(P, 'VertexNormals', N)
I'm interested in how to apply this for a line across a surface that is not defined by the mesh of the surface. I've asked this in a separate question here.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Walter Roberson
Walter Roberson 2011년 10월 24일
The OpenGL renderer does not support phong; this is documented in the Figure Properties page.
I do not see anything in your code that requires transparency, so you might be able to simply switch to zbuffer rendering of your figure.
  댓글 수: 1
Theo
Theo 2011년 10월 24일
Issuing the command,
set(gcf, 'Renderer', 'Zbuffer')
does not seem to change the lighting on the edges. Nor does trying
set(P, 'Edgelighting', 'gouraud')

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Surface and Mesh Plots에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by