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