• 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 Nodrap · Jun 28, 2016 at 08:55 AM · shader programming

Shader global values not acting globally

I created my first vertex shader recently, based on the standard mobile diffuse shader. It has parameters that allow the scene to be curved into the distance and are set up as uniform variables. It all seems to work really well but I get some odd objects that just seem to refuse to deform even though they have the right shader. Also they sometime flicker between the correctly warped position and their original position.

I use Shader.SetGlobalFloat("curveScale", value); to set the global value and so I would expect all objects with this shader would warp. Here's the shader in case its related to it:

 Shader "Custom/Diffuse Coloured - Curved" {
     Properties {
         _MainTex ("Base (RGB)", 2D) = "white" {}
         _Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
     }
  
 SubShader {
     Tags { "RenderType"="Opaque" }
     LOD 150
  
 CGPROGRAM
 #pragma surface surf Lambert vertex:vert
  
 sampler2D _MainTex;
     uniform float4 _Color;
     uniform half curveStart;
     uniform half curveRate;
     uniform half curveScale;
  
 struct Input {
     float2 uv_MainTex;
 };
  
 half4 Bend(half4 v)
 {
     half depth = v.z-curveStart;
  
     if (depth<0)
     {
         return v;    // Unchanged
     }
  
     half4 val = v;
     val.x = val.x + ( (1 - cos(depth*curveRate)) * curveScale);
  
     return val;
 }
  
  
 void vert (inout appdata_full v)
 {
     half4 vPos = Bend(v.vertex);
  
     v.vertex = vPos;
 }
  
 void surf (Input IN, inout SurfaceOutput o) {
     fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
     o.Albedo = c.rgb * _Color;
     o.Alpha = c.a;
 }
 ENDCG
 }
  
 Fallback "Mobile/VertexLit"
 }


In trying to track down the cause I set up a testbed which creates cubes from a prefab and then setting their color either by setting the sharedMaterial or material. When they are set by material the warping stops working. Now I know it would duplicate the material at this point but the setting of a global float should still apply to all uses of that shader, shouldn't it?

alt text Here the mixed coloured cubes are fixed but the common shared ones bend. All use the same shader and global values. As someone new to shaders I fear I'm missing something important!

testdeformshader.png (62.8 kB)
Comment
Add comment
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

1 Reply

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

Answer by Eno-Khaon · Jun 28, 2016 at 09:07 AM

In your shader, try adding this to your tags:

 "DisableBatching" = "True"

For example, this would give you:

 Tags { "RenderType"="Opaque" "DisableBatching" = "True" }

I'm guessing that your cubes are dynamically batching which, in this case, is causing their origin point to move to global (0, 0, 0). Under most circumstances, the batching is a good thing. It can drastically reduce draw calls in your scene. However, it doesn't often play well with vertex modification in shaders.

Edit: At the very least, if you see a change as a result of this, then it may be a potential lead. The more I think about the problem, the less logical and straightforward the problem seems to be.

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 Nodrap · Jun 28, 2016 at 05:45 PM 0
Share

Tried that and the bending stopped happening completely. Oddly the original problem changed the next day (go figure) and all the objects started to curve about their own origins (I think). But the day before they weren't, it was around world coordinates! Go figure. I can only guess that some kind of caching might have occurred whilst I was modifying the shader. But anyway, I used a

half4 wPos = mul (_Object2World, v);

To convert it to world coords and now the random flickering and some materials not bending has all gone. I'm guessing it was a Unity compiling shader related problem as today its all different. Very worrying!

I'll share my little test project as I'd still like to know why they stop bending. Small UnityPackage

avatar image Eno-Khaon Nodrap · Jun 28, 2016 at 06:36 PM 0
Share

Thank you very much for the sample project -- it let me confirm my suspicions.

YES! The problem does, in fact, lie in the dynamic batching, which is disabled automatically when the cubes have their own instance of a material.

The thing is, all your cubes really are moving. They're just moving a really, really tiny amount.

If you zoom in right next to a selected (non-batched) cube, you'll be able to notice that it shifts slightly outside its original boundaries. By contrast, when the cubes are batched together, they stretch relative to their distance from the center. The cubes are appearing between 10 and 29 on the Z-axis, which results in them beco$$anonymous$$g more skewed the further from 0 they are. Additionally, as unit cubes, this also means that the ones appearing at the 10 mark are shifting 20 times further than non-batched cubes are.

Edit: As for why this shift changes when batched, your shader is modifying position in object/local space based on a potentially ambiguous value:

 half depth = v.z-curveStart;

$$anonymous$$ultiplying the vertex position by _Object2World will move the center point to (0, 0, 0), the same as is effectively applied by the batching.

As an additional note, the reason why the problem also seemed a bit inconsistent is due to the way the dynamic batching is calculated. Sometimes, objects will be batched after they already existed in the scene and sometimes they may no longer be batched later on.

avatar image Nodrap Eno-Khaon · Jun 29, 2016 at 08:18 AM 0
Share

Yes, this all makes sense now! So the batching effectively changes the "origin" of the object when it comes into the shader, and the way it batches explains the randomness. Great stuff. Incidentally I tried the original test with the modified shader, that adjusts the input into world space, and now all cubes move as we would expect. :)

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

44 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Need help with using world position in shader 1 Answer

Generate mesh from shader for Skybox (withouth the MeshRender workaround) 0 Answers

Shader graph equivelent of Unreal's StaticBool? 2 Answers

Making a rather simple shader.shader 0 Answers

Why doesn't my new shader property show up in the inspector? 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