accessing "unused" UVs in a shader

In my EGG file I have stored some data in named UV sets that I need to access in my shader. The problem is Panda is “optimizing” out the extra UVs because they are not used by any texture/texture stage.
I can access them if I insert dummy textures in the EGG file that use these UVs, for example:

<Texture> dummy1_png {
  "../textures/dummy1.png"
  <Scalar> uv-name { blend }
}

which is pretty hacky. Is there a better way to be able to access my extra UVs?

It depends on the exporter.
maya2egg has an option to keep all uv sets, while chicken is easy to mod, if it’s not already there.

I’ve written my own exporter, it definitely writes the UVs in the EGG file, and Panda loads them, but they are not available to the shader unless they are actually called for by a texture. It is a good optimization, but in this specific case I need a way to get them to the shader.

I understand your problem now. :astonished:

Actually, you can access any vertex data column in the shader, by using “floatN vtx_ANYTHING” syntax, but unfortunately the column name for non-default UV set is always “texcoord.XXXX”, so it’s impossible to get it this way because “float2 vtx_texcoord.XXXX” will generate floating point error. Not sure about the new shader system’s interface though.

The workaround is as you have tried, by binding a dummy texture to the 2nd UV, but you don’t have to insert it into the EGG.
You can add that dummy texture on the fly :

from pandac.PandaModules import *
import direct.directbase.DirectStart

tri = loader.loadModel('unused UV')
tri.reparentTo(aspect2d)

ts = TextureStage('')
ts.setTexcoordName('2nd')
ts.setSort(1) # <--- must be explicitly layed after the default
tri.setTexture(ts,Texture())

sha = loader.loadShader('unused UV.sha')

base.accept('enter', tri.setShader, [sha])
base.accept('delete', tri.setShaderOff)
run()
//Cg

void vshader( 
  in float4 vtx_position : POSITION, 
  in float2 vtx_texcoord1 : TEXCOORD1, 
  in uniform float4x4 mat_modelproj,
  out float4 l_color0 : COLOR0, 
  out float4 l_position : POSITION, 
  out float2 l_texcoord1 : TEXCOORD1
  )
{
  l_position = mul(mat_modelproj, vtx_position);
  l_texcoord1 = vtx_texcoord1;
}

void fshader(
  in float2 l_texcoord1: TEXCOORD1,
  in uniform sampler2D tex_0,
  out float4 o_color : COLOR)
{
  o_color = tex2D(tex_0, l_texcoord1);
}
<CoordinateSystem> { Z-up }

<Texture> tex1 {
  "maps/envir-reeds.png"
}

<Group> triangle {
  <VertexPool> vp {
    <Vertex> 0 {
      0 0 0
      <UV>  { 0 0 }
      <UV> 2nd { 1 0 }
    }
    <Vertex> 1 {
      1 0 1
      <UV>  { 1 1 }
      <UV> 2nd { 0 1 }
    }
    <Vertex> 2 {
      0 0 1
      <UV>  { 0 1 }
      <UV> 2nd { 0 0 }
    }
  }
  <Polygon> {
    <TRef> { tex1 }
    <VertexRef> { 0 1 2 <Ref> { vp } }
  }
}

Press ENTER to use the 2nd UV by the shader, and DEL to use the default one.

Ah, thank you.
I had tried creating a texture stage but did not know about the sort value. I’ll give that a try.