- Home /
Why does fmod(x,1.0) not work in Unity4, but fmod(x,1.0001) does?
This is an interesting one... I've found that the shaderlab code below doesn't work in Unity4 (it did in 3.5!). I believe I've traced it to the fmod call inside my cellDist function.
This works:
uWrapped = fmod(1.0+uNeighbor, 1.0001);
This doesn't:
uWrapped = fmod(1.0+uNeighbor, 1.0);
Any ideas why? If I just do a straight-up fmod of, say, IN.worldPos.y with 1.0, everything works properly.. so what's weird about the call I'm doing? Unity doesn't give any helpful errors on compilation. I don't like fudging my fmod, it quickly introduces precision errors in the shader as you move away from the origin.
Here's the whole shader:
Shader "Custom/VoronoiShader" {
Properties {
_UColor("U Color", Color) = (0,0,0,1)
_VColor("V Color", Color) = (1,1,1,1)
_Frequency("Frequency", Range(1,100)) = 4
_Offset("Offset", Range(-100,100)) = 0
_ScaleU("ScaleU", Range(.001,1)) = 1
_ScaleV("ScaleV", Range(.001,1)) = 1
_Amp ("Amp", Range(0,1)) = 1
_Freq ("Freq", Range(0,25)) = 2
_Speed ("Speed", Range(0,25)) = 25
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
#pragma target 3.0
struct Input
{
float3 worldNormal;
float3 worldPos;
};
float4 _UColor;
float4 _VColor;
float _Frequency;
float _Offset;
float _ScaleU;
float _ScaleV;
float _Amp;
float _Freq;
float _Speed;
float quantize(float u)
{
float regionSize = 1.0/_Frequency;
int quant = (int)(u/regionSize);
return (float)(quant*regionSize);
}
half4 cellDist(float u, float v)
{
float minDist = 3.0;
float secMinDist = 3.0;
float uNeighbor, vNeighbor, uWrapped, vWrapped, randomU, randomV, dist;
for(int uOffset = -1; uOffset <= 1; uOffset++)
{
for(int vOffset = -1; vOffset <= 1; vOffset++)
{
uNeighbor = quantize(u)+uOffset/_Frequency;
vNeighbor = quantize(v)+vOffset/_Frequency;
//hack to get around potential fmod(x,1.0) bug?
uWrapped = fmod(1.0+uNeighbor, 1.0001);
vWrapped = fmod(1.0+vNeighbor, 1.0001);
randomU = uNeighbor + .5/_Frequency * sin(_Time*_Speed) * _Amp*(cos(3.1415*uWrapped*_Freq+_Time*_Speed)*sin(3.1415*vWrapped*_Freq+_Time*_Speed));
randomV = vNeighbor + .5/_Frequency * cos(_Time*_Speed) * _Amp*(cos(3.1415*vWrapped*_Freq+_Time*_Speed)*sin(3.1415*uWrapped*_Freq+_Time*_Speed));
dist = sqrt(pow(randomU-u,2) + pow(randomV-v,2));
if(dist < secMinDist)
{
if(dist < minDist)
{
secMinDist = minDist;
minDist = dist;
}
else
{
secMinDist = dist;
}
}
}
}
half4 c = _UColor + ((_VColor-_UColor) * (minDist)) * _Frequency;
return c;
}
void surf (Input IN, inout SurfaceOutput o)
{
float u = IN.worldPos.x * _ScaleU;
float v = IN.worldPos.z * _ScaleV;
half4 voronoi = cellDist(u,v);
o.Albedo = voronoi.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
Your answer
Follow this Question
Related Questions
3D Texture and normals 0 Answers
Simple shader Parse error: syntax error problem 0 Answers
clipping shader for OpenGL quad 0 Answers
Collision issues SOLVED 2 Answers
Shader - Using Multiple Pass for different shader target 1 Answer