• 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 Matthew Scott · Apr 29, 2013 at 05:43 AM · shadervertexcubemapdeformationdiffuse

Cubemap Diffuse / Heightmap Shader Issues.

I'm trying to code a shader that uses two cubemaps, one for diffuse and one for vertex deformation. There going to be used on a quad sphere.

My shader skills are yet to be...refined shall we say. I can grasp the basic logic but I still need to get my head around how these things work...

From what I understand about shaders, I managed to combine and modify what I could to get this result...

 Shader "Custom/Test"
 {
     Properties
     {
         _CubeDiffuse ("Cubemap Diffuse Map", CUBE) = "" {}
         _CubeHeight ("Cubemap Height Map", CUBE) = "" {}
         _Amount ("Extrusion Amount", Range(-1,1)) = 0.5 //PROBLEM2 - This should act as a multiplier for _CubeHeight rather than a dedicated setting.
     }
     
     SubShader
     {
         Tags { "RenderType" = "Opaque" }
       
         CGPROGRAM
         #pragma surface surf Lambert vertex:vert
         
         struct Input
         {
             float3 worldRefl; //PROBLEM 1 - I this this input is causing the diffuse to distort like a reflective cubemap would.
         };
 
         float _Amount; //PROBLEM2 - I need this 'Amount' to read the values from _CubeHeight not _Amount.
         
         void vert (inout appdata_full v)
         {
             v.vertex.xyz += v.normal * _Amount;
         }
 
           samplerCUBE _CubeDiffuse;
       
           void surf (Input IN, inout SurfaceOutput o)
           {
             o.Albedo = texCUBE (_CubeDiffuse, IN.worldRefl).rgb; //PROBEM 1 - It's applied here.
         }
         
         ENDCG
     } 
     Fallback "Diffuse"
 }
 

The diffuse part works, but it acts like a reflection cube map and distorts as the object rotates. And adjusting the 'Amount' value leads to every vertex moving the exact same amount as expected.

Problem1 - I need to solve the distortion issue.

Problem2 - I need the amount value to read from the greyscale value of the _CubeHeight Texture.

I've searched everywhere on the net for something similar and found this one shader which takes care of the diffuse but not the vertex deformation. And it also does not respond to lighting...

 Shader "Custom/PlanetShader"
 {
     Properties
     {
         _CubeTex("Cubemap", CUBE) = "" {}
     }
     
     SubShader
     {
         Tags { "RenderType"="Opaque" }
  
         Pass
         {
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma fragmentoption ARB_precision_hint_fastest
  
             #include "UnityCG.cginc"
  
             samplerCUBE _CubeTex;
  
             struct appdata_t
             {
                 float4 vertex : POSITION;
                 float3 normal : NORMAL;
             };
  
             struct v2f
             {
                 float4 vertex : POSITION;
                 float3 texcoord : TEXCOORD0;
             };
  
             v2f vert(appdata_t v)
             {
                 v2f OUT;
                 OUT.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 OUT.texcoord = v.normal;
                 return OUT;
             }
  
             half4 frag(v2f IN) : COLOR
             {
                 return texCUBE(_CubeTex, IN.texcoord);
             }
             ENDCG 
         }
     }
     
     FallBack "Diffuse"
 }

Any help or guidance would be greatly appreciated.

Comment
Add comment · Show 7
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 whydoidoit · Apr 29, 2013 at 06:10 AM 1
Share

