GLSL shader problem

Hi there,

I have a question regarding the use of shaders.
My system is currently equipped with an ATI graphics card.

As i’m working on a rts project that would require multiple hundreds of models moving around, i’ve started a looking into geometry instancing, which for my gfx card requires the use of GLSL shaders (i’ve received a lot of useful help on a seperate thread )

However, i seem to be unable to get this type of shaders to work with Panda3D.
When i implement even the simplest of GLSL shader, anything this shader is used on simple isn’t rendered in Panda3D.
The console however reports a succesfull compile of the shader.

I’ve tried 2 different ATI Radeon HD cards, a fresh install of W7 64bit, the latest catalyst drivers (12.3), fresh install of Panda1.8.0, yet that didn’t solve the problem.

GPU caps viewer tells me i have OpenGL 4.2 running & the GLSL tests from that program do work on my system.

Below are the shaders i’ve currently applied (i’ve used the solar system sample program & added these shaders to the sun model in step 3):

vertex shader

#version 140
 

void main() {
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}

fragment shader

#version 150
out vec4 MyFragColor;
void main(void)
{
    MyFragColor = vec4(0.4, 0.4, 0.8, 1.0);
}

Does anyone have any pointers for me?

I’ve just found this:

bugs.launchpad.net/panda3d/+bug/912674

could my problem be related to this error?

Actually I logged that bug. Sorry I didn’t connect the dots in my head. I thought you were seeing one object, not no objects at all, but this makes sense now.

I wasn’t sure if that bug was related to my custom build or with Panda itself, but if you are having the same problem then it might be a bug in the Panda code. I think it was one of the recent additions that caused the problem. My build is working after I went back and got older versions of some files, so I’ll take a look and see what the difference is with the latest code.

One other thing to try first is replacing MyFragColor with the default name gl_FragColor in the shader.

Thanks again teedee :slight_smile:

Changing the fragment shader didn’t help.

For what its worth, if i apply this shader, no objects are rendered. If i apply the geometry instancing one, only the base object is rendered (because it is niet affected by the shader maybe)

I’ve not forgotten about this, just been busy, and having a lot of trouble updating to the latest Panda code which seems to have broken my game in several places.

i understand completely

cheers

I believe I have found the problem Panda code.
In panda\src\glstuff\glShaderContext_src.I, the uses_custom_vertex_arrays function has been changed to always return true. In this case, most of my object with GLSL shader on them are no longer rendering. It looks like any object with a transform on it is not rendering.
If I revert the code to how it was in the previous revision, with GLSL shaders returning false and Cg shaders returning true, then the objects with GLSL shaders work properly as they did before.

Hmm, looks like a bug all right. What happens if you use p3d_Vertex instead of gl_Vertex?

David

The objects show up, but only because the shader fails:

:display:gsg:glgsg(error): An error occurred while compiling shader!
ERROR: 0:8: 'p3d_Vertex' : undeclared identifier
ERROR: 0:8: 'assign' :  cannot convert from '4X4 matrix of float' to 'Position 4-component vector of float'

Sorry, I should have clarified that I also meant for you to add “in vec4 p3d_Vertex;” to the top of the shader.

I’ve just committed some changes in the GLSL handling for another reason, and I ran into a few bugs along these lines. I fixed some, but not all. I’ll look a bit further.

David

Ah, yes I am used to GLSL providing my inputs for me. :slight_smile: I gave it a try but it seems to behave the same as gl_Vertex.
I suspect the data provided by gl_Vertex (and p3d_Vertex) is correct, since objects with a default transform seem to show up with their points in the right place.
Perhaps gl_ModelViewProjectionMatrix is getting the wrong transform, or the object is being culled out entirely.
I tested this with the same code as before, I’ll give the new code a try and see if that fixed anything.

Tried with the new code, but same problem remains.
Would it help if I provided a sample scene?

Not sure if it is related, but I also have a problem with DX9 spamming warnings and it looks like it being forced to use parasite buffers. I noticed that the function which determines if render-to-texture is supported or not changed since I synced up that code, so that was my first suspect. I filed a bug for that a few days ago.

Here’s a simple app that demonstrates the problem. If I run this under gdb and force GLShaderContext::uses_custom_vertex_arrays() to always return false, then this works. Otherwise it doesn’t render anything visible.

from panda3d.core import *
from direct.showbase.ShowBase import ShowBase

vshader = """
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
"""

fshader = """
void main() {
    gl_FragColor = vec4(1.0, 0.5, 1.0, 1.0);
}
"""

class Game(ShowBase):
    def __init__(self):
        """Get the game ready to play."""
        ShowBase.__init__(self)
        self.model = self.loader.loadModel('smiley')
        self.model.reparentTo(render)
        self.shader = Shader.make(Shader.SLGLSL, vshader, fshader)
        self.model.setShader(self.shader)
        self.cam.setPos(0, -10, 0)

game = Game()
game.run()

