Vertex Transform and UV with Render Pick

In TD088/TD099, I’m having some difficulty getting correct UVs in the callback of the Render Pick DAT. I have a vertex shader that shrinks rectangles whose primitive center are outside of the center of the screen. Shrinking is like giving them a scale factor that’s less than 1, which I’ve done in the shader code.

worldSpaceVert.xyz = mix(primCenter, worldSpaceVert.xyz, scale);

When scale is 0, the rectangle will be size zero because all four corners will end up at center.xy. When scale is 1, the rectangle is unchanged, and so on.

When I hard-code scale=0.2, scale=0.5, scale=1. etc, the render pick works well. I can click inside any region of any SOP, and the UV that is printed to the textport is correct.

However, if I allow the scale to be dynamic, based on screen space, the UVs are bad. If I click the upper-left corner of a larger rectangle, the render pick misses it. If I click the upper-middle edge of a smaller rectangle, the V-value is mysteriously low, (0.5,0.75) when I expect something like (0.5,0.99). If I click just outside of the upper-middle edge of a smaller rectangle, I get a UV of (0.5,0.84) even though I expect the render pick to not detect it.

I’m doing this in the vertex shader, but I’m not sure how much effect it has:

TDWritePickingValues(); vTDPickVert.worldSpacePosition = worldSpaceVert.xyz; vTDPickVert.sopSpacePosition = mix(primCenter, P, scale); vTDPickVert.camSpacePosition = camSpaceVert.xyz;
The sopSpacePosition line is a little questionable, but 1) it’s not UV-related, and 2) it works as long as scale is a constant value.

And even if you can’t help me fix the UV issue, I hope you can get some use out of the vertex shader idea. :wink:

Update:
I’m surprised that something like this doesn’t ruin the uv-picking.

[code]// early on
scale = 1.;

// much later
TDWritePickingValues();

worldSpaceVert.xyz += vec3(1000.);
camSpaceVert = uTDMat.cam * worldSpaceVert;
vTDPickVert.worldSpacePosition = worldSpaceVert.xyz;
vTDPickVert.sopSpacePosition = mix(primCenter, P, scale) + vec3(1000.);
vTDPickVert.camSpacePosition = camSpaceVert.xyz;
vTDPickVert.uv[0] = uv[0];[/code]

If render picking relies on a separate hidden buffer, shouldn’t that huge offset of vec3(1000.) ruin the placement of the SOPs in this buffer?

Update:
Side note that the docs are a little confusing because this suggested line won’t work

vTDPickVert.worldSpacePosition = uTDMats.world * vec4(newPosition, 1.0);

vTDPickVert.worldSpacePosition is a vec3 not a vec4.
render_pick_vTDPickVert.2.toe (7.05 KB)

I tried doing this idea from scratch again and made the project easier to explore. There’s a switch DAT “switch1” that changes the mode of how rectangles get locally scaled. These are the modes (zero-indexed for discussion):
0) small in center

  1. larger in center
  2. shrinking left to right
  3. growing left to right

While watching the textport and clicking around project1, I noticed something between modes 2 and 3. When in mode 2, the farthest right rectangle responds to clicks in its upper right region but not its upper left region. In mode 3, the farthest left rectangle responds to clicks in its upper left region but not its upper right region. These are coincidentally symmetrical problems, and I’m not sure why it turned out that way. Anyway, the general problem is still that the UVs from the render pick seem incorrect.
render_pick_issue.1.toe (7.45 KB)

I’ve noticed that if you make a typo in this section

#else // TD_PICKING_ACTIVE // put typo here some_typo #endif // TD_PICKING_ACTIVE
it doesn’t report the error in the info DAT for the shader. This is unhelpful, especially because the docs [url]https://docs.derivative.ca/Write_a_GLSL_Material[/url] have this incorrect line:

vTDPickVert.worldSpacePosition = uTDMats.world * vec4(newPosition, 1.0);

It should be more similar to

vTDPickVert.worldSpacePosition.xyz = worldSpacePos.xyz;

Aside from that, I’m still having trouble getting vertex transformations and render picking to work at the same time. Can anyone give advice? I have an ortho camera and a shader that keeps the width of a rectangle constant in screen space, but the render pick isn’t finding it.

Here’s the outline of the shader

[code]
// make vec4 worldSpacePos based on ortho camera…

// write to gl_Position
gl_Position = TDWorldToProj(worldSpacePos);

#else // TD_PICKING_ACTIVE
TDWritePickingValues();
vTDPickVert.worldSpacePosition.xyz = worldSpacePos.xyz;
#endif // TD_PICKING_ACTIVE[/code]

Windows TD 42310
renderpick_bug.2.toe (6.61 KB)

The issue here is that picking is done by applying another step to the projection to zoom in on on where the cursor is happening, so only the area we are interested in picking is rendered. So the fact you are using the projection matrix to position your vertices is why things are breaking down.

Let me think about a solution. I think I could potentially leave the proj matrix in uTDMats as it was originally, and use the special pick projection internally in TDWorldToProj only

Cool thanks. That explains the mystery of how the render pick actually works! It’s like the object picker VR example in the palette.

Ok, in the next build of 40000 we post this will work correctly.
Thanks for the report!