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 Tabemasu Games · Nov 20, 2014 at 11:04 AM · shadercustomvertex

Apply a bumped shader on top of a custom vertex shader

Hi,

I am working on a custom vertex shader which will modify the position of a mesh vertices according to time and other parameters.

But I'd like to keep the "visual" shader already attached to my mesh (in my case a Bumped Diffuse shader).

I tried something like this:

 Shader "Custom/Test" {
     SubShader {
         Pass {
             CGPROGRAM
 
             #pragma vertex vert
             #pragma fragment frag
 
             struct VertStruct
              {
                  float4 position : POSITION;
                  float4 color : COLOR;
              };
 
             VertStruct vert(VertStruct v) {
                 v.position.x *= 2.0f;
                 v.position.y *= 0.5f;
                 v.position.z *= 0.5f;
 
                 VertStruct output;
                 output.position = mul(UNITY_MATRIX_MVP, v.position);
                 output.color = v.color;
                 return output;
             }
 
             fixed4 frag(float4 color : COLOR) : COLOR {
                 return color;
             }
 
             ENDCG
         }
     }
 }
 

But instead of having my mesh go through the two shaders one after the other, it's rendered twice in the scene: alt text

How can I apply the bumped diffuse shader and THEN, apply my custom vertex shader on top of that (or the other way around)?

test shader.png (218.6 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 CHPedersen · Nov 20, 2014 at 12:01 PM

Your image doesn't show in the question, but I can sort of imagine what it looks like.

Having it go through two shaders, one after the other, IS to render it twice. There is no difference in that regard, it's like having multiple materials on the renderer, or designing a shader that has multiple passes. Each pass, or each material, will send the object through the pipeline once, causing it to render. That's how the pipeline works. :)

What you need to do instead is to add your custom vertex shader to the standard bump mapping shader. This is pretty easy to do, but requires a little bit of preparation. First, acquire the source to the built-in shaders. There's a download link next to the editor's at this link:

http://unity3d.com/unity/download/archive

Find the surface shader source for the bump mapped shader you need. There are multiple different ones, depending on whether you need to modify the Bump Diffuse, Bump Specular, Transparent Bumped Diffuse, Transparent Bumped Specular, etc.

Suppose it's the bumped specular you want. The source code for that shader looks like this:

 Shader "Bumped Specular" {
 Properties {
     _Color ("Main Color", Color) = (1,1,1,1)
     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
     _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
     _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
     _BumpMap ("Normalmap", 2D) = "bump" {}
 }
 SubShader { 
     Tags { "RenderType"="Opaque" }
     LOD 400
     
 CGPROGRAM
 #pragma surface surf BlinnPhong
 
 
 sampler2D _MainTex;
 sampler2D _BumpMap;
 fixed4 _Color;
 half _Shininess;
 
 struct Input {
     float2 uv_MainTex;
     float2 uv_BumpMap;
 };
 
 void surf (Input IN, inout SurfaceOutput o) {
     fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
     o.Albedo = tex.rgb * _Color.rgb;
     o.Gloss = tex.a;
     o.Alpha = tex.a * _Color.a;
     o.Specular = _Shininess;
     o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
 }
 ENDCG
 }
 
 FallBack "Specular"
 }

Now, what you want is to add your custom vertex shader to that. There's an example of how to do so in the Surface Shader examples at this link:

http://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html

Under the section "Normal extrusion with vertex modifyer". But in short, you need to define your vertex function after the surface function declaration by adding "vertex:vert" after the lighting function name, if your vertex function is called vert. Doing so would change the specular bump mapped shader to this:

 Shader "Bumped Specular" {
 Properties {
     _Color ("Main Color", Color) = (1,1,1,1)
     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
     _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
     _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
     _BumpMap ("Normalmap", 2D) = "bump" {}
 }
 SubShader { 
     Tags { "RenderType"="Opaque" }
     LOD 400
     
 CGPROGRAM
 #pragma surface surf BlinnPhong vertex:vert
 
 
 sampler2D _MainTex;
 sampler2D _BumpMap;
 fixed4 _Color;
 half _Shininess;
 
 struct Input {
     float2 uv_MainTex;
     float2 uv_BumpMap;
 };
 
 void vert (inout appdata_full v) {
     // Your custom vertex shader code goes here
 }
 
 void surf (Input IN, inout SurfaceOutput o) {
     fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
     o.Albedo = tex.rgb * _Color.rgb;
     o.Gloss = tex.a;
     o.Alpha = tex.a * _Color.a;
     o.Specular = _Shininess;
     o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
 }
 ENDCG
 }
 
 FallBack "Specular"
 }


That shader is the same as the standard bump mapped specular shader, just prepared for your custom vertex shader code.

Hope this helps. You should be able to complete your shader with this.

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 Tabemasu Games · Nov 20, 2014 at 12:33 PM 0
Share

I thought of this solution but did not think it would be the best one, because it causes code to be duplicated and not updated if Unity updates its shaders (even though it might happen very rarely).

Too bad we cannot call a shader function from another. I'm still new in writing shaders, so I have difficulties understanding the workflow of it.

Thank you very much!

avatar image CHPedersen · Nov 20, 2014 at 12:41 PM 0
Share

You can call a shader function from another, but it depends perhaps on what you mean by "shader function". If you're talking about defining a function to be accessible in other shaders, you can just define it in a cginc-file, and then include that in your shader. That's what Unity itself does with its file "UnityCG.cginc".

If you mean you wish to use a pass defined in another shader, you can do so too: It requires only that the target shader's pass be named (has a "Name" tag), and that you call it with the "usepass" syntax in the calling shader.

But if you want to totally dynamically combine different shaders with separate passes into a single pass through the pipeline... That's not possible, and the notion doesn't apply to the whole pass design.

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Need help with using world position in shader 1 Answer

Vertex program max instructions limit 2 Answers

Z-priming alpha-per-vertex 0 Answers

Strange artifacts on Vertex Color Shader 0 Answers

Easy way to make a custom toon water shader 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