• 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
1
Question by jonnyhopper · Oct 23, 2013 at 08:29 PM · surface shadervertex shader

Modifying vertex position in a surface shader

Hi! So I have this vertex shader in my surface shader:

         void myvert( inout appdata_full v) 
         {
             float4 vv = mul( _Object2World, v.vertex );
             vv.xyz -=  _WorldSpaceCameraPos.xyz;
              v.vertex.y -= vv.z * vv.z * 0.005f;
         }

Which is a fairly standard "cylindrical roll off" type vertex modification (a la animal crossing) where the camera is pointing along the z access

  • Get world vertex

  • Get the distance along the z access from the camera

  • do a quadratic roll off according to distance

This works fine, generally. Problem is, there's some obvious "sliding" when the z- rotation in the object's world matrix is non-zero.

Anyone got any ideas how to solve this (doing the same thing in object space, perhaps? Unsure how to do that)

Many thanks, Jonny.

EDIT: I figured it out! It's simply transforming the offset back into the object's local space, like so:

 v.vertex += mul( _World2Object, float4( 0.0f, vv.z * vv.z * -0.005f, 0.0f, 0.0f ) );
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
3

Answer by jonnyhopper · Oct 25, 2013 at 11:03 AM

Thought it might be worth writing this up properly as it may be useful to others. The problem is not necessarily obvious, even though the solution is.

Problem: Writing a custom vertex shader for a surface shader does not allow you to output a world space vertex. This is presumably because Unity is going to do a bunch of other local space processing before transforming it into world space afterwards.

Problems then arise when you have scales or rotations on your local vertex, which is pretty much always.

Solution: Simply transform the vertex into world space, do your world space processing and then transform back into local space.

 void SurfaceShaderVertexTransform( inout appdata_full v) 
 {
      // transform into worlspace
      float4 world_space_vertex = mul( _Object2World, v.vertex );

      /* Do some cool things here */

      // transform back into local space
      v.vertex = mul( _World2Object, world_space_vertex )
 }
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 tanoshimi · Oct 25, 2013 at 01:21 PM 0
Share

I asked a similar question a few weeks back about perfor$$anonymous$$g vertex manipulation of a surface shader in eyespace. Unfortunately, I still don't think that's possible because, unlike _Object2World/_World2Object, I don't think there's an equivalent inverse operation to go from eyespace back to model space.

As for the reason why vertices must remain in model space - I agree with your explanation: essentially the vertex modifier is a kind of preprocessor whose output is fed into the true vertex shader generated from the surface shader code. So the vertex information must be output from it in model coordinates exactly as it would have been if supplied directly from Unity.

avatar image jonnyhopper · Oct 25, 2013 at 01:28 PM 1
Share

Hmm I have a thought - posted on your original question

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

16 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

Related Questions

Access GameObject position and model position in surface shader? 0 Answers

Issue with the merging of a surface shader and vert/frag shader using UNITY_MATRIX_MVP 0 Answers

Surface Shader vertex displacement, shadows not moving 1 Answer

Surface shader + Instancing -> Invalid subscript 'texcoord' in generated code 1 Answer

How to convert surface shader to Vertex/Fragment code? 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