In panda/src/glstuff/glGraphicsStateGuardian_src.cxx GLGraphicsStateGuardian::begin_draw_primitives - it assumes this is a Cg shader and not GLSL if GLShaderContext ::uses_custom_vertex_arrays returns true.

  if (_current_shader_context == 0 || !_current_shader_context->uses_custom_vertex_arrays()) {
    // No shader, or a non-Cg shader.
    if (_vertex_array_shader_context != 0) {
      _vertex_array_shader_context->disable_shader_vertex_arrays(this);
    }
    if (!update_standard_vertex_arrays(force)) {
      return false;
    }
  } else {
    // Cg shader.

If I force uses_custom_vertex_arrays() to return false, the shader works. But if it uses a a texure (uniform sampler2D tex_0), the texture is all black. So something else seems to be broken with texture bindings when using GLSL.

Regarding the recently added tessellation shader code, in shader.cxx:

////////////////////////////////////////////////////////////////////
//     Function: Shader::ShaderCapabilities::clear()
//       Access: Public
//  Description:
////////////////////////////////////////////////////////////////////
void Shader::ShaderCaps::
clear() {
  _supports_glsl = false;
  
#ifdef HAVE_CG
  _active_vprofile = CG_PROFILE_UNKNOWN;
  _active_fprofile = CG_PROFILE_UNKNOWN;
  _active_gprofile = CG_PROFILE_UNKNOWN;
  _active_fprofile = CG_PROFILE_UNKNOWN;
  _ultimate_vprofile = CG_PROFILE_UNKNOWN;
  _ultimate_fprofile = CG_PROFILE_UNKNOWN;
  _ultimate_gprofile = CG_PROFILE_UNKNOWN;
  _ultimate_fprofile = CG_PROFILE_UNKNOWN;
#endif
}

I think there is a typo here, the fourth assignments should be be to the _tprofile instead of _fprofile.

Ah, indeed, thank you.

Hi all & thanks on keeping this up.

I understand there is a lot on your minds, but do you have an idea when this could be fixed in a panda release?

Sorry for the delay. I promise I’ll take a look at it before the next bugfix release. Looks like I messed something up when I added support for custom vertex arrays.

@drwr: Tessellation shaders, huh? That’s so cool!

Somewhat old thread here, but I was working on something involving GLSL today and was running into some problems along the lines described here. After staring at the C++ code for (quite) a while, I now believe that this is not actually a bug.

Starting with the sample shader code from above:

vshader = """
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
"""

fshader = """
void main() {
    gl_FragColor = vec4(1.0, 0.5, 1.0, 1.0);
}
"""

Variable naming is very important here, and to my eye the C++ code is somewhat inconsistent in its handling of binding. For uniform variables either “gl_” or “p3d_” is acceptable, but for attributes only “p3d_” will be bound. So as a first pass, the code above needs to be changed to:

vshader = """
attribute vec4 p3d_Vertex;
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * p3d_Vertex;
}
"""

That’ll get at least a pink blob rendered. To get it textured, it needs to look like this:

vshader = """
attribute vec4 p3d_Vertex;
attribute vec4 p3d_MultiTexCoord0;
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * p3d_Vertex;
    gl_TexCoord[0] = p3d_MultiTexCoord0;
}
"""

fshader = """
uniform sampler2D p3d_Texture0;
void main() {
    gl_FragColor = texture2D(p3d_Texture0, gl_TexCoord[0].st);
}
"""

Note that:

  • “p3d_ModelViewProjectionMatrix” will work, and is probably a better choice than the “gl_” name used in the code above (I have a sneaking suspicion that the “gl_” version just works by accident).

  • “gl_MultiTexCoord0” won’t work, because attributes have to start with the “p3d_” prefix.

  • “gl_Texture0” doesn’t seem to work, in spite of it being a uniform, and unfortunately it doesn’t cause an error to be logged (I believe this is because anything beginning “gl_” is special to GLSL, so it isn’t even reported back to Panda’s C++ code).

  • “p3d_Texture[0…X]” is the only type of name that works for a sampler here (i.e. p3d_Tex0, etc. is no good), unless you explicitly declare a texture with the same name in your Panda code (using set_shader_input()). If you go that route, though, don’t name your variable “p3d_*” (i.e. use “Tex0”, not “p3d_Tex0”) or you’ll get an “Unrecognized uniform name” error. (For 90% of use cases, p3d_Texture[0…X] is your best bet.)

I’d recommend, then, that the original example should best be implemented as:

vshader = """
uniform mat4 p3d_ModelViewProjectionMatrix;
attribute vec4 p3d_Vertex;
attribute vec4 p3d_MultiTexCoord0;
void main() {
    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
    gl_TexCoord[0] = p3d_MultiTexCoord0;
}
"""

fshader = """
uniform sampler2D p3d_Texture0;
void main() {
    gl_FragColor = texture2D(p3d_Texture0, gl_TexCoord[0].st);
}
"""

With this implementation I successfully got a textured smiley rendered in my window (caveat: I build my own Panda from the latest CVS sources, so there’s a chance there’s some other issue with recent public builds).

Given all of the above, I’m pretty sure that the bug mentioned previously in this thread (#912674) isn’t actually a problem, as the example code provided there is using “gl_” instead of “p3d_” throughout.

Hope all of this is of some help to the original posters, even at this late date. I’m going to be working in this general area of functionality for the next few days, so if anyone has additional problems/questions feel free to shout 'em out and I’ll see if I can help further.

–jonah

Thanks for taking a look at this issue. If it solves the problem it would still very much help. We are planning on releasing our game within a few months.

I’ve been using older versions of the shader code from before this problem started happening, and it would be great to be able to keep in sync with Panda’s latest updates. I will try implementing your suggestions soon.