development branch shader input

I’ve been using the development branch because of a few flexibilities it grants with shaders. I have even started using some of the changes from [url]New Cg shader inputs]
The statements I’ve been using look a bit like this

self.terrain.setShaderInput("normalMapStrength", [2.5])

I recently updated to a newer daily and the statement above actually freeze the application. Just to be clear its not even the shader that causes the freeze. It doesn’t get that far. It doesn’t run past that line of code.

I’m guessing this is a bug?

Does it work if you remove the square brackets?

self.terrain.setShaderInput("normalMapStrength", 2.5)

Could you please put together the simplest sample program that reproduces the freeze?

Certainly. Sorry. I wasn’t trying to be lazy, but I wasn’t sure if the proper code style for shader inputs changed in the dev branch.

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        
        # Load the environment model.
        self.environ = self.loader.loadModel("models/environment")
        self.environ.setShaderInput("normalMapStrength", [2.5])
        print "didn't freeze."


app = MyApp()
app.run()

On my computer that results in a freeze. Yes removing the brackets doesn’t cause a freeze, but the code with the brackets was working in a previous build and they are functionally different. For example, removing the brackets in my terrain engine will crash my shader with the following error.

I guess I can just switch back to the old style for now, but I needed to get a lot of individual floats into my shader, and I didn’t want to sacrifice precision, create a lot of overhead, or use illogical matrices. I thought the new input style in dev was getting me closer to that ideal. Perhaps I can just interject the question: what is the best way to achieve that? As always, thank you for all the generous help.

What is the data type in the shader? If it’s float4 or something similar, then using [] is the wrong way to specify them, use tuples or VBase4 instead, or just specify them as individual parameters to setShaderInput.

I don’t recommend using arrays if you have a fixed number of inputs.

For the record, that code doesn’t freeze for me on latest dev.

The datatype I would like to have in the shader is a single float, not a float4. When I simply pass a float as input however the shader receives it as a float4. So I was trying to follow the advice in this post [url]New Cg shader inputs]. The shader still received this as a float2 for some reason, but I thought that was a bit better at least.

Now that format stopped working for me. Is there a way to input individual floats?

It works the other way around. The code first looks at the inputs that your shader uses, and then tries to match up the inputs you passed to the input type of the shader. So the code should (theoretically) be able to pass it properly to the shader if the shader specifies a “float” and you pass it without brackets.

Really?! Well that has always resulted in an error like this for me.

Here’s a simple program to duplicate this error.

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

def makeShader(name='test.sha'):
    string = '''
    void vshader(float4 vtx_position : POSITION,
                 out float4 l_position : POSITION,
                 uniform float4x4 mat_modelproj)
    {
      l_position=mul(mat_modelproj, vtx_position);
    }

    void fshader(in uniform float test,
                 out float4 o_color : COLOR)
    {
      o_color=float4(test, test, test, 1.0);
    }
    '''
    f = open(name, 'w')
    f.write(string)

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        # Load the environment model.
        self.environ = self.loader.loadModel("models/environment")
        self.environ.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 150, 0)

        makeShader()
        self.environ.setShaderInput("test", 1.0)
        myShader = Shader.load("test.sha", Shader.SLCg)
        self.environ.setShader(myShader)

app = MyApp()
app.run()

I still get that error whether the variable is in the vertex or fragment shader.

Is there just some strange issue on my computer? Can anyone else run that program and see if it duplicates my error?

EDIT:

Ok it actually looks like it was just implicit casting mentioned memecss’s thread that was not working out at all. In essence you must change this

self.environ.setShaderInput("test", [1.0])

to this

self.environ.setShaderInput("test", PTAFloat([1.0]))

That allows for individual float parameters, and its the only thing I’ve found so far that works.

I’ve already checked in a fix for this a couple of days ago. I didn’t tell you yet because the buildbot has been having issues and a build with the new changes hasn’t been made yet.