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 Rs · Feb 15, 2013 at 02:54 PM · shaderrandomcg

Randomness in CG shaders

Hi all, I need a random value in the shader I'm creating now and I know I can pass a value from a script very easily but what if I want to avoid the script? Is there a way to generate a random constant inside a CG shader?

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

3 Replies

· Add your reply
  • Sort: 
avatar image
6

Answer by Aily · Jan 24, 2014 at 09:56 AM

 float rand(float3 co)
 {
     return frac(sin( dot(co.xyz ,float3(12.9898,78.233,45.5432) )) * 43758.5453);
 }

You can use it with world position of pixel in Unity's surface shaders , like this:

 ...
 struct Input 
 {
     ....
     float3 worldPos;
 };
 
 .....
 
 void surf (Input IN, inout SurfaceOutput o) 
 {
     o.Albedo = half3(rand(IN.worldPos));
     o.Alpha = 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 jamesflowerdew · Aug 08, 2014 at 11:52 AM 2
Share

Hi, I wanted to dig this discussion up again :). I found this post looking for random numbers in cg, and had a play with this result.

 Shader "Custom/noise" {
     Properties {
         _Color("Colour (RGBA)", Color) = (0,0,0,1)
         _Res("Noise Resolution",Float)=128
     }
     SubShader {
         Tags { "RenderType"="Opaque" }
         LOD 200
         
         CGPROGRA$$anonymous$$
 
         #pragma surface surf Lambert
          float4 _Color;
         float _Res;
         struct Input {
             float2 uv: TEXCOORD;
             float3 worldPos;
         };
         
         float rand(float3 myVector)  {
             return frac(sin( dot(myVector ,float3(12.9898,78.233,45.5432) )) * 43758.5453);
         }
         
         void surf (Input IN, inout SurfaceOutput o) {
             float3 vWPos=IN.worldPos;
             //float3 vTimeOffset=float3(1,1,1)*_Time[0];
             //vWPos+=vTimeOffset;
             vWPos*=_Res;
             
             float Rand1=rand(round(vWPos));
             vWPos+=float3(.5,.5,.5);
             
             Rand1+=rand(round(vWPos));
             vWPos-=float3(1,1,1);
             //Rand1+=rand(round(vWPos));
             Rand1/=2;
             o.Albedo =float3(Rand1,Rand1,Rand1)*_Color.xyz;
             o.Alpha = 1;
         }
         ENDCG
     } 
     FallBack "Diffuse"
 }


However, I cannot get more than 3 random calls on this and noticed that the patterns become recurrent very quickly. Ideally I'd need 4 calls for a perlin effect that I read about, but more importantly this would be more useful if it were faster anyway.

Is there an equation that doesn't require sin and cos? these are costly.

Also, is there a simpler version that just takes single values ins$$anonymous$$d of float3?

Ideally I'd like a cg function that could receive an int seed, and return an "apparently random number". Ranges that go above 256 values are not needed, a returned int of 0-100 would be fine, as would a returned float or half of 0 to 1 with an accuracy of about .01.

I am aware that you can use texture lookups, but pulling a number out of simple maths is surely faster than a texture lookup in some cases, particularly if you want worldspace based uvs? [edit] just to clarify I don't want "real" random numbers, the same seed should produce the same result.

avatar image TruffelsAndOranges · Jul 09, 2015 at 08:49 AM 2
Share

Why not just add _Time to the rand-function like this: float rand(float3 co) { return frac(sin( _Time dot(co.xyz ,float3(12.9898,78.233,45.5432) )) 43758.5453); }

avatar image
3

Answer by Dave-Carlile · Feb 15, 2013 at 03:24 PM

I don't believe there is a direct way to generate random numbers in a shader. You can fake it out though.

  • Create a texture that contains random values, set it to repeat

  • Use incoming vertex or uv values to "sample" the random number texture

Or you can implement your own function fairly easily by converting a standard psuedo-random algorithm...

http://en.wikipedia.org/wiki/Random_number_generators http://mathoverflow.net/questions/29494/pseudo-random-number-generation-algorithms

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 Rs · Feb 15, 2013 at 03:36 PM 0
Share

