• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by devluz · Oct 28, 2014 at 10:40 AM · shader programmingvertex

getting the local vertex positions in vertex shader

Is it possible that the vertex position given in the struct appdata_base are already the transformed? I need to get the local positions of my vertices in the vertex shader but after 30 min of confusion and testing I noticed that the vertex position are already in the world space and all the matrices are changed to compensate this. e.g. _Object2World seems to be a normal identity matrix. I can't find any documentation about this.

How do I get the actual local vertex positions and the real world/model matrix? Is there any documentation?

Example shader:

 Shader "own/markercell"
 {
     Properties 
     {
         _MaskTex ("_MaskTex", 2D) = "white" {}
         _MainColor ("_MainColor", Color) = (1,1,1,1)
         _NeighbourPos("_NeighbourPos", Vector) = (1,1,1,1)
 
     }
     SubShader
     {
         Lighting Off 
         Fog { Mode Off }
         ZWrite Off
         Blend SrcAlpha OneMinusSrcAlpha      
 
 
         Tags { "Queue"="Transparent" "RenderType"="Transparent" }
         Pass
         {
             CGPROGRAM
 
             #pragma vertex vert
             #pragma fragment frag
 
             #include "UnityCG.cginc"
             
             sampler2D _MaskTex;
             uniform fixed4 _MainColor;
             uniform float _Scale;
             uniform float4 _NeighbourPos;
 
             struct vertOut 
             {
                 float4 pos : SV_POSITION;
                 float2 tex : TEXCOORD0;
                 float3 lpos : TEXCOORD2;
             };
             
 
             vertOut vert(appdata_full input)
             {
                 vertOut output;
 
                 
                 fixed4 pos = input.vertex; 
 
                 output.lpos = input.vertex;
                 output.pos = mul (UNITY_MATRIX_MVP, pos);
                 output.tex = input.texcoord;
                 return output;
             }
 
             fixed4 frag(vertOut input) : COLOR0
             {
                 fixed4 output = fixed4(0,0,0,0);
                 output.a = 1;
                 output.rgb = input.lpos;
 
                 return output;
             }
 
             ENDCG
         }
     }
 }

The shader should simply show the local position as color but it shows the world position.

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image devluz · Oct 28, 2014 at 07:30 PM 0
Share

getting more and more the feeling this could be a bug in unity. If I change the scale of the object it works ... sometimes.

avatar image tanoshimi · Oct 28, 2014 at 07:42 PM 0
Share

Using this shader on a default cube primitive, I get local shading exactly as I would expect.

I admit I do get some slightly odd effects if I change to use non-uniform scaling of that cube - it doesn't become worldspace, but the lighting seems to go awry. Left pic has scale of 2,2,2 - Right pic shows effect of changing scale slightly to 2,2.001,2 alt text. Don't know if this is related or not though.

untitled.jpg (136.2 kB)
avatar image devluz · Oct 28, 2014 at 08:14 PM 0
Share

Thanks for testing. Can you move the object? if it is at 0,0,0 the world position and local positions are similar. It looks to me like the same thing is happening. The scale is applied to all vertices before the vertex shader thus the colors become brighter because the values are higher.

For me it changes if I change the camera positions, scale and so on. Sometimes I get local and sometimes global vertex positions and with _Object2World being an identity matrix sometimes I can't get the world position of the object without adding a new uniform ...

the left object works properly in my screenshot all others are broken. If I rotate the camera they flicker and work sometimes and sometimes not.

alt text

bugview.jpg (52.5 kB)
avatar image tanoshimi · Oct 28, 2014 at 10:05 PM 0
Share

I have a theory (though not a solution).... when you say that you move your camera around and sometimes they work, sometimes they don't. Would it by any chance work with local shading when there's only one object in view, but turns to "global" when there's two or more?

avatar image tanoshimi · Oct 28, 2014 at 10:08 PM 0
Share

Here's what I'm getting:

9 cubes all using the same shader = "global" vertex position. alt text

Disable the mesh renderer on (any) 8 of the cubes, and the remaining cube becomes "local" vertex position shaded. alt text

global.jpg (86.0 kB)
local.jpg (76.6 kB)

2 Replies

· Add your reply
  • Sort: 
avatar image
10
Best Answer

Answer by tanoshimi · Oct 28, 2014 at 10:18 PM

Ok, so if I'm right, it's actually a simpler solution than I first thought. Unity is using dynamic batching - combining your objects' meshes to reduce drawcalls, but because that happens before it's sent to the GPU (which is the whole point), the vertex information seen by the shader has been modified.

The solution is simply to disable dynamic batching in Edit -> Project Settings -> Player.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image devluz · Oct 28, 2014 at 11:45 PM 0
Share

great thanks! Works perfectly now. :) This should be better documented in unity. I was about to go crazy!

avatar image antiart · Sep 23, 2016 at 04:18 PM 2
Share

Now it's even easier to disable batching:

Add a tag to your subshader like

 SubShader {
     Tags{ "DisableBatching" = "true"}
     ...
 }

Did the trick for me.

avatar image tanoshimi antiart · Sep 23, 2016 at 04:26 PM 0
Share

Yes that's right - in Unity 5.x you can now simply disable batching per-material.

avatar image
0

Answer by Khuran91 · Feb 21, 2015 at 03:03 PM

I have a similar issue. I'm trying to write a shader that draws random white pixels on a solid black plane, using local coordinates of the plane to generate random values. This is what I've written:

 Shader "Custom/stars_shader"
 {
     SubShader
     {
         Pass 
         {
             CGPROGRAM
             #pragma fragment frag
             #pragma vertex vert
             #include "UnityCG.cginc"
             
             struct fragmentInput
               {
                   float4 m_position : TEXCOORD2;
                 float4 position : SV_POSITION;
               };
 
             fragmentInput vert(appdata_base i)
             {
                 fragmentInput o;
                 o.position = mul (UNITY_MATRIX_MVP, i.vertex);
                 o.m_position = i.vertex;
                 return o;
             }
               
               float rand(float3 co)
             {
                 return frac(sin(dot(co.xyz, float3(12.9898,78.233,45.5432))) * 43758.5453);
             }
 
             float4 frag(fragmentInput i) : COLOR
             {
                 float4 color;
                 if(rand(i.m_position.xyz) < 0.995f)
                     color = float4(0, 0, 0, 1);
                 else
                     color  = float4(1, 1, 1, 1);
                 return color;
             }
             
             ENDCG
         }
     } 
     FallBack "Diffuse"
 }

But the results are quite weird. As the plane and\or the camera move around, the white pixels change positions chaotically, which makes me think that the random values are re-generated for each movement. I have disabled dynamic batching, and the scene contains only the camera and the plane.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Khuran91 · Feb 21, 2015 at 03:22 PM 0
Share

Also, using texcoord0 ins$$anonymous$$d of local coordinates (as shown in the unity manual shader examples) i get the same result.

avatar image Khuran91 · Feb 21, 2015 at 05:59 PM 0
Share

and if I make the fragment program output the local coordinates directly as a color, it works correctly. I am really confused.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

How to mask textures by vertex color? 0 Answers

Surface Shader, run vertex multiple times 0 Answers

Need help with using world position in shader 1 Answer

Addition to Standard Shader stopping it from batching? 0 Answers

confusing compute shader results 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges