Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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
1
Question by DavidWilliams · Apr 28, 2013 at 08:03 AM · lightingshadersnormalstangents

I'm computing my surface normals in the fragment program - so why does Unity still require per-vertex normals/tangents?

Hi all,

In computer graphics there exist techniques for computing a surface normal in the fragment shader, without needing per-vertex information. This is done by using ddx/ddy of the fragments world space to find two vectors which lie on the triangle's surface, and then taking the cross product to find the normal. That is, you can achive a flat-shaded lighting effect even if your vertices only contain positions.

I have implemented this in Unity with the following simple surface shader:

 Shader "FlatShadedMesh"
 {
   SubShader
   {
     Tags { "RenderType" = "Opaque" }
     CGPROGRAM
     #pragma surface surf Lambert
     #pragma target 3.0
     #pragma only_renderers d3d9
       
     struct Input
     {
       float4 color : COLOR;
       float3 worldPos;
     };
       
     void surf (Input IN, inout SurfaceOutput o)
     {
       // Compute the surface normal in the fragment shader.
       float3 surfaceNormal = normalize(cross(ddx(IN.worldPos.xyz), ddy(IN.worldPos.xyz)));
         
       o.Albedo = IN.color;
       o.Normal = surfaceNormal;
     }
     ENDCG
   }
   Fallback "Diffuse"
 }

I then generate a mesh using the following snippet of code:

 Mesh mesh = new Mesh();
 mesh.name = "testMesh";
 
 mesh.Clear();        
         
 Vector3[] vertices = new Vector3[resultVertLength / 4];
 Vector3[] normals = new Vector3[resultVertLength / 4];
 Vector4[] tangents = new Vector4[resultVertLength / 4];
 for(int ct = 0; ct < resultVertLength / 4; ct++)
 {
     vertices[ct] = new Vector3(resultVertices[ct * 4 + 0], resultVertices[ct * 4 + 1], resultVertices[ct * 4 + 2]);
 
     normals[ct] = new Vector3(0.0f, 0.0f, 1.0f); // <-- Dummy normals required by Unity
     tangents[ct] = new Vector4(1.0f, 0.0f, 0.0f, 1.0f); //<-- Dummy tangents required by Unity
 
 }
 mesh.vertices = vertices; 
 mesh.normals = normals; // What a waste!
 mesh.tangents = tangents; // What a waste!
 mesh.triangles = resultIndices;

Note that I am providing dummy normals and tangents. These properties are the same for every vertex, are basically meaningless, and are never used by my surface shader. But if I don't include these dummy properties then Unity complains:

Shader wants tangents but the mesh testMesh doesn't have them

Shader wants normals, but the mesh testMesh doesn't have them

So what must I do so that Unity will let me remove these properties? They are basically tripling the size of my vertex data. My best guess is that Unity wants them to do lighting calculation in tangent space. Can I make it do lighting in world space instead? Any other thoughts on how I can eliminate this unused data?

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 whydoidoit · Apr 28, 2013 at 08:06 AM

You need to write a vertex/fragment shader - surface shaders have a lot of pre-written code that gets included that need inputs based on the script you actually write.

Comment
Add comment · Show 6 · 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 DavidWilliams · Apr 28, 2013 at 08:14 AM 0
Share

Thanks, I half suspected this. But how is it possible to access Unity's light information (position, colour, etc) from a vertex/fragment program? I read http://docs.unity3d.ru/Components/SL-Attenuation.html but I believe it only works with Unity 2 (which is old). At least I tried it, and Unity commented out my shader and explicitly told me to use surface shaders ins$$anonymous$$d. $$anonymous$$aybe I should try again and then post a new question for this...

avatar image whydoidoit · Apr 28, 2013 at 08:17 AM 0
Share

With Lighting On in the pass:

unity_LightPosition[n] and unity_LightColor[n]

avatar image whydoidoit · Apr 28, 2013 at 08:17 AM 0
Share

Ordered by most impactful to least...

avatar image DavidWilliams · Apr 28, 2013 at 11:00 AM 0
Share

Great, thank you. It seems rather hard to find official documentation for this, I feel that unity_LightPosition[n] should be listed on http://docs.unity3d.com/Documentation/Components/SL-BuiltinValues.html for example (actually I found '_ObjectSpaceLightPos' so maybe I'll use that). However, now that I know what to search for I found a some nice information on the Wiki here: http://en.wikibooks.org/wiki/Cg_Program$$anonymous$$g/Unity/Diffuse_Reflection

Hopefully that tells me everything I need to know - thanks again for you help!

avatar image whydoidoit · Apr 28, 2013 at 11:03 AM 0
Share

Best thing I found was to read the UnitCG.inc stuff and see how they do it :)

If you feel this has helped, can you tick the answer?

Show more comments

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.

Follow this Question

Answers Answers and Comments

13 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

Related Questions

How to write unlit surface shader? 6 Answers

Can I retrieve per face normals instead of per vertex normals in vertex shader? 1 Answer

Reflections not seamless 1 Answer

Mirroring Entire Scene 0 Answers

Is vertices.normals face- or vertex-normals? 1 Answer


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