glsl and multiple objects and flickering colors

I have set up four planes and each should have their own color. But instead I’m seeing flickering colors (colors change when I move camera):
What I’m doing wrong?

cube = NodePath(PandaNode("cube"))
cube.reparentTo(render)
        
planes = [(25, 25), (25, 75), (75, 25), (75, 75)]
color = [(0, 255, 0), (255, 0, 0), (255, 255, 0), (0, 0, 255)]

shader = Shader.load(Shader.SLGLSL, "models/vertexprog.glsl", "models/fragmentprog.glsl","") 
for x in range(len(planes)):
    block = loader.loadModel("models/plane.egg")
    block.reparentTo(cube)
    block.setPos(planes[x][0], planes[x][1], 0)
    block.setShaderInput("pos", planes[x][0], planes[x][1], 0, 0)
    block.setShaderInput("color", color[x][0], color[x][1], color[x][2], 0)

cube.setShader(shader)

fragment shader is following

uniform vec4 color;

void main(void)
{
	gl_FragColor = color;
}



Since you’re not testing for occlusion, and since your planes overlap a bit, the last plane drawn is the one you see. Unless you specify a fixed render order using binning, Panda will not guarantee any particular draw order, so that’s why it appears to flicker.

Change any one of those properties to avoid the flicker. :slight_smile:

David

You can call setDepthOffset(1) on the plane that should be in the foreground, that should fix the z-fighting.

Can you provide some code snipets?
The words “occlusion” and “binning” are new words to me.

Meanwhile I added some space between planes, but same result.


Waaait a minute. I think we both misunderstood your problem.

I think the problem is here that Panda is sharing the same shader context where it shouldn’t, or something like that. In any way, for some reason it doesn’t issue the right color for the right plane.

Here is my testcase:
zed.ee/panda/flicker.zip

Could you file a bug report on bugs.launchpad.net/panda3d so that it doesn’t get forgotten?

done
bugs.launchpad.net/panda3d/+bug/551129

Thanks!

David

could the error below be also related to this issue?
All inputs are correctly set

On one machine I got no error, but same flickering effect. When running panda (and myscript) from visual studio (with some breakpoints triggred) I got also no erros.

also when adding, then everything works as it should (correct values are passed for each node/object)

render.setShaderInput("pos", 0, 0, 0, 0)
Assertion failed: Shader input pos is not present.
 at line 382 of c:\panda_cvs\panda\src\pgraph\shaderAttrib.cxx
Assertion failed: Shader input pos is not present.
 at line 382 of c:\panda_cvs\panda\src\pgraph\shaderAttrib.cxx
Assertion failed: Shader input pos is not present.
 at line 382 of c:\panda_cvs\panda\src\pgraph\shaderAttrib.cxx
Assertion failed: Shader input pos is not present.
 at line 382 of c:\panda_cvs\panda\src\pgraph\shaderAttrib.cxx
Traceback (most recent call last):
  File "c:\panda_cvs\built\direct\showbase\ShowBase.py", line 1678, in __igLoop
    self.graphicsEngine.renderFrame()
AssertionError: Shader input pos is not present.
 at line 382 of c:\panda_cvs\panda\src\pgraph\shaderAttrib.cxx
:task(error): Exception occurred in PythonTask igLoop
Traceback (most recent call last):
  File "GraderSimulator.py", line 386, in <module>
    run()
  File "c:\panda_cvs\built\direct\showbase\ShowBase.py", line 2532, in run
    self.taskMgr.run()
  File "c:\panda_cvs\built\direct\task\Task.py", line 502, in run
    self.step()
  File "c:\panda_cvs\built\direct\task\Task.py", line 460, in step
    self.mgr.poll()
  File "c:\panda_cvs\built\direct\showbase\ShowBase.py", line 1678, in __igLoop
    self.graphicsEngine.renderFrame()
AssertionError: Shader input pos is not present.
 at line 382 of c:\panda_cvs\panda\src\pgraph\shaderAttrib.cxx

I’m using latest code from cvs.

I’m trying to debug this issue and added some debug output.

Although there is four planes, shader input values are only read three times.

do_frame
Vertex shader was successfully compiled to run on hardware.

get_shader_input_vector, id: color,  vec:255 0 0 0
get_shader_input_vector, id: color,  vec:255 255 0 0
get_shader_input_vector, id: color,  vec:0 0 255 0
do_frame
get_shader_input_vector, id: color,  vec:255 0 0 0
get_shader_input_vector, id: color,  vec:255 255 0 0
get_shader_input_vector, id: color,  vec:0 0 255 0
do_frame

Is that normal?

This is the output when colors are flickering and camera is still.

do_frame
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
do_frame
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
do_frame
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
do_frame
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
do_frame
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
do_frame
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
do_frame
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
do_frame
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
do_frame
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
do_frame
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
do_frame
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
do_frame
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
do_frame
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB684, id: color,  vec:255 0 0 0
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
do_frame
get_shader_input_vector, this: 00ECB4B4, id: color,  vec:0 255 0 0
get_shader_input_vector, this: 00ECB794, id: color,  vec:0 0 255 0
get_shader_input_vector, this: 00ECB70C, id: color,  vec:255 255 0 0
do_frame

Seems I tracked down the bug, but not 100% sure.
I added the line starting with ** to glGraphicsStateGuardian_src.cxx

  if (context == 0 || (context->valid() == false)) {
    if (_current_shader_context != 0) {
      _current_shader_context->unbind(this);
      _current_shader = 0;
      _current_shader_context = 0;
    }
  } else {
    if (context != _current_shader_context) {
      // Use a completely different shader than before.
      // Unbind old shader, bind the new one.
      if (_current_shader_context != 0) {
        _current_shader_context->unbind(this);
      }
      context->bind(this);
      _current_shader = shader;
      _current_shader_context = context;
**      context->issue_parameters(this, Shader::SSD_shaderinputs);
    } else {
#ifdef OPENGLES_2
      context->bind(this, false);
#endif
      if (state_has_changed) {
        // Use the same shader as before, but with new input arguments.
        context->issue_parameters(this, Shader::SSD_shaderinputs);
      }
    }
  }

Hm, it does seem like that line should be placed there. Can you confirm whether this actually does fix the issue? If so, I’ll check it in.

Thanks very much for looking into this issue!

Very nice! :slight_smile:

David

Yes, it does fix the issue. Sorry for not being very clear previously.

Thanks! I committed this fix, and it will be in 1.7.1.