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
0
Question by highpockets · Oct 03, 2013 at 05:19 PM · shadershadersvertexcolorvertex-lighting

Changing the vertex color by script

Hi,

I'm having trouble trying to change the vertex color from my script ( I do not want to change the color via the material because I don't want to break batching ). I have a shader that I thought was correctly written to do what I'm trying to accomplish, but I must have an error in it somewhere. The script works, but the game objects that I'm trying to change the color of, remain the same color.

Here is my shader:

 Shader "My Shaders/Normal Maps/OptimizedNormal"
 {
  
     Properties
     {
  
        _Color( "ColorTint", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
        _BumpMap( "NormalTexture", 2D ) = "bump" {}
        _BumpDepth( "BumpDepth", Range( 0.0, 1.0 ) ) = 1
        _SpecColor( "SpecularColor", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
        _Shininess( "Shininess", float ) = 10
     }
  
     SubShader
     {
  
        Pass
        {
  
          Tags { "LightMode" = "ForwardBase" }
  
          CGPROGRAM
          #pragma vertex vert
          #pragma fragment frag
          #pragma fragmentoption ARB_precision_hint_fastest
  
          //user defined variables
          uniform fixed4 _Color;
          uniform sampler2D _BumpMap;
          uniform fixed _BumpDepth;
          uniform half4 _BumpMap_ST;
          uniform fixed4 _SpecColor;
          uniform half _Shininess;
  
          //unity defined variables
          uniform half4 _LightColor0;
  
          //base input structs
          struct vertexInput
          {
  
           half4 vertex : POSITION;
           half3 normal : NORMAL;
           half4 texcoord : TEXCOORD0;
           half4 tangent : TANGENT;
          };
  
          struct vertexOutput
          {
  
           half4 pos : SV_POSITION;
           half4 tex : TEXCOORD0;
           fixed4 lightDirection : TEXCOORD1;
           fixed3 viewDirection : TEXCOORD2;
           fixed3 normalWorld : TEXCOORD3;
           fixed3 tangentWorld : TEXCOORD4;
           fixed3 binormalWorld : TEXCOORD5;
          };
  
  
          //vertex function
          vertexOutput vert( vertexInput v )
          {
  
           vertexOutput o;
           o.normalWorld = normalize( mul( half4( v.normal, 0.0 ), _World2Object ).xyz );
           o.tangentWorld = normalize( mul( _Object2World, v.tangent ).xyz );
           o.binormalWorld = normalize( cross( o.normalWorld, o.tangentWorld ) * v.tangent.w );
  
           half4 posWorld = mul( _Object2World, v.vertex );
           o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
           o.tex = v.texcoord;
  
           o.viewDirection = normalize( _WorldSpaceCameraPos.xyz - posWorld.xyz );
  
           half3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
  
           o.lightDirection = fixed4( 
               normalize( lerp( _WorldSpaceLightPos0.xyz, fragmentToLightSource, _WorldSpaceLightPos0.w ) ),
               lerp( 1.0, 1.0/length( fragmentToLightSource ), _WorldSpaceLightPos0.w ) );
  
           return o;
          }
  
          //fragment function
          fixed4 frag( vertexOutput i ) : COLOR
          {
  
           //texture Maps
           fixed4 texN = tex2D( _BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw );
  
           //unPackNormal function
           fixed3 localCoords = fixed3( 2.0 * texN.ag - float2( 1.0, 1.0 ), _BumpDepth );
  
           //normal transpose matrix
           fixed3x3 local2WorldTranspose = fixed3x3(
               i.tangentWorld,
               i.binormalWorld,
               i.normalWorld
           );
  
           //calculate normal direction
           fixed3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
  
           //Lighting
           //dot product
           fixed nDotL = saturate( dot( normalDirection, i.lightDirection.xyz ) );
  
           fixed3 diffuseReflection = i.lightDirection.w * _LightColor0.xyz * nDotL;
           fixed3 specularReflection = diffuseReflection * _SpecColor.xyz * pow( saturate( dot( reflect( -i.lightDirection.xyz, normalDirection ), i.viewDirection ) ), _Shininess);
  
           fixed3 lightFinal = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuseReflection + ( specularReflection );
  
           return fixed4( lightFinal * _Color.rgb, 1.0 );
          }
  
          ENDCG
        }
     }
     //Fallback "Diffuse"
 }

I thought that declaring _Color as uniform allows me to change the default value of the verts from my C# script, but the objects remain white. This is the C# script that I wrote for changing the verts color:

  void Start ()
 {    
 GameObject[] gos;
         gos = GameObject.FindGameObjectsWithTag( "Container" );
         int colorNumber = 0;
         
         foreach( GameObject go in gos )
         {
         
             var mf = go.GetComponent<MeshFilter>();
             var colors = new Color[ mf.sharedMesh.vertexCount];
             
             if( colorNumber == 0 )
             {
                 
                 for(var i = 0; i < colors.Length; i++)
                 {
                     colors[i] = new Color( 1, 0, 0, 1 );
                 }
                 
                 mf.mesh.colors = colors;
                 colorNumber = 1;
                 continue;
             }
             
             if( colorNumber == 1 )
             {
                 
                 for(var i = 0; i < colors.Length; i++)
                 {
                     colors[i] = new Color( 0, 1, 0, 1 );
                 }
                 
                 mf.mesh.colors = colors;
                 colorNumber = 2;
                 continue;
             }
             
             if( colorNumber == 2 )
             {
                 
                 for(var i = 0; i < colors.Length; i++)
                 {
                     colors[i] = new Color( 0, 0, 1, 1 );    
                 }
                 
                 mf.mesh.colors = colors;
                 colorNumber = 3;
                 continue;
             }
             
             if( colorNumber == 3 )
             {
                 
                 for(var i = 0; i < colors.Length; i++)
                 {
                     colors[i] = new Color( 0.5f, 0.25f, 0, 1 );
                 }
                 
                 mf.mesh.colors = colors;
                 colorNumber = 4;
                 continue;
             }
             
             if( colorNumber == 4 )
             {
                 
                 for(var i = 0; i < colors.Length; i++)
                 {
                     colors[i] = new Color( 1f, 0, 0.2f, 1 );
                 }
                 
                 mf.mesh.colors = colors;
                 colorNumber = 0;
                 continue;
             }
         }
     }

        
             



Both the shader and C# scripts run without error, but like I said, the color of the game objects just remains as the default white that I set in the top of the shader.

Does anyone know where I'm going wrong? I have a feeling that I haven't got something right in the shader.

I do not want to change the color via the material as this will break batching and I want to keep these game objects in the same draw call.

Any help is much appreciated. Thanks

Comment
Add comment · Show 4
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 robertbu · Oct 03, 2013 at 05:28 PM 0
Share

While verbose, your code to change the vertex colors looks like it should do the job. Try this shader to see if the problem is a shader issue:

http://wiki.unity3d.com/index.php?title=VertexColor

avatar image highpockets · Oct 04, 2013 at 01:15 AM 0
Share

Thanks for the suggestion robertbu. I was able to change the color with that shader. I'm still having no luck with my own shader though. So, my C# script works fine and although my shader runs without errors, I'm not able to change the vertex color. So, I'm not including something in my shader.

Does anyone have an idea about what's happening?

avatar image robertbu · Oct 04, 2013 at 04:18 AM 0
Share

In order to use vertex colors, you need a Shader that implements vertex colors. Only a $$anonymous$$ority of shaders use vertex colors. There are other shaders that support vertex colors on the Wiki and elsewhere on the net. I don't know if there is on that supports the feature set you need.

avatar image highpockets · Oct 04, 2013 at 04:32 AM 0
Share

Cool, I'm certain that I have only missed a small thing within the shader, but I haven't nailed it down yet. I'm sure that I only need to modify it a tad and it will work. I have completely customized/optimized the shader for my desired feature set, but the only thing that isn't working is the vertex color input. I will continue researching and I will post my solution when I find it..... That is only if someone can't beat me to it and answer my question.

Anyways, I probably speak for a lot of people trying to figure out program$$anonymous$$g and asking questions on here by saying that I appreciate your help robertbu, you're a machine on unity answers!! I was wondering to myself if you ever get time to work on your own stuff!! You seem to answer questions 24/7 on here and you've helped me better understand a lot of things.. Big thanks!

2 Replies

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

Answer by whydoidoit · Oct 04, 2013 at 04:42 AM

The shader you posted does not read a vertex colour or pass a colour from the vertex to the fragment...

      struct vertexInput
      {
 
       half4 vertex : POSITION;
       half3 normal : NORMAL;
       half4 texcoord : TEXCOORD0;
       half4 tangent : TANGENT;
       half4 color : COLOR; //Add this
      };

      struct vertexOutput
      {
 
       half4 pos : SV_POSITION;
       half4 tex : TEXCOORD0;
       half4 color : TEXCOORD6; //Add this
       fixed4 lightDirection : TEXCOORD1;
       fixed3 viewDirection : TEXCOORD2;
       fixed3 normalWorld : TEXCOORD3;
       fixed3 tangentWorld : TEXCOORD4;
       fixed3 binormalWorld : TEXCOORD5;
      };

Then you need to assign the colour to the output in the Vertex shader:

       o.color = v.color;

And return it multiplied by your calculations in the Fragment shader:

      return fixed4( lightFinal * _Color.rgb * i.color.rgb, 1.0 );
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 highpockets · Oct 04, 2013 at 04:52 AM 0
Share

Hahaha, where were you like 30 $$anonymous$$utes ago?!! Thanks whydoidiot

avatar image whydoidoit · Oct 04, 2013 at 04:53 AM 0
Share

I was in bed :)

avatar image
1

Answer by highpockets · Oct 04, 2013 at 04:51 AM

OK, OK, after a bit of research I found my solution in the documentation:

http://unity3d.com/support/documentation/Components/SL-VertexProgramInputs.html

I was failed to pass the color input value in the structs ( vertexInput/vertexOutput ). I also realized that you have to declare it as color because I tried doing it through troubleshooting and just declaring it as "col". That is not accepted by unity. It needs to use the word "colour" with the semantic "COLOR" and no other in order for it to work.

Anyways, for those who are looking in the future. This is my final shader script:

 Shader "My Shaders/Normal Maps/OptimizedNormal"
 {
     
     Properties
     {
     
         _Color( "ColorTint", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
         _BumpMap( "NormalTexture", 2D ) = "bump" {}
         _BumpDepth( "BumpDepth", Range( 0.0, 1.0 ) ) = 1
         _SpecColor( "SpecularColor", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
         _Shininess( "Shininess", float ) = 10
     }
     
     SubShader
     {
         
         Pass
         {
         
             Tags { "LightMode" = "ForwardBase" }
             
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma fragmentoption ARB_precision_hint_fastest
             
             //user defined variables
             uniform fixed4 _Color;
             uniform sampler2D _BumpMap;
             uniform fixed _BumpDepth;
             uniform half4 _BumpMap_ST;
             uniform fixed4 _SpecColor;
             uniform half _Shininess;
             
             //unity defined variables
             uniform half4 _LightColor0;
             
             //base input structs
             struct vertexInput
             {
             
                 half4 vertex : POSITION;
                 half3 normal : NORMAL;
                 half4 texcoord : TEXCOORD0;
                 half4 tangent : TANGENT;
                 fixed4 color : COLOR;
             };
             
             struct vertexOutput
             {
             
                 half4 pos : SV_POSITION;
                 half4 tex : TEXCOORD0;
                 fixed4 lightDirection : TEXCOORD1;
                 fixed3 viewDirection : TEXCOORD2;
                 fixed3 normalWorld : TEXCOORD3;
                 fixed3 tangentWorld : TEXCOORD4;
                 fixed3 binormalWorld : TEXCOORD5;
                 fixed4 color : COLOR;
             };
             
             
             //vertex function
             vertexOutput vert( vertexInput v )
             {
             
                 vertexOutput o;
                 o.normalWorld = normalize( mul( half4( v.normal, 0.0 ), _World2Object ).xyz );
                 o.tangentWorld = normalize( mul( _Object2World, v.tangent ).xyz );
                 o.binormalWorld = normalize( cross( o.normalWorld, o.tangentWorld ) * v.tangent.w );
                 
                 half4 posWorld = mul( _Object2World, v.vertex );
                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
                 o.tex = v.texcoord;
                 o.color = v.color;
                 
                 o.viewDirection = normalize( _WorldSpaceCameraPos.xyz - posWorld.xyz );
                 
                 half3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
                 
                 o.lightDirection = fixed4( 
                     normalize( lerp( _WorldSpaceLightPos0.xyz, fragmentToLightSource, _WorldSpaceLightPos0.w ) ),
                     lerp( 1.0, 1.0/length( fragmentToLightSource ), _WorldSpaceLightPos0.w ) );
                 
                 return o;
             }
             
             //fragment function
             fixed4 frag( vertexOutput i ) : COLOR
             {
                 
                 //texture Maps
                 fixed4 texN = tex2D( _BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw );
                 
                 //unPackNormal function
                 fixed3 localCoords = fixed3( 2.0 * texN.ag - float2( 1.0, 1.0 ), _BumpDepth );
                 
                 //normal transpose matrix
                 fixed3x3 local2WorldTranspose = fixed3x3(
                     i.tangentWorld,
                     i.binormalWorld,
                     i.normalWorld
                 );
                 
                 //calculate normal direction
                 fixed3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
                 
                 //Lighting
                 //dot product
                 fixed nDotL = saturate( dot( normalDirection, i.lightDirection.xyz ) );
                 
                 fixed3 diffuseReflection = i.lightDirection.w * _LightColor0.xyz * nDotL;
                 fixed3 specularReflection = diffuseReflection * _SpecColor.xyz * pow( saturate( dot( reflect( -i.lightDirection.xyz, normalDirection ), i.viewDirection ) ), _Shininess);
                 
                 fixed3 lightFinal = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuseReflection + ( specularReflection );
                 
                 return fixed4( lightFinal * i.color, 1.0 );
             }
             
             ENDCG
         }
     }
     //Fallback "Diffuse"
 }
Comment
Add comment · 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

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

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

Shaders - changing the vertex color via script 1 Answer

Local position in vertex shader? 1 Answer

Quad vertex color shader 0 Answers

Lightweight Render Shader not receive shadows 0 Answers

How to set shader vertex normals to face up 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