Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P3D - Something wrong with PShape shading #2018

Closed
RectangleWorld opened this issue Aug 12, 2013 · 15 comments · Fixed by #2644
Closed

P3D - Something wrong with PShape shading #2018

RectangleWorld opened this issue Aug 12, 2013 · 15 comments · Fixed by #2644
Assignees
Labels

Comments

@RectangleWorld
Copy link

(Possibly related to 2014)

Something seems to be wrong with the way lighting is being calculated (at least on the two machines where I tested my code). Note the bright areas at the bottom of the sphere (see below), which is lit from above by a directional light. The vertices at the edge of a surface seem to be the culprit (and maybe this is not an easy thing to fix). I see the same behavior with the default lights().

Simple test code is below. The camera rotates around the sphere. If you watch it running you'll see some strange abrupt change in lighting, especially at the lower sphere detail setting. The screencaps show the same code, first with the default sphere detail, the last two created with sphereDetail(10,10).

default_res_01
res_10_10_01
res_10_10_02

Full source code for the example:

float cameraAngle;
float cameraAngleInc;
PShape sphere;

void setup() {
  size(400,400,P3D);
  smooth(8);
  noStroke();
  sphereDetail(10,10);
  sphere = createShape(SPHERE, 150);
  cameraAngle = 0;
  cameraAngleInc = TWO_PI/600;
}

void draw() {
  cameraAngle += cameraAngleInc;
  camera(500*cos(cameraAngle),300,500*sin(cameraAngle),0,0,0,0,-1,0);
  directionalLight(204,204,204,0,-1,0);
  ambientLight(24,24,24);
  background(0);
  shape(sphere);
}

void keyPressed() {
  saveFrame("frame_####.png");
}
@codeanticode
Copy link
Member

Hello, thanks a lot for your report! In fact, it is issue #1232, which I just closed since yours more detailed. Take a look at the notes and links in #1232 though, which I think point to the solution. However, I haven't had the chance to work on it yet.

@RectangleWorld
Copy link
Author

Just want to note that this issue is still present in the latest beta 2.1b1.

@codeanticode
Copy link
Member

yes, I haven't had the chance to look into it yet.

@RectangleWorld
Copy link
Author

I don't want to be a pest, because I am very grateful for Processing and the hard work that goes into it! And I wish I could contribute my time to help but I'm afraid I don't have the expertise.

In any case, I want to mention that this issue is still present in 2.1.1, and I think "enhancement" might be the wrong label for this issue, because it seems to be a genuine bug. But I understand there are lots of more serious bugs that come up.

Thanks again for all you do.

@TheWitnesses
Copy link

One possible explanation is that because the triangles are so large, the light render is lighting up all of the triangle evenly, but it can't wrap fully around the object. Due to the big flat surface of the triangles, the lighting can't spread properly. If smaller triangles were used, then the sphere would be lit up more evenly.

@JakubValtar
Copy link
Contributor

I tracked this problem down to LightVert.glsl
https://github.com/processing/processing/blob/master/core/src/processing/opengl/LightVert.glsl#L86-90

  if (dot(-one_float * ecVertex, ecNormal) < zero_float) {
    // If normal is away from camera, choose its opposite.
    // If we add backface culling, this will be backfacing
    ecNormal *= -one_float;
  }

normals

This creates problems when normal vectors are not perpendicular to surrounding polygons, but are interpolated between adjacent polygons so the lighting won't create an unwanted edge (case of sphere). Shader inverts the normal if it is pointing away from the camera. However, this doesn't mean that all adjacent polygons are backfacing. Some vertices thus get wrong normals and different amounts of light than they should have. This creates ugly transitions from dark to light at the edges you are seeing.

You can try to run above example code with the sphereDetail(3,2); instead. Bottom vertex is lit up because the normal is inverted.

I'd like to fix this, but I'm not sure what is processing going for in terms of displaying and lighting back sides of polygons. Can @codeanticode elaborate what's the idea behind inverting in 76fb389?

(edit - sorry, I explained it wrong the first time)

@codeanticode
Copy link
Member

@JakubValtar Hello and thanks so much for your detailed analysis of the issue. I believe you are correct in your description of problems with the normal calculation. Right now I'm working on something else, but will get back to this as soon possible. Some potentially useful notes on this other issue: #1232 (see the Renderman reference)

@JakubValtar
Copy link
Contributor

Thanks, I will think of a solution in the meantime.

The Renderman discourages the practice of flipping normals, because it causes artifacts we are seeing.

Just to be clear: do you want the polygons to have same appearance from both sides, or do you want the side facing the light source to be lit and the other side to have just ambient light?

@codeanticode
Copy link
Member

We would like to have the side facing the light source to be lit, while the other just having ambient light.

@JakubValtar
Copy link
Contributor

Sorry, I asked the wrong question. I meant:

Do you want the inside of the objects to be also lit? Both sides of polygons to reflect the light from appropriate side?

Making back side of polygons dark/invisible would solve the problem, but change the behavior and possibly break sketches which count on the fact that Processing treats front faces and back faces the same. (By front face I mean the side where normal vector points towards the observer.)

@codeanticode
Copy link
Member

Your original question was well phrased, and your last comment it is also correct. It is just that I didn't think carefully about the implications of making the back sides unlit. As you pointed out, doing so will change the way lighting in Processing has worked since its beginnings, with the undesirable consequence of breaking sketches that depend on that behavior. So, the conclusion is that we need to fix the lighting artifacts (due to the normal flipping) but at the same time keep "dual-side lighting".

@JakubValtar
Copy link
Contributor

Ok, I have it fixed in my branch. I'm going to make a few small improvements, test it and send pull request when it's ready. It will take a few days since there are a lot of small fixes to make tesselation produce triangles with correct front faces and normals.

@codeanticode
Copy link
Member

This is great, thanks so much again. Let me know if you have any questions about the tessellation code in the OpenGL renderer.

@RectangleWorld
Copy link
Author

You guys are both awesome. Looking forward to trying it out sometime!

(Woops...sorry I closed the issue accidentally! Reopened.)

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants