# frac(x) results in strange artifacts when x is close to zero

This topic is 1422 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am using a cg shader to create a white grid on my terrain. The terrain iteself consists of tiles where each tile is 4x4 units big. I'm using this fact to calculate locale UV coordinates for each tile to draw the content of a grid texture. This grid texture's size is only 128x128 pixels. It's border consists of white pixels and the middle part is transparent.

The calculation of those local uv coordinates is done by using frac(x). However, it results in artifacts on the transition to neighbouring tiles. Disabling the generation of MipMaps for the grid texture makes those artifacts disappear. I still don't understand why those MipMaps are causing this.

Do you know why? Can I avoid this somehow?

Shader "Custom/World"
{
Properties
{
_Color ("Main Color", Color)            = (0.5,0.5,0.5,1)
_MainTex ("Base (RGB) Trans (A)", 2D)   = "white" {}
_Grid ("Base (RGA) Trans (A)", 2D)      = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1))    = 0.5
}

{
Tags
{
"Queue"           = "AlphaTest"
"IgnoreProjector" = "True"
"RenderType"      = "TransparentCutout"
}
LOD 200

CGPROGRAM
#pragma surface surf Lambert alphatest:_Cutoff

sampler2D _MainTex;
sampler2D _Grid;
fixed4 _Color;

struct Input
{
float2 uv_MainTex;
float3 worldNormal;
float3 worldPos;
};

float2 getGridUV(float3 worldPos)
{
float u = frac(worldPos.x / 4.0); // a tile is 4 units wide
float v = frac(worldPos.z / 4.0); // and also 4 units deep

return float2(u, v);
}

void surf(Input IN, inout SurfaceOutput o)
{
fixed4 c    = tex2D(_MainTex, IN.uv_MainTex) * _Color;
float alpha = tex2D(_Grid, getGridUV(IN.worldPos)).a;

o.Albedo    = c.rgb * (1.0 - alpha) + (1,1,1,1) * alpha;
o.Alpha     = c.a;
}

ENDCG
}
}



Edit: The title isn't really correct but I can't change it anymore. Sorry.

Edited by BrightBit

##### Share on other sites

You'll have to point out what exactly is wrong with the image you posted. Or at least post an image that looks correct, so we can spot the differences. I'm not sure what I'm looking at.

Also, the title of the post claims frac is the cause of the problem, but the content of your post indicates that it's mipmaps that are the thing that determines whether the artifact appears or not. Your use of frac looks correct to me, so I would guess your problem is that your mipmaps don't look the way you think they do.

How are you generating mips? Do you ever look at your mips to make sure they're correct? Is it possible your mips have some kind of corruption near the border?

Edited by Samith

##### Share on other sites

Thank you Erik. Your suggestion did the trick and someone submitted this link to me that seems to fit to your assumption about the mip mapping behaviour of the gpu.

##### Share on other sites

Fwiw, you should never avoid using mips without good reason. Mips are there largely to avoid thrashing the cache, and therefore improve performance. You can avoid the problem Erik described by supplying your own derivatives into the tex2d call that are calculated prior to the frac() call. This lets the hardware use the mips that it would have had the frac() call not been there. Something along the lines of this:

float2 uv = worldPos.xz / 4; // <- swizzle elements however you need, instead of doing your math seperately on x and z!
float alpha = tex2Dgrad(_Grid, frac(uv), ddx(uv), ddy(uv)).a;


Also, its perfectly acceptible to use texture coordinates that are outside of 0 to 1. You can assign sampler addressing modes to let the hardware automatically repeat the texture, or clamp it, in either dimension. That avoids the need for the tex2Dgrad & frac completely.

EDIT: sorry, i missed the part where Erik already pointed out the usages of the wrap mode. I'll leave my comment about tex2Dgrad though, as its handy for similar situations that cant be fixed via repeat (such as when tiling within 0 to 1)

Edited by Digitalfragment

1. 1
2. 2
3. 3
4. 4
frob
15
5. 5

• 20
• 12
• 13
• 14
• 84
• ### Forum Statistics

• Total Topics
632144
• Total Posts
3004419

×