+4
Completed

Vertex local position

Jason Booth 10 years ago updated by Matt Weaver 7 years ago 16
Hi - I really need to get the vertex's local position in the pixel shader. (v.vertex, basically). I'm doing a form of trilinear texturing, but without the local vertex position the texture will not move/rotate correctly with the object. I can fix the movement with (worldPos-objPos), of course, but this won't handle rotation.

I've hacked this into the shader - but i have to repeat the hack every time I edit it in shader forge, or course..



Answer

-1
Answer
Completed

Yep, glad it worked out!

Under review
Can you not use the transform node to transform it to the correct space? That one should handle rotation properly
Nope - when I do that it it still acts as if it's in world space.  

Even if that did work, it wouldn't be sufficient, in that it would be using the world space of the vertex after vertex offset. Having the original, local vertex position allows you to work with things in the original model space, free from scale, position, rotation, and vertex offsets, without trying to undo all of those transformations in the shader.

 
Hey Joachim,
  Is this something you can likely put in over the next few weeks? If not, I'm going to have to turn a few massive shaders I'm working on into regular code - which I can do - but it would be a drag. Thanks!
Ok, I've converted over to hand written shaders for this. I actually needed to send over some additional data in a TEXCOORD from the vertex shader, so simply having the original model-space vertex position wouldn't have been enough to fully solve the issues I was having. That said, I still want to be able to access this one day..


 
This would be useful for me too.  I also tried using the transform node to transform from world back to local and it didn't work as expected.  I'm using a triplanar shader to texture objects which move about the scene and the texture pans when they move about even if I try to use the transform node to undo the world transform.
+1
You should be able to subtract the object position from the world position, and then transform it using the transform node, I think
That won't handle rotations. You'd need to use a matrix to transform it correctly, but the whole idea of using anything for this is silly, since v.vertex simply needs to be passed as a texcoord to the pixel shader and no actual calculations are needed. Doing an extra matrix mul for every pixel is extremely wasteful for something that's already easily available in the vertex shader. I've pretty much gone back to writing shaders by hand because of these types of issues. 
Hi guys,  Actually it does.  If I subtract the position and use the transform from world to local it does what I want.  I also need to transform the normals though for the triplanar shader to work.  As Jason says though it is really wasteful in terms of processing but it will do fine for the time being.  Personally I never really think of tools like Shader Forge as a way to make a efficient shaders more as a way to do quick prototyping and experiments.  But it would be nice to have more raw data passed through from the vertex shader so I could write more efficient code in the tool.
It is silly, but it's also something that's hard to fix properly on my end, for several reasons.
I've mentioned it several times throughout UserEcho - the shader compiler and the non-existent dependency system, make all issues regarding vert/frag separation, and almost everything related to dependencies, a mess to fix.

I intend to do a full rewrite of Shader Forge's compiler, which make this a quick fix, rather than a mess, but it won't happen until after Unite 2014.

I'm sorry that it's causing you issues at the moment, but right now there's no easy way around it.
No worries Joachim, it'll all get fixed up eventually. 

Tony: I recently went through the same challenge with the normals. What I ended up doing was modifying the TBN in the vertex shader to account for it. I tried several other techniques first, but this seemed the most elegant and least instructions in the end (targeting sm2.0 for some of this). Here's the code, hope it helps:

// Sides that get sampled upside-down (-X, -Y, -Z) need to have their normal map's Y flipped.
// Positive sides end up with +1, while negatives end up with -1.

float lowest = min(min(v.normal.x, v.normal.y), v.normal.z);

// For top and bottom, the tangent points to the right. In all other cases it points straight down.
float3 tangent = float3(abs(v.normal.y), -max(abs(v.normal.x), abs(v.normal.z)), 0.0);
v.tangent = float4(normalize(tangent), floor(lowest) * 2.0 + 1.0);
o.normalDir = mul(half4(v.normal,0), _World2Object).xyz;
o.tangentDir = normalize( mul( _Object2World, half4( v.tangent.xyz, 0.0 ) ).xyz );
o.binormalDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
What I would like to do, is to have a manual mode in Shader Forge, where you have a split between the fragment shader and the vertex shader, allowing you to make things like this.

But, again, that would have to be after Unite, and after making a proper dependency system :)
The dependency system is so central to almost all new features people want, and without it, all new features would be like hardcoded hacks, potentially breaking more things in the process
+11
Are there any way of getting raw vertex's local position (v.vertex) available now?

I need to get the vertex position on local mesh coordinate to paint the object by a gradient proportional to the vertex height. Something like this:

I used the WorldPosition node, subtract by the ObjectPosition, then applied a Transform (from World to Local). Then extract the Y coordinate. It seems to work when I have only one object in the scene using the shader. It also works for rotations. When I move or rotate the object, the gradient keeps right, doesn't change. But then I create a second object using the same shader and the colors of both objects turned green and the gradient is gone. So I realized that when the other object is outside the camera view, the one inside the view displays the right gradient again. If I move the other back to view, both are green again.


Any help to make me understand what is happening would be great!

Thanx in advance.

Hi Thomas. I am learning SF and need a shader that does something similar to what you are talking about (spherical planet with procedural terrain heights). I programmed a system to generate the geometry but I am not great with shaders. Would it be possible to show me a screenshot of at least part of your SF node setup? I know this is an old thread but any help would be appreciated. Thanks!

I just realized that when I deactivate the "Draw call batching", the problem with more than one object is solved.

-1
Answer
Completed

Yep, glad it worked out!