Divided Huge Texture Shader

I have a huge sphere (you can think a planet) and 21600x10800 texture for it. (That size req because there is a zoom option) Sure i will divide that texture. But how to use? I need a shader for it.

That scene havent much object but i dont want waste performance too.
I need a basic diffuse with a little self lightning. I mean if there is no light, it req visible a little instead of black. with light it will be more lighter. (No lightning texture only not black without light)

How to write that shader?

3 Answers

3

unity supports maximum of 4096x4096 textures, so you should split it to 18 textures.

and the best way even in performance reason is to make a 3d model of sphere mapped to 18 different materials. then use just a regular shader.

P.S. “No lightning texture only not black without light” is also known as Ambient Light

P.P.S. i could help you to write a shader with 18 textures, but i’m not sure this will be better then 18 materials with simple shaders…

remove grid by changing texture wrap mode from 'repeat' to 'clamp' shader limits can be avoided, for example ignoring tiling/offset of textures is way to decrease calculations post your shader - i'll look

–

never use textures with non-power-of-two size in 3d graphics. use 4096x4096 and it will takes no more then 64MB per texture, 48MB without alpha channel

–

sorry for shader, but i didn't found a way to make more then 16 textures. before that all limits was avoided in my practice 8). this one looks like compiler limit. hope unity4 will support texture arrays. about memory i said already, 4096x4096 RGBA 32bit texture will take 64MB (without mipmaps). and the last. to avoid sharp edges on textures seams, first switch them to clamp instead of repeat, second - make a 1-pixel border same on seamed textures (so top pixel row on bottom texture should be same as bottom pixel row on top texture and so on)

–

is this error always occurs on 11s loading? try to load different images without any associating with material?

–

without associating with material, errored. i used different images too. TextureLoader.LoadImageIntoTexture(TextureLoaded) making error. When i remove it, working (loading all images without error). i used TextureLoaded.Resize instead of it but same. If i keep without DXT1, memory problem. (After ~4GB memory in use or over ~1.2GB ie memory, giving error. Yeah i have more memory and 64 bit pc) strange but i added "yield return new WaitForSeconds(3);" after this code it loaded up to 16 then errored.

–

If i change it to clamp, only 1 texture normal others getting one color. So i cant choose clamp i think it req divide sphere to objects. Currently one object and 18 material. If i divide it to 18 sphere part. It will get smoothing problem.

Shader:

