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?

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;
}

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…

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!!!

63808-noiseshader3.png

63809-noiseshader2.png

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"
}