Search Unity

Handle Uniform Non-Uniform scale in a shader?

Discussion in 'Shaders' started by Cameron_SM, Dec 15, 2011.

  1. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    I have a shader that's not actually using the vertices for anything (except as a means to define where to draw) but I still want to be able to access the object scale values in an ubiquitous way for uv scaling in the fragment shader.

    I can get uniform scale from unity_Scale.w which works fine when my object is uniformly scaled but is there any way to know what the individual xyz component scale of an object/model-transform is if it's been non-uniformly scaled?

    That is, without analysing vertex positions.

    I thought perhaps unity_Scale.xyz would work, but they always seem to be 0 regardless of unscaled/uniform/nonuniform. Why even use a float4 for unity_Scale if only w is used???.

    :confused:

    I also tried using the _World2Object matrix x/y/z component magnitude but they too all seem to be unit length regardless of uniform/non-uniform scale.

    :rolleyes:

    I know I could pass in data via the mesh to get this but I need it to be dynamic and don't want to have to attach scripts that update mesh arrays every frame.
     
    Last edited: Dec 15, 2011
  2. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    That is only true if your meshes are batched.
     
  3. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    Arr I see, did some tests and you're right, _World2Object x/y/z axis vectors do scale, but again only if the object scale is uniform. Got my hopes up for a moment there but I do appreciate the info, probably would have lost most of a day down the road thinking W2O was always unit length so thanks.

    I guess there's no simple method to tell what scale an object is inside a shader if it's been non-uniform scaled.
     
  4. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    I guess the length of the 3D vector (_Object2World[0][0], _Object2World[1][0], _Object2World[2][0]) would give you the scaling of the x axis. Similarly (_Object2World[0][1], _Object2World[1][1], _Object2World[2][1]) for the y axis etc.

    Please let me know whether this works.
     
    INeatFreak likes this.
  5. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Currently if you're using non-uniform scale, Unity will scale the mesh on the CPU, and the shaders will already receive only pre-scaled vertex positions, normals etc. So in the shaders, everything that can happen is no scale at all or uniform scale.

    Why do we do this, is a long story. It's not very clever to do these days and we plan to eventually get rid of that. But for now, it's like that.
     
    twobob likes this.
  6. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    Arr, that explains a lot, thanks.
     
  7. Matthew Scott

    Matthew Scott

    Joined:
    Jan 16, 2013
    Posts:
    33
    Hmm, my meshes are using a scale of 1, 1, 1 and I'm still having a battle with this matrix MVP. After reading here I changed the way a lot of my meshes for my particle system are created but I'm still having difficulties, which I'm assuming are related to what Jessy is saying about batching.

    If anyone cares to take a quick look and offer some advice that would be a real big help.

    http://forum.unity3d.com/threads/21...sue-amp-Matrix-MVP-Woes?p=1446312#post1446312
     
  8. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    Any updates on when this might be changed?
     
  9. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    bump, is this still true?
     
  10. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    We're fixing this in Unity 5.0. In there, mesh scaling is never done on the CPU. All the vertex shaders are expected to normalize normals & tangents after transforming them into whatever space they need for lighting.
     
    Jessy, wuhao1117, JesOb and 1 other person like this.
  11. alebasco

    alebasco

    Joined:
    Apr 26, 2014
    Posts:
    5
    Hey Aras, thanks for that info. I noticed that the unity_Scale is now auto corrected out, as it is obsolete?

    Is there any replacement? (I'm using b17, will be upgrading to b18 soon)

    The overarching goal is to get a value that is the difference in position between that portion I am coloring now, and the origin of the model, so that I can apply a gradient effect on them from the top down, which works, but if the origin is at center, it does not.
     
  12. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    You can calculate scale(s) from the _Object2World matrix.
     
  13. battou

    battou

    Joined:
    Jan 25, 2011
    Posts:
    222
    Can you please tell how to calculate scale from _Object2World matrix?
     
  14. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
    vertex and normals come in already scaled, but tangents do not?
     
  15. RandomOutput

    RandomOutput

    Joined:
    Mar 11, 2015
    Posts:
    2
    There is probably a more efficient way to run this operation but this should give you the X,Y,Z scales applied to the object.
    Code (csharp):
    1. float4 modelX = float4(1.0, 0.0, 0.0, 0.0);
    2. float4 modelY = float4(0.0, 1.0, 0.0, 0.0);
    3. float4 modelZ = float4(0.0, 0.0, 1.0, 0.0);
    4.  
    5. float4 modelXInWorld = mul(_Object2World, modelX);
    6. float4 modelYInWorld = mul(_Object2World, modelY);
    7. float4 modelZInWorld = mul(_Object2World, modelZ);
    8.  
    9. float scaleX = length(modelXInWorld);
    10. float scaleY = length(modelYInWorld);
    11. float scaleZ = length(modelZInWorld);
     
    Crashhelmet and LiterallyJeff like this.
  16. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    this is long long old thread.....i use 4.6.7 f1, v.normal still not correct when non uniform scale...so sad...
     
  17. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    hi aubergine,u sure v.normal is correct?I use 4.6.7f1,see it not ...
     
  18. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    any ? I test non_uniform scale in unity5.1.2f1,when scale.y=3 ,batching the mesh,then v.normal look not correct,still not fixed this??
     

    Attached Files:

    • bug.jpg
      bug.jpg
      File size:
      605.8 KB
      Views:
      1,274
    Last edited: Jul 31, 2015
  19. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    it seems both them not work when batching.
     
  20. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    Hi Aras,how about non uniform scale batching in unity 5,it seem s not work.
     
  21. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    how about this ?
     
    Fattie likes this.
  22. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    up
     
    Fattie likes this.
  23. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    this is very hard to fixed?I do not think so...Only calculate changed vertex in cpu then upload to vertex buffer for gpu,this is very hard?????Why unity team maybe exist bout 10 years,still not fixed this very very base function ??SO disappoint about unity team:oops:
     
    Fattie likes this.
  24. NinjaISV

    NinjaISV

    Joined:
    Dec 29, 2014
    Posts:
    124
    This is very annoying...
     
    Fattie likes this.
  25. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    cause you not need to acheive the best performanceo_O
     
  26. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    Can you guys please make UNITY_MATRIX_T_MV scale at the same rate as a normal gameobject, or another keyword that does this. Currently the scaling appears to be squared. This keyword makes it SOOOO easy to make great billboards but the only issue is that it doesnt scale right.
     
    Fattie likes this.
  27. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    476
    hi @Aras or anyone at Unity,

    Years and years have gone by,

    it is totally undocumented so could you please update on this?

    Simple example, here's a shader which has absolutely no textures.

    It just draws a brown square:



    It simply gets the local position like this
    the quad has been scaled,

    you can see that if we knew the scaling (or even just the ratio)

    it would be very easy to draw "square squares"



    How do we get this simple info in the shader ??
     
  28. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    This was already answered in this thread 3 years ago.
    https://forum.unity.com/threads/handle-uniform-non-uniform-scale-in-a-shader.115675/#post-2113659

    The only thing that's changed is the name of the local to world matrix, but using the code as is and Unity will fix the name for you from _Object2World to unity_ObjectToWorld.

    If your mesh is batched (dynamically or staticly) then the mesh is pre transformed on the CPU and the matrix will have no scale information. You'll need to disable batching either in the project settings or in this shader specifically.

    Tags { "DisableBatching"="True" }
    https://docs.unity3d.com/Manual/SL-SubShaderTags.html
     
  29. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    NO,We need Batching to decrease the drawcall at the same time
     
  30. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You can have per mesh information about scale, or you can have batching, not both.