Ok - so you want to not use a reflection vector for the cubemap sample I guess, just the normal, (because that's what the second shader does).

The following is a total guess as I don't have a rig to test it:

 Shader "Custom/Test"
 {
     Properties
     {
        _CubeDiffuse ("Cubemap Diffuse $$anonymous$$ap", CUBE) = "" {}
        _CubeHeight ("Cubemap Height $$anonymous$$ap", CUBE) = "" {}
        _Amount ("Extrusion Amount", Range(-1,1)) = 0.5 //PROBLE$$anonymous$$2 - This should act as a multiplier for _CubeHeight rather than a dedicated setting.
     }
  
     SubShader
     {
        Tags { "RenderType" = "Opaque" }
  
        CGPROGRA$$anonymous$$
        #pragma surface surf Lambert vertex:vert

         samplerCUBE _CubeDiffuse;
         samplerCUBE _CubeHeight;
        float _Amount;


  
        struct Input
        {
          float3 normal; //PROBLE$$anonymous$$ 1 - I this this input is causing the diffuse to distort like a reflective cubemap would.
        };
  
  
        void vert (inout appdata_full v)
        {
          v.vertex.xyz += v.normal * texCUBE(_CubeHeight, v.normal).r;
        }
  
         void surf (Input IN, inout SurfaceOutput o)
         {
          o.Albedo = texCUBE (_CubeDiffuse, IN.normal).rgb; 
        }
  
        ENDCG
     } 
     Fallback "Diffuse"
 }
avatar image whydoidoit · Apr 29, 2013 at 06:13 AM 0
Share

Ok scratch that - spotted the definitions I was missing and have updated the comment.

avatar image Matthew Scott · Apr 29, 2013 at 04:24 PM 0
Share

Thanks, I'll try this out and let you know how it goes!

avatar image Matthew Scott · Apr 29, 2013 at 07:27 PM 0
Share

No such luck, I don't think it likes the 'normal' stuff, and it seems to throwing up at line 31. Hmm, it's for an FYP so, I guess I'll just have to work around it and write down other methods.

avatar image whydoidoit · Apr 29, 2013 at 08:00 PM 0
Share

There's some platforms that don't support samplers in the vertex shader - that may go double for cube samplers...

avatar image Matthew Scott · Apr 29, 2013 at 08:17 PM 0
Share

Hmm, I think you may be right. I updated the shader and fixed the cubemap to diffuse issue...incase anyone wants to make use of it for some reason I've posted it here, I've also added in rim lighting.

 Shader "Custom/Test"
 {
     Properties
     {
         _CubeDiffuse ("Cubemap Diffuse $$anonymous$$ap", CUBE) = "" {}
         _RimColor ("Rim Color", Color) = (0.50, 0.50, 0.50, 0.0)
           _RimPower ("Rim Power", Range(0.5, 8.0)) = 3.0
           _ColorTint ("Tint", Color) = (1.0, 0.6, 0.6, 1.0)
     }
 
     SubShader
     {
 
         Tags { "RenderType" = "Opaque" }
 
         CGPROGRA$$anonymous$$
         #pragma surface surf Lambert
 
         struct Input
         {
             float3 worldNormal; INTERNAL_DATA
             float3 viewDir;
         };
 
         samplerCUBE _CubeDiffuse;
         float4 _RimColor;
           float _RimPower;
 
         void surf (Input IN, inout SurfaceOutput o)
         {
             o.Albedo = texCUBE (_CubeDiffuse, IN.worldNormal);
             half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
               o.Emission = _RimColor.rgb * pow (rim, _RimPower);
         }
 
         ENDCG
     } 
     Fallback "Diffuse"
 }

Do you have any other thoughts on how I might accomplish this? I thought I might move the vertices manually through code, but I assume that would require vertex colours or at least something that can serve as a reference for how much to move each vertex by. Obviously with this shader there are no vertex colors...I really need to find some sort of solution, even it's hacky or a workaround.

avatar image whydoidoit · Apr 29, 2013 at 08:25 PM 0
Share

Well I guess you could distort the mesh by playing with the vertices - as it's not really changing right? That would be a performance boost too. So just need to figure out what the equivalent code is of that cube sampler and do it in the ordinary script.

Presu$$anonymous$$g the vertices are evenly spaced it can't be beyond the wit of man to get the right value from the right place I would have thought. Happy to think it through with you.

1 Reply

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

Answer by Matthew Scott · Apr 29, 2013 at 10:19 PM

Well, this was the idea I had, but I'm running short on time, and I'm not entirely sure it would work.

For every vertice in the quad sphere mesh, I need to get the colour of the height map at that particular point and move it vector3.up a said amount depending on the greyscale value of the texture at that point. I can't use vertex colours, so my idea was this.

Each vertex position is in local space so theoretically it should work. At each vertex point, create another point further out in the same direction. From there, ray cast back towards the sphere and retrieve the uv co-oords of the texture at the hit point. From these uv co-oords I hope to retrieve the colour of the pixel in that texture uv location and then move the related vertex by that amount according to my own math...move Vector.up pixel.greyscale heightscale...for e.g.

Am I on the right track here? I've run out of options I can think off..

Comment
Add comment · Show 1 · 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 Matthew Scott · Dec 08, 2013 at 11:41 PM 0
Share

HAC$$anonymous$$Y! But it got the job done. (Old question but just wanted to clear that up...

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

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

Problem of color in custom vertex shader 0 Answers

Sprite Deform Diffuse Shader 0 Answers

Curved + Diffuse Shader??? 0 Answers

How do I update the collider mesh based on the shader vertex deformed mesh? 0 Answers

How can I add the diffuse property to a vertex 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