Thank you for your answer Dave. Very clarifying. I used this approach in the past. I think I'll end up using _Time and length(vertex) in some expression to generate my value. I also took a look to the noise function but people suggest to avoid using it. Thanks a lot. Sorry I can't vote you up yet.

avatar image MountDoomTeam · Aug 16, 2013 at 09:10 PM 0
Share

if you need a single random value, you can gen it in a unityscript and use material.SetFloat

avatar image
0

Answer by Lloyd_RedironLabs · Feb 13, 2016 at 05:44 AM

I know this is an old post, but I thought I'd share my variation of the above.

It adds metallic, smoothness, transparency, illumination, emission, allows textures and uses _Time for randomizing as suggested above - mostly just ripped from the Unity 5 shader concept.

If you want to see something cool, put a fade effect on it. Use a sphere. And make it red. It looks like a giant alien computer coming to eat your face!!!

Preview

Options

 Shader "Custom/Noise/NoiseRandomAdvanced" {
     Properties{
         _Color("Colour (RGBA)", Color) = (0,0,0,1)
         
         _Res("Noise Resolution",Float) = 128
         _MainTex("Color (RGB) Alpha (A)", 2D) = "white" {}
 
         _Glossiness("Smoothness", Range(0,1)) = 0.5
         _Metallic("Metallic", Range(0,1)) = 0.0
 
         _Illum("Illumin (A)", 2D) = "white" {}
         _Emission("Emission (Lightmapper)", Float) = 1.0
     }
     SubShader{
             
         Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
         LOD 200
 
         CGPROGRAM
 
         #pragma surface surf Standard fullforwardshadows alpha
         #pragma target 3.0
 
         float4 _Color;
         float _Res;
 
         struct Input {
             float2 uv: TEXCOORD;
             float3 worldPos;
             float2 uv_MainTex;
             float2 uv_Illum;
         };
 
         half _Glossiness;
         half _Metallic;
         sampler2D _Illum;
         fixed _Emission;
 
         float rand(float3 myVector) {
             return frac(sin(_Time[0] * dot(myVector ,float3(12.9898,78.233,45.5432))) * 43758.5453);
         }
     
         sampler2D _MainTex;
 
         void surf(Input IN, inout SurfaceOutputStandard o) {
             float3 vWPos = IN.worldPos;
             vWPos *= _Res;
 
             float Rand1 = rand(round(vWPos));
             vWPos += float3(.5,.5,.5);
 
             Rand1 += rand(round(vWPos));
             vWPos -= float3(1,1,1);
             Rand1 /= 2;
 
             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color * float4(Rand1, Rand1, Rand1, Rand1);
 
             o.Albedo = c;
             o.Metallic = _Metallic - (1- _Color.a);
             o.Smoothness = _Glossiness;
             o.Emission = c.rgb * tex2D(_Illum, IN.uv_Illum).a * _Emission.rrr;
             o.Alpha = _Color.a;
         }
         ENDCG
     }
     FallBack "Diffuse"
 }



noiseshader3.png (63.3 kB)
noiseshader2.png (22.2 kB)
Comment
Add comment · Show 3 · 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 chanfort · Apr 27, 2016 at 07:03 PM 0
Share

I am getting completely black shader on the cube using this. How do you set it up? alt text alt text

screen-shot-2016-04-27-at-200454.png (64.5 kB)
avatar image Jessespike chanfort · Apr 27, 2016 at 08:08 PM 0
Share

Did you press Play? The shader will be black when not in play mode.

avatar image LilaQ · Aug 27, 2016 at 01:44 AM 1
Share

I am disappointed not seeing a screenshot of the cool thing :-(

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

14 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

Related Questions

How to force the compilation of a shader in Unity? 5 Answers

_LightMatrix0 and Directional Light 1 Answer

conditional pragma target 0 Answers

Shader: get nearest point light's color, direction and general custom lighting questions 0 Answers

Is there a way to enable shader pass from code? 0 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