• 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
Question by MachindoApps · Aug 01, 2013 at 02:58 PM · shaderterraincgpixel lightvertex-lit

Terrain custom shader not lit per pixel?

When applying a custom shader to a Terrain object, the terrain always appears to be vertex-lit, even though the shader is written to be per-pixel.

The original (textured) terrain:

alt text

Terrain with altitude band shader and one directional light at camera's position: alt text

This terrain has a pixel error setting of 4, as you can see, the quality is pretty poor with it 'vertex lit' like this.

Shader code is below. It looks like the normal values for the terrain are only coming out per-vertex, perhaps I am doing something wrong?

 Shader "Custom/AltitudeShader" {
 
     Properties {
         _BaseColour ("Diffuse Material Colour", Color) = (1, 1, 1, 1)
         _Colour1 ("Colour 1", Color) = (0, 1, 0, 1)
         _Colour2 ("Colour 2", Color) = (1, 1, 0, 1)
         _Colour3 ("Colour 3", Color) = (1, .5, 0, 1)
         _Colour4 ("Colour 4", Color) = (1, 0, 0, 1)
         
         _Limit1 ("Limit 1", float) = 2000.0
         _Limit2 ("Limit 2", float) = 2500.0
         _Limit3 ("Limit 3", float) = 3000.0
 
     }
         
     SubShader {
 
         Pass {
             Tags { "LightMode" = "ForwardBase" } 
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
 
             struct vertex_input {
                 float4 vertex : POSITION;
                 float3 normal : NORMAL;
             };
             
             struct vertex_output {
                 float4 pos : SV_POSITION;
                 float4 world_pos : TEXCOORD0;
                 float3 normal_dir : TEXCOORD1;
             };
             
             uniform float4 _LightColor0;
             float4 _BaseColour;
             float4 _Colour1;
             float4 _Colour2;
             float4 _Colour3;
             float4 _Colour4;
             float _Limit1;
             float _Limit2;
             float _Limit3;
             
             vertex_output vert(vertex_input i) {
                 vertex_output o;
                 o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
                 o.world_pos = mul(_Object2World, i.vertex);
                 o.normal_dir = i.normal;
                 o.normal_dir = normalize(float3(mul(float4(i.normal, 0.0), _World2Object)));
                 return o;
             }
             
             fixed4 frag(vertex_output i) : COLOR0 {
                 
                 //diffuse component
                 float3 normal_dir = normalize(i.normal_dir);
                 float3 view_dir = normalize(_WorldSpaceCameraPos - float3(i.world_pos));
                 float3 light_dir;
                 float attenuation;
                 
                 if(_WorldSpaceLightPos0.w == 0.0) {
                     //directional light
                     attenuation = 1.0;
                     light_dir = normalize(float3(_WorldSpaceLightPos0));
                 } else {
                     //point or spot light
                     float3 light_diff = float3(_WorldSpaceLightPos0 - i.world_pos);
                     float3 dist = length(light_diff);
                     attenuation = 1.0 / dist;
                     light_dir = normalize(light_diff);
                 }
                 
                 float3 ambient_light = float(UNITY_LIGHTMODEL_AMBIENT) * float3(_BaseColour);
                 
                 float3 diffuse_reflection = attenuation * _LightColor0.rgb * float3(_BaseColour) * max(0.0, dot(normal_dir, light_dir));
                 
                 //altitude bands
                 float4 alt_col;
                 if(i.world_pos.y < _Limit1) {
                     alt_col = _Colour1;
                 } else if(i.world_pos.y < _Limit2) {
                     alt_col = _Colour2;
                 } else if(i.world_pos.y < _Limit3) {
                     alt_col = _Colour3;
                 } else {
                     alt_col = _Colour4;
                 }
                 alt_col *= (float4(diffuse_reflection, 1.0) * _BaseColour);
                 return alt_col;
             }
             
             ENDCG
         }
     
     }    
 }

Has anyone else come across this? Is it something inherent in shading Terrain objects, or is there a problem with my shader code? Any help greatly appreciated. Thanks!

Comment

People who like this

0 Show 3
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 Xtro · Aug 01, 2013 at 04:27 PM 0
Share

What is your render path ?

avatar image MachindoApps · Aug 01, 2013 at 04:29 PM 0
Share

Render path is set to 'Forward'

avatar image MachindoApps · Aug 01, 2013 at 04:37 PM 0
Share

Additionally, the view light has its Render Mode set to Important, which should force it to be pixel-lit when using the Forward render path.

1 Reply

· Add your reply
  • Sort: 
avatar image

Answer by Xtro · Aug 01, 2013 at 04:36 PM

I suggest you to try it on deferred render mode. I'm not a shader expert but I solved my shader problems by switching to the deferred render mode. I know it's not supported on mobile platforms (if this is the case for you) but in Unity4.2 they started to support mobile platforms for deferred mode.

Comment

People who like this

0 Show 4 · 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 MachindoApps · Aug 01, 2013 at 04:45 PM 0
Share

Thanks, yes I'm targeting iOS and Android as well as desktop, so will need support. I'm still on 4.1.5 - will install 4.2 and give that a try, thanks.

avatar image Xtro · Aug 01, 2013 at 04:58 PM 0
Share

If you get the correct behavior on deferred mode(On desktop player), I suggest you to stick with it. On mobile, it's decreased to forward automatically if the device doesn't support it. Yes, the terrain may look bad on mobile but there is a good reason for it. The mobile doesn't support it. I hope your terrain doesn't look awful on mobile :(

avatar image Xtro · Aug 08, 2013 at 07:26 PM 0
Share

Did you try it?

avatar image MachindoApps · Aug 28, 2013 at 09:20 AM 0
Share

Yes, tried it, and it made no difference on desktop or mobile. Still looking for a solution to this.

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

15 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

Related Questions

CG diffuse shader 1 Answer

Making Parts of the Terrain invisible, depending on y coordinate f the vertex 1 Answer

Unity Terrain - shader for custom post-splat? 0 Answers

Blended texture Shader 1 Answer

How to force the compilation of a shader in Unity? 5 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