Shader "Custom/Planet" {
	Properties {
		_MainTex11 ("Texture 1 1", 2D) = "white" {}
		_MainTex12 ("Texture 1 2", 2D) = "white" {}
		_MainTex13 ("Texture 1 3", 2D) = "white" {}
		_MainTex21 ("Texture 2 1", 2D) = "white" {}
		_MainTex22 ("Texture 2 2", 2D) = "white" {}
		_MainTex23 ("Texture 2 3", 2D) = "white" {}
		_MainTex31 ("Texture 3 1", 2D) = "white" {}
		_MainTex32 ("Texture 3 2", 2D) = "white" {}
		_MainTex33 ("Texture 3 3", 2D) = "white" {}
		_MainTex41 ("Texture 4 1", 2D) = "white" {}
		_MainTex42 ("Texture 4 2", 2D) = "white" {}
		_MainTex43 ("Texture 4 3", 2D) = "white" {}
		_MainTex51 ("Texture 5 1", 2D) = "white" {}
		_MainTex52 ("Texture 5 2", 2D) = "white" {}
		_MainTex53 ("Texture 5 3", 2D) = "white" {}
		_MainTex61 ("Texture 6 1", 2D) = "white" {}
		_MainTex62 ("Texture 6 2", 2D) = "white" {}
		_MainTex63 ("Texture 6 3", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex11;
		sampler2D _MainTex12;
		sampler2D _MainTex13;
		sampler2D _MainTex21;
		sampler2D _MainTex22;
		sampler2D _MainTex23;
		sampler2D _MainTex31;
		sampler2D _MainTex32;
		sampler2D _MainTex33;
		sampler2D _MainTex41;
		sampler2D _MainTex42;
		sampler2D _MainTex43;
		sampler2D _MainTex51;
		sampler2D _MainTex52;
		sampler2D _MainTex53;
		sampler2D _MainTex61;
		sampler2D _MainTex62;
		sampler2D _MainTex63;

		struct Input {
			float2 uv_MainTex11;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			if (IN.uv_MainTex11.x >= 5.0/6.0) {
				if (IN.uv_MainTex11.y >= 2.0/3.0) {
					o.Albedo = tex2D (_MainTex61, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else if (IN.uv_MainTex11.y >= 1.0/3.0) {
					o.Albedo = tex2D (_MainTex62, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else {
					o.Albedo = tex2D (_MainTex63, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
			}
			else if (IN.uv_MainTex11.x >= 4.0/6.0) {
				if (IN.uv_MainTex11.y >= 2.0/3.0) {
					o.Albedo = tex2D (_MainTex51, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else if (IN.uv_MainTex11.y >= 1.0/3.0) {
					o.Albedo = tex2D (_MainTex52, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else {
					o.Albedo = tex2D (_MainTex53, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
			}
			else if (IN.uv_MainTex11.x >= 3.0/6.0) {
				if (IN.uv_MainTex11.y >= 2.0/3.0) {
					o.Albedo = tex2D (_MainTex41, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else if (IN.uv_MainTex11.y >= 1.0/3.0) {
					o.Albedo = tex2D (_MainTex42, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else {
					o.Albedo = tex2D (_MainTex43, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
			}
			else if (IN.uv_MainTex11.x >= 2.0/6.0) {
				if (IN.uv_MainTex11.y >= 2.0/3.0) {
					o.Albedo = tex2D (_MainTex31, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else if (IN.uv_MainTex11.y >= 1.0/3.0) {
					o.Albedo = tex2D (_MainTex32, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else {
					o.Albedo = tex2D (_MainTex33, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
			}
			else if (IN.uv_MainTex11.x >= 1.0/6.0) {
				if (IN.uv_MainTex11.y >= 2.0/3.0) {
					o.Albedo = tex2D (_MainTex21, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else if (IN.uv_MainTex11.y >= 1.0/3.0) {
					o.Albedo = tex2D (_MainTex22, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else {
					o.Albedo = tex2D (_MainTex23, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
			}
			else {
				if (IN.uv_MainTex11.y >= 2.0/3.0) {
					o.Albedo = tex2D (_MainTex11, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else if (IN.uv_MainTex11.y >= 1.0/3.0) {
					o.Albedo = tex2D (_MainTex12, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
				else {
					o.Albedo = tex2D (_MainTex13, IN.uv_MainTex11 * float2(6.0, 3.0)).rgb;
				}
			}
		}
		ENDCG
	}
	FallBack "Diffuse"
}

Inspired by this code snippet, I created a surface shader to put four 4096x2048 textures on a sphere. It does only work with texture mode repeat, and along the borders of the textures occurs a dividing line. Any way to get around this? Or is multi-sub material the only way?

–

Final Answer:
Using multi-sub material better then shader.
Always use power of 2 sized textures for less size. (Bigger size for less size :wink:

As i found “Do not download big images dynamically” because no runtime compression.
Sure there is a function “Texture2D.Compress” but not enough.

I will load DDS file instead of jpg (DXT1 compressed texture). I will take care of its size with some other methods.

Btw again ScroodgeM thanks for help.

PS did you check you video memory usage? textures in VRAM are always stored uncompressed, and texture 4Kx4Kx32bit with mipmaps will take about 85 MB of VRAM. 18 textures 85 MB each means 1.5GB of VRAM... r u sure you and all users have such size?

–