eldee
July 29, 2019, 12:13pm
1
Until now I was sending the texture transform matrices manually towards my shaders using something like :
np.setShaderInput("texmat_%d" % index, np.getTexTransform(stage).getMat())
I’m trying to use instead the built-in texture matrices p3d_TextureMatrix[] but so far I can’t understand how the matrices are organized in the array. It seems that only the first entry is set, even if all the texture stages have a tex matrix applied.
rdb
July 29, 2019, 12:26pm
2
They should correspond to the texture stages. Do you have a test case that shows otherwise?
eldee
July 29, 2019, 12:32pm
3
Not yet only tested with my full app, I will make a simple one (if the problem is not in my own code )
eldee
July 29, 2019, 1:26pm
4
Here is the test case and actually the results are even weirder than I thought :
import os
from panda3d.core import Texture, TextureStage, CardMaker, Shader, load_prc_file_data
from direct.showbase.ShowBase import ShowBase
load_prc_file_data("", "gl-version 3 2")
def shader():
return Shader.make(Shader.SL_GLSL,
vertex="""
#version 410
uniform mat4 p3d_ProjectionMatrix;
uniform mat4 p3d_ModelViewMatrix;
in vec4 p3d_Vertex;
in vec4 p3d_MultiTexCoord0;
out vec4 texcoord;
void main() {
gl_Position = p3d_ProjectionMatrix * (p3d_ModelViewMatrix * p3d_Vertex);
texcoord = p3d_MultiTexCoord0;
}
""",
fragment="""
#version 410
uniform mat4 p3d_TextureMatrix[2];
uniform sampler2D p3d_Texture0;
uniform sampler2D p3d_Texture1;
in vec4 texcoord;
out vec4 frag_color;
void main() {
vec4 texcoord_tex0 = p3d_TextureMatrix[0] * texcoord;
//vec4 texcoord_tex0 = texcoord;
vec4 tex0 = texture(p3d_Texture0, texcoord_tex0.xy);
vec4 texcoord_tex1 = p3d_TextureMatrix[1] * texcoord;
//vec4 texcoord_tex1 = texcoord;
vec4 tex1 = texture(p3d_Texture1, texcoord_tex1.xy);
frag_color = tex0 * tex1;
}
""")
base = ShowBase()
cm = CardMaker('card')
card = render.attachNewNode(cm.generate())
card.setPos(-0.5, 3, -0.5)
card.set_shader(shader())
tex = loader.loadTexture('maps/smiley.rgb')
ts = TextureStage('first')
card.setTexture(ts, tex)
card.setTexScale(ts, 1, -1)
tex = loader.loadTexture('maps/noise.rgb')
ts = TextureStage('second')
card.setTexture(ts, tex)
card.setTexScale(ts, 2, 2)
card.ls()
base.run()
If I don’t use the texture matrices, the output is :
If I use the texture matrix of the first texture, the smiley is inverted :
If i use the texture matrix of the second texture, the noise texture disappears :
If I use the texture matrix for both textures, the result is even weirder :
eldee
July 30, 2019, 8:38am
5
Same problem on Mac and Linux so it’s not a driver problem. It looks like all the texture matrices are written in the first slot of the matrix array.
rdb
July 30, 2019, 5:31pm
6
Yeah, thanks for the clear test case, this has a straightforward fix:
For the record, texture stages without sort value are in indeterminate order, so you should generally always give them a distinct sort value.
eldee
July 30, 2019, 8:12pm
7
Thanks for the fix but also thanks for the info, that something I overlooked until now.
Side question, if a texture stage has no transform matrix applied, will there still be an entry in the TextureMatrix ?
rdb
July 30, 2019, 9:26pm
8
Yes, it will then contain the identity matrix.