- Is it helpful to make use of Generate Mipmaps for a texture utilized in a skybox shader?
Utilizing the equirectangular / panorama / latitude-longitude texture mapping you have chosen, sure, mipmaps can be useful for efficiency when trying up.
As a result of this projection stretches tiny areas close to the poles (just like the “high” of the sky) throughout the entire width of the feel, two pixels very shut to one another on the display screen will find yourself studying widely-separated elements of the feel, regardless that they need virtually the identical color worth in the long run. This thrashes the feel cache, rising common latency and reducing throughput / efficient texture bandwidth. On cell, that additionally means draining extra battery. These results get extra extreme as your texture decision will increase.
When mipmaps can be found (and we use the proper texture-fetching code), the GPU can detect that the feel is being successfully downsampled right here, and swap to studying from a smaller mip for each samples. As a result of the mip is smaller, extra of it suits in cache at a time, and there is a higher likelihood that texels you fetched to shade one pixel will be re-used for a close-by one, enhancing efficiency.
For only one texture on a contemporary system, you most likely will not discover the distinction. However in case you are utilizing a lot of these lookups for issues like reflection maps, or in case you’re concentrating on lower-end cell gadgets, these prices can add up.
An alternate is to make use of a texture projection with a extra even texel distribution, like a cubemap. In that case, you may simply dimension your cubemap to be about the proper decision to your goal show dimension, and you will not see such wild variation in caching efficiency relying on the place the participant appears. The shader code for sampling the feel can also be cheaper.
When you’re utilizing this skybox as a mirrored image map, then mipmaps are additionally helpful for cheaply rendering uninteresting / blurry reflections, in both projection format.
- What’s the highest LOD for textures with a decision of 1024?
Every stage of element is one mipmap stage, with the decision halving at every step. When you had a 1024×1024 map to start out with, then…
- The unique decision (1024 x 1024)
- The primary mipmap, at half res (512 x 512)
- The second mipmap, at quarter res (256 x 256)
- The third mipmap, at eighth res (128 x 128)
- The fourth mipmap, at sixteenth res (64 x 64)
- The fifth mipmap (32 x 32)
- The sixth mipmap (16 x 16)
- The seventh mipmap (8 x 8)
- The eighth mipmap (4 x 4)
- The ninth mipmap (2 x 2)
- The deepest mipmap (1 x 1 – a single texel)
Normally, a texture whose smallest dimension is $2^n$ can have as much as $n$ mipmaps, plus the unique decision.
Since a panorama picture is normally wider than it’s tall, it’s best to use the vertical dimension when doing mipmap figuring. So a 1024×512 picture can have as much as 9 down-scaled mipmaps, plus the unique, and a 1024×256 sky dome picture can have as much as 8, plus the unique.
Simply because a texture can have this many mipmap ranges doesn’t essentially imply that it does. Some settings that may have an effect on this:
- You possibly can configure a mipmap restrict to make use of solely the smaller mip ranges. This may be configured within the high quality settings by platform, so as an illustration the identical recreation constructed for desktop, cell, and internet may use completely different texture sizes and completely different mips on every vacation spot.
- You possibly can allow mipmap streaming, so higher-resolution variations usually are not loaded till wanted. This implies the variety of mipmaps truly accessible may change at runtime.
- A texture created by script or imported from a format that accommodates mips like DDS will be configured to incorporate solely the upper decision mips (as much as a restrict set by the creator), skipping the lower-res mip ranges.
- What’s going to occur if the decision modifications to 512 however the LOD worth isn’t modified?
A name to tex2Dlod
will pattern the mip on the index specified by the w part of the feel coordinate. So this name:
tex2Dlod(_MainTexture, half4(coords, 2, 0));
…will all the time pattern from mipmap index 0, the best decision accessible (fully shedding any advantages of mipmapping as mentioned in query 1 – we’ll come again to this).
For a 1024×1024 picture, that is the 1024×1024 model it is sampling from. When you resize the picture to 512×512 (or it will get restricted to that decision by the mipmap restrict, high quality settings, or mipmap streaming), then it is the 512×512 model it is sampling from.
When you used 1 within the w part, then from a 1024×1024 picture, it might pattern the 512×512 mip, and from a 512×512 picture, it might pattern the 256×256 mip (in each circumstances: one step down from the best accessible).
If the worth give for the w part is larger than the deepest mip index within the texture, the deepest (lowest-resolution) mip is used as a substitute.
As an apart, the “2” within the code above is meaningless – tex2Dlod doesn’t use the z part of the feel coordinate, as you may see within the documentation.
- How will tex2Dlod behave if Generate Mipmaps is disabled within the texture settings?
It can all the time pattern from the highest-resolution model of the feel accessible, precisely what you are doing now.
Now, the query you did not ask, however most likely ought to have:
“How can I accurately repair the seam on an equirectangular panorama texture?”
I want to make use of tex2Dlod to repair the sting seams difficulty
No, that is not the right solution to repair the seam in case you care about gaining the advantages of mipmapping mentioned in query 1.
What we wish to do as a substitute is inform the graphics card how shortly the feel coordinate is altering between close by pixels on the display screen, so it might probably choose/mix the most effective mip ranges (and anisotropic filtering, if enabled) mechanically.
What causes the seam is the place the longitude wraps round from π (180°) to -π (-180°). We all know these values reference the identical a part of the feel, however the texture mapping {hardware} sees a bounce throughout the entire width of the feel from one pixel to the one instantly beside it, as if the feel have been scaled means down, so the sampling {hardware} mips-down unnecessarily with the same old tex2D
name.
We will use the trick I present on this reply to right the feel gradient and ignore this spurious bounce within the x coordinate.
This is a shader that does that:
Shader "Skybox/FixedPanorama"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[KeywordEnum(Sky Sphere, Sky Dome)] _Mapping("Mapping", float) = 0
}
SubShader
{
Tags { "RenderType"="Background" "Queue"="Background" "PreviewType"="Skybox" }
Cull Off
ZWrite Off
Cross
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local __ _MAPPING_SKY_DOME
#embody "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float3 route : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex.xyz);
o.route = v.vertex.xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half2 longlat;
longlat.x = atan2(i.route.z, i.route.x) * half(-0.5);
longlat.y = asin(i.route.y/size(i.route));
longlat /= half(UNITY_PI);
#ifdef _MAPPING_SKY_DOME
longlat.x += half(0.5);
longlat.y *= half(2.0);
#else
longlat += half(0.5);
#endif
// Compute how briskly the feel coordinates are altering
// as we transfer throughout the display screen.
half4 gradient = half4(ddx(longlat), ddy(longlat));
// Wrap the gradient for longitude, so a bounce of +/-1 turns into 0
gradient.xz = frac(gradient.xz + half(1.5)) - half(0.5);
// If you wish to pattern a smaller mip to cheaply blur the picture,
// simply multiply the gradient by the scale of your blur.
// gradient *= half(4.0); // Steps down 2 mips, approximating a 4x4 blur.
fixed4 col = tex2Dgrad(_MainTex, longlat,
gradient.xy, gradient.zw);
return col;
}
ENDCG
}
}
}
Be sure you set the feel wrap mode to “Clamp” on the V axis to get right mipmap era (texels alongside the highest of the sky should not get blended with ones from the underside). Listed here are the settings I used when penning this reply:
However I would reiterate that it is higher to simply use a cubemap for this – it is what they’re designed for. For an equal variety of texels, cubemaps have a greater worst-case angular decision than equirectangular panoramas, means much less stretching and anisotropy, and no seams to repair. It additionally helps that the logic for sampling and filtering them accurately is built-in, so we get easier shaders that simply do the proper factor out of the field. Utilizing Unity’s automated cubemap import, you do not even have to vary the textures you are utilizing as your supply recordsdata – it might probably transparently re-encode them as cubemaps behind the scenes.