Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Custom Shader blending problems - help required..

Discussion in 'Shaders' started by ciprianbiris, Jul 3, 2014.

  1. ciprianbiris

    ciprianbiris

    Joined:
    Oct 11, 2013
    Posts:
    32
    Hi. I wrote a Shader and I have an annoying issue:

    Rendering is perfect with an Intel HD Card 4600 but wrong with GTX 780M.
    What I try to do is blend 5 different passes in a surface shader for combining a total of 64 small texture.
    I do this because Texture Atlas would bring bleeding and without MipMaps I would have moire effect.
    What am I doing wrong?

    Here is the shader code:
    Code (CSharp):
    1. Shader "Custom/light" {
    2. Properties
    3. {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _Tx1 ("Texture 1", 2D) = "white" {}
    6.     _Tx2 ("Texture 2", 2D) = "white" {}
    7.     _Tx3 ("Texture 3", 2D) = "white" {}
    8.     _Tx4 ("Texture 4", 2D) = "white" {}
    9.     _Tx5 ("Texture 5", 2D) = "white" {}
    10.     _Tx6 ("Texture 6", 2D) = "white" {}
    11.     _Tx7 ("Texture 7", 2D) = "white" {}
    12.     _Tx8 ("Texture 8", 2D) = "white" {}
    13.     _Tx9 ("Texture 9", 2D) = "white" {}
    14.     _Tx10 ("Texture 10", 2D) = "white" {}
    15.     _Tx11 ("Texture 11", 2D) = "white" {}
    16.     _Tx12 ("Texture 12", 2D) = "white" {}
    17.     _Tx13 ("Texture 13", 2D) = "white" {}
    18.     _Tx14 ("Texture 14", 2D) = "white" {}
    19.     _Tx15 ("Texture 15", 2D) = "white" {}
    20.     _Tx16 ("Texture 16", 2D) = "white" {}
    21.     _Tx17 ("Texture 17", 2D) = "white" {}
    22.     _Tx18 ("Texture 18", 2D) = "white" {}
    23.     _Tx19 ("Texture 19", 2D) = "white" {}
    24.     _Tx20 ("Texture 20", 2D) = "white" {}
    25.     _Tx21 ("Texture 21", 2D) = "white" {}
    26.     _Tx22 ("Texture 22", 2D) = "white" {}
    27.     _Tx23 ("Texture 23", 2D) = "white" {}
    28.     _Tx24 ("Texture 24", 2D) = "white" {}
    29.     _Tx25 ("Texture 25", 2D) = "white" {}
    30.     _Tx26 ("Texture 26", 2D) = "white" {}
    31.     _Tx27 ("Texture 27", 2D) = "white" {}
    32.     _Tx28 ("Texture 28", 2D) = "white" {}
    33.     _Tx29 ("Texture 29", 2D) = "white" {}
    34.     _Tx30 ("Texture 30", 2D) = "white" {}
    35.     _Tx31 ("Texture 31", 2D) = "white" {}
    36.     _Tx32 ("Texture 32", 2D) = "white" {}
    37.     _Tx33 ("Texture 33", 2D) = "white" {}
    38.     _Tx34 ("Texture 34", 2D) = "white" {}
    39.     _Tx35 ("Texture 35", 2D) = "white" {}
    40.     _Tx36 ("Texture 36", 2D) = "white" {}
    41.     _Tx37 ("Texture 37", 2D) = "white" {}
    42.     _Tx38 ("Texture 38", 2D) = "white" {}
    43.     _Tx39 ("Texture 39", 2D) = "white" {}
    44.     _Tx40 ("Texture 40", 2D) = "white" {}
    45.     _Tx41 ("Texture 41", 2D) = "white" {}
    46.     _Tx42 ("Texture 42", 2D) = "white" {}
    47.     _Tx43 ("Texture 43", 2D) = "white" {}
    48.     _Tx44 ("Texture 44", 2D) = "white" {}
    49.     _Tx45 ("Texture 45", 2D) = "white" {}
    50.     _Tx46 ("Texture 46", 2D) = "white" {}
    51.     _Tx47 ("Texture 47", 2D) = "white" {}
    52.     _Tx48 ("Texture 48", 2D) = "white" {}
    53.     _Tx49 ("Texture 49", 2D) = "white" {}
    54.     _Tx50 ("Texture 50", 2D) = "white" {}
    55.     _Tx51 ("Texture 51", 2D) = "white" {}
    56.     _Tx52 ("Texture 52", 2D) = "white" {}
    57.     _Tx53 ("Texture 53", 2D) = "white" {}
    58.     _Tx54 ("Texture 54", 2D) = "white" {}
    59.     _Tx55 ("Texture 55", 2D) = "white" {}
    60.     _Tx56 ("Texture 56", 2D) = "white" {}
    61.     _Tx57 ("Texture 57", 2D) = "white" {}
    62.     _Tx58 ("Texture 58", 2D) = "white" {}
    63.     _Tx59 ("Texture 59", 2D) = "white" {}
    64.     _Tx60 ("Texture 60", 2D) = "white" {}
    65.     _Tx61 ("Texture 61", 2D) = "white" {}
    66.     _Tx62 ("Texture 62", 2D) = "white" {}
    67.     _Tx63 ("Texture 63", 2D) = "white" {}
    68.     _Tx64 ("Texture 64", 2D) = "white" {}
    69. }
    70. SubShader {
    71.     Tags { "RenderType"="Opaque" }
    72.     LOD 200
    73.    
    74.  
    75.  
    76. //Blend DstColor Zero    
    77.  
    78. CGPROGRAM
    79. #pragma surface surf Lambert
    80. #pragma target 3.0  
    81.  
    82.  
    83. sampler2D _Tx1;
    84. sampler2D _Tx2;
    85. sampler2D _Tx3;
    86. sampler2D _Tx4;
    87. sampler2D _Tx5;
    88. sampler2D _Tx6;
    89. sampler2D _Tx7;
    90. sampler2D _Tx8;
    91. sampler2D _Tx9;
    92. sampler2D _Tx10;
    93. sampler2D _Tx11;
    94. sampler2D _Tx12;
    95. sampler2D _Tx13;
    96.  
    97. fixed4 _Color;
    98.  
    99.  
    100. struct Input {
    101.     float2 uv_Tx1;
    102.     float2 uv2_Tx2;
    103. };
    104.  
    105. void surf (Input IN, inout SurfaceOutput o) {
    106.     float blockID = IN.uv2_Tx2.x;
    107.     //fixed4 c = tex2D(_Tx1, IN.uv_MainTex) * _Color;
    108.     fixed4 c=0.0f;
    109.    
    110.     if (blockID==1)
    111.     {
    112.     c = tex2D(_Tx1, IN.uv_Tx1) * _Color;
    113.     }
    114.     if (blockID==2)
    115.     {
    116.     c = tex2D(_Tx2, IN.uv_Tx1) * _Color;
    117.     }
    118.     if (blockID==3)
    119.     {
    120.     c = tex2D(_Tx3, IN.uv_Tx1) * _Color;
    121.     }
    122.     if (blockID==4)
    123.     {
    124.     c = tex2D(_Tx4, IN.uv_Tx1) * _Color;
    125.     }
    126.     if (blockID==5)
    127.     {
    128.     c = tex2D(_Tx5, IN.uv_Tx1) * _Color;
    129.     }
    130.     if (blockID==6)
    131.     {
    132.     c = tex2D(_Tx6, IN.uv_Tx1) * _Color;
    133.     }
    134.     if (blockID==7)
    135.     {
    136.     c = tex2D(_Tx7, IN.uv_Tx1) * _Color;
    137.     }
    138.     if (blockID==8)
    139.     {
    140.     c = tex2D(_Tx8, IN.uv_Tx1) * _Color;
    141.     }
    142.     if (blockID==9)
    143.     {
    144.     c = tex2D(_Tx9, IN.uv_Tx1) * _Color;
    145.     }
    146.     if (blockID==10)
    147.     {
    148.     c = tex2D(_Tx10, IN.uv_Tx1) * _Color;
    149.     }
    150.     if (blockID==11)
    151.     {
    152.     c = tex2D(_Tx11, IN.uv_Tx1) * _Color;
    153.     }
    154.     if (blockID==12)
    155.     {
    156.     c = tex2D(_Tx12, IN.uv_Tx1) * _Color;
    157.     }
    158.     if (blockID==13)
    159.     {
    160.     c = tex2D(_Tx13, IN.uv_Tx1) * _Color;
    161.     }
    162.     o.Albedo = c.rgb;
    163.     o.Alpha = c.a;
    164.  
    165. }
    166. ENDCG
    167.  
    168. //Blend One One
    169. //Blend One One
    170. Blend SrcAlpha OneMinusSrcAlpha
    171.  
    172. CGPROGRAM
    173. #pragma surface surf Lambert
    174. #pragma target 3.0  
    175.  
    176.  
    177. sampler2D _Tx14;
    178. sampler2D _Tx15;
    179. sampler2D _Tx16;
    180. sampler2D _Tx17;
    181. sampler2D _Tx18;
    182. sampler2D _Tx19;
    183. sampler2D _Tx20;
    184. sampler2D _Tx21;
    185. sampler2D _Tx22;
    186. sampler2D _Tx23;
    187. sampler2D _Tx24;
    188. sampler2D _Tx25;
    189. sampler2D _Tx26;
    190.  
    191. fixed4 _Color;
    192.  
    193.  
    194. struct Input {
    195.     float2 uv_Tx14;
    196.     float2 uv2_Tx15;
    197. };
    198.  
    199. void surf (Input IN, inout SurfaceOutput o) {
    200.     float blockID = IN.uv2_Tx15.x;
    201.     //fixed4 c = tex2D(_Tx1, IN.uv_MainTex) * _Color;
    202.     fixed4 c=0.0f;
    203.     if (blockID==14)
    204.     {
    205.     c = tex2D(_Tx14, IN.uv_Tx14) * _Color;
    206.     }
    207.     if (blockID==15)
    208.     {
    209.     c = tex2D(_Tx15, IN.uv_Tx14) * _Color;
    210.     }
    211.     if (blockID==16)
    212.     {
    213.     c = tex2D(_Tx16, IN.uv_Tx14) * _Color;
    214.     }
    215.     if (blockID==17)
    216.     {
    217.     c = tex2D(_Tx17, IN.uv_Tx14) * _Color;
    218.     }
    219.     if (blockID==18)
    220.     {
    221.     c = tex2D(_Tx18, IN.uv_Tx14) * _Color;
    222.     }
    223.     if (blockID==19)
    224.     {
    225.     c = tex2D(_Tx19, IN.uv_Tx14) * _Color;
    226.     }
    227.     if (blockID==20)
    228.     {
    229.     c = tex2D(_Tx20, IN.uv_Tx14) * _Color;
    230.     }
    231.     if (blockID==21)
    232.     {
    233.     c = tex2D(_Tx21, IN.uv_Tx14) * _Color;
    234.     }
    235.     if (blockID==22)
    236.     {
    237.     c = tex2D(_Tx22, IN.uv_Tx14) * _Color;
    238.     }
    239.     if (blockID==23)
    240.     {
    241.     c = tex2D(_Tx23, IN.uv_Tx14) * _Color;
    242.     }
    243.     if (blockID==24)
    244.     {
    245.     c = tex2D(_Tx24, IN.uv_Tx14) * _Color;
    246.     }
    247.     if (blockID==25)
    248.     {
    249.     c = tex2D(_Tx25, IN.uv_Tx14) * _Color;
    250.     }
    251.     if (blockID==26)
    252.     {
    253.     c = tex2D(_Tx26, IN.uv_Tx14) * _Color;
    254.     }
    255.     o.Albedo = c.rgb;
    256.     o.Alpha = c.a;
    257.  
    258. }
    259. ENDCG
    260.  
    261. //Blend One One
    262.  
    263. CGPROGRAM
    264. #pragma surface surf Lambert
    265. #pragma target 3.0  
    266.  
    267.  
    268. sampler2D _Tx27;
    269. sampler2D _Tx28;
    270. sampler2D _Tx29;
    271. sampler2D _Tx30;
    272. sampler2D _Tx31;
    273. sampler2D _Tx32;
    274. sampler2D _Tx33;
    275. sampler2D _Tx34;
    276. sampler2D _Tx35;
    277. sampler2D _Tx36;
    278. sampler2D _Tx37;
    279. sampler2D _Tx38;
    280. sampler2D _Tx39;
    281.  
    282. fixed4 _Color;
    283.  
    284.  
    285. struct Input {
    286.     float2 uv_Tx27;
    287.     float2 uv2_Tx28;
    288. };
    289.  
    290. void surf (Input IN, inout SurfaceOutput o) {
    291.     float blockID = IN.uv2_Tx28.x;
    292.     //fixed4 c = tex2D(_Tx1, IN.uv_MainTex) * _Color;
    293.     fixed4 c=0.0f;
    294.     if (blockID==27)
    295.     {
    296.     c = tex2D(_Tx27, IN.uv_Tx27) * _Color;
    297.     }
    298.     if (blockID==28)
    299.     {
    300.     c = tex2D(_Tx28, IN.uv_Tx27) * _Color;
    301.     }
    302.     if (blockID==29)
    303.     {
    304.     c = tex2D(_Tx29, IN.uv_Tx27) * _Color;
    305.     }
    306.     if (blockID==30)
    307.     {
    308.     c = tex2D(_Tx30, IN.uv_Tx27) * _Color;
    309.     }
    310.     if (blockID==31)
    311.     {
    312.     c = tex2D(_Tx31, IN.uv_Tx27) * _Color;
    313.     }
    314.     if (blockID==32)
    315.     {
    316.     c = tex2D(_Tx32, IN.uv_Tx27) * _Color;
    317.     }
    318.     if (blockID==33)
    319.     {
    320.     c = tex2D(_Tx33, IN.uv_Tx27) * _Color;
    321.     }
    322.     if (blockID==34)
    323.     {
    324.     c = tex2D(_Tx34, IN.uv_Tx27) * _Color;
    325.     }
    326.     if (blockID==35)
    327.     {
    328.     c = tex2D(_Tx35, IN.uv_Tx27) * _Color;
    329.     }
    330.     if (blockID==36)
    331.     {
    332.     c = tex2D(_Tx36, IN.uv_Tx27) * _Color;
    333.     }
    334.     if (blockID==37)
    335.     {
    336.     c = tex2D(_Tx37, IN.uv_Tx27) * _Color;
    337.     }
    338.     if (blockID==38)
    339.     {
    340.     c = tex2D(_Tx38, IN.uv_Tx27) * _Color;
    341.     }
    342.     if (blockID==39)
    343.     {
    344.     c = tex2D(_Tx39, IN.uv_Tx27) * _Color;
    345.     }
    346.     o.Albedo = c.rgb;
    347.     o.Alpha = c.a;
    348.  
    349. }
    350. ENDCG
    351.  
    352. //Blend One One
    353.  
    354. CGPROGRAM
    355. #pragma surface surf Lambert
    356. #pragma target 3.0  
    357.  
    358.  
    359. sampler2D _Tx40;
    360. sampler2D _Tx41;
    361. sampler2D _Tx42;
    362. sampler2D _Tx43;
    363. sampler2D _Tx44;
    364. sampler2D _Tx45;
    365. sampler2D _Tx46;
    366. sampler2D _Tx47;
    367. sampler2D _Tx48;
    368. sampler2D _Tx49;
    369. sampler2D _Tx50;
    370. sampler2D _Tx51;
    371. sampler2D _Tx52;
    372.  
    373. fixed4 _Color;
    374.  
    375.  
    376. struct Input {
    377.     float2 uv_Tx40;
    378.     float2 uv2_Tx41;
    379. };
    380.  
    381. void surf (Input IN, inout SurfaceOutput o) {
    382.     float blockID = IN.uv2_Tx41.x;
    383.     //fixed4 c = tex2D(_Tx1, IN.uv_MainTex) * _Color;
    384.     fixed4 c=0.0f;
    385.     if (blockID==40)
    386.     {
    387.     c = tex2D(_Tx40, IN.uv_Tx40) * _Color;
    388.     }
    389.     if (blockID==41)
    390.     {
    391.     c = tex2D(_Tx41, IN.uv_Tx40) * _Color;
    392.     }
    393.     if (blockID==42)
    394.     {
    395.     c = tex2D(_Tx42, IN.uv_Tx40) * _Color;
    396.     }
    397.     if (blockID==43)
    398.     {
    399.     c = tex2D(_Tx43, IN.uv_Tx40) * _Color;
    400.     }
    401.     if (blockID==44)
    402.     {
    403.     c = tex2D(_Tx44, IN.uv_Tx40) * _Color;
    404.     }
    405.     if (blockID==45)
    406.     {
    407.     c = tex2D(_Tx45, IN.uv_Tx40) * _Color;
    408.     }
    409.     if (blockID==46)
    410.     {
    411.     c = tex2D(_Tx46, IN.uv_Tx40) * _Color;
    412.     }
    413.     if (blockID==47)
    414.     {
    415.     c = tex2D(_Tx47, IN.uv_Tx40) * _Color;
    416.     }
    417.     if (blockID==48)
    418.     {
    419.     c = tex2D(_Tx48, IN.uv_Tx40) * _Color;
    420.     }
    421.     if (blockID==49)
    422.     {
    423.     c = tex2D(_Tx49, IN.uv_Tx40) * _Color;
    424.     }
    425.     if (blockID==50)
    426.     {
    427.     c = tex2D(_Tx50, IN.uv_Tx40) * _Color;
    428.     }
    429.     if (blockID==51)
    430.     {
    431.     c = tex2D(_Tx51, IN.uv_Tx40) * _Color;
    432.     }
    433.     if (blockID==52)
    434.     {
    435.     c = tex2D(_Tx52, IN.uv_Tx40) * _Color;
    436.     }
    437.     o.Albedo = c.rgb;
    438.     o.Alpha = c.a;
    439.  
    440. }
    441. ENDCG
    442.  
    443. //Blend One One
    444.  
    445. CGPROGRAM
    446. #pragma surface surf Lambert
    447. #pragma target 3.0  
    448.  
    449.  
    450. sampler2D _Tx53;
    451. sampler2D _Tx54;
    452. sampler2D _Tx55;
    453. sampler2D _Tx56;
    454. sampler2D _Tx57;
    455. sampler2D _Tx58;
    456. sampler2D _Tx59;
    457. sampler2D _Tx60;
    458. sampler2D _Tx61;
    459. sampler2D _Tx62;
    460. sampler2D _Tx63;
    461. sampler2D _Tx64;
    462. sampler2D _Tx65;
    463.  
    464. fixed4 _Color;
    465.  
    466.  
    467. struct Input {
    468.     float2 uv_Tx53;
    469.     float2 uv2_Tx54;
    470. };
    471.  
    472. void surf (Input IN, inout SurfaceOutput o) {
    473.     float blockID = IN.uv2_Tx54.x;
    474.     //fixed4 c = tex2D(_Tx1, IN.uv_MainTex) * _Color;
    475.     fixed4 c=0.0f;
    476.     if (blockID==53)
    477.     {
    478.     c = tex2D(_Tx53, IN.uv_Tx53) * _Color;
    479.     }
    480.     if (blockID==54)
    481.     {
    482.     c = tex2D(_Tx54, IN.uv_Tx53) * _Color;
    483.     }
    484.     if (blockID==55)
    485.     {
    486.     c = tex2D(_Tx55, IN.uv_Tx53) * _Color;
    487.     }
    488.     if (blockID==56)
    489.     {
    490.     c = tex2D(_Tx56, IN.uv_Tx53) * _Color;
    491.     }
    492.     if (blockID==57)
    493.     {
    494.     c = tex2D(_Tx57, IN.uv_Tx53) * _Color;
    495.     }
    496.     if (blockID==58)
    497.     {
    498.     c = tex2D(_Tx58, IN.uv_Tx53) * _Color;
    499.     }
    500.     if (blockID==59)
    501.     {
    502.     c = tex2D(_Tx59, IN.uv_Tx53) * _Color;
    503.     }
    504.     if (blockID==60)
    505.     {
    506.     c = tex2D(_Tx60, IN.uv_Tx53) * _Color;
    507.     }
    508.     if (blockID==61)
    509.     {
    510.     c = tex2D(_Tx61, IN.uv_Tx53) * _Color;
    511.     }
    512.     if (blockID==62)
    513.     {
    514.     c = tex2D(_Tx62, IN.uv_Tx53) * _Color;
    515.     }
    516.     if (blockID==63)
    517.     {
    518.     c = tex2D(_Tx63, IN.uv_Tx53) * _Color;
    519.     }
    520.     if (blockID==64)
    521.     {
    522.     c = tex2D(_Tx64, IN.uv_Tx53) * _Color;
    523.     }
    524.     o.Albedo = c.rgb;
    525.     o.Alpha = c.a;
    526.  
    527. }
    528. ENDCG
    529.  
    530. //Pass: Surface SHADER
    531.   //    ZWrite Off
    532.     //  ZTest Greater
    533.     //  Blend DstColor Zero
    534. }
    535.  
    536. //Fallback "VertexLit"
    537. }
    538.  
    Here is it rendered with my Intel HD card:

    Here it is rendered with my GTX 780M
     
  2. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    thats a HEAVILY non-optimized shader

    you can eliminate the bleeding problem by using padding around each texture

    i'm not sure whats going on with it now but i wouldn't be surprise if it had anything to do with the multiple textures, samples and conditional logic you have there
     
  3. ciprianbiris

    ciprianbiris

    Joined:
    Oct 11, 2013
    Posts:
    32
    I found the problem:
    replacing:
    if (blockID==1)
    with:
    if ((blockID>=0.99) && (blockID<1.01))

    solved it.
    Can you tell me how I could optimize this shader?
    Regarding bleeding, the only way to remove it completely is using this shader. All other methods did not give good enough results.
     
  4. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    it's a common technique when using sprite sheets, you simply pack the textures together but you leave a margin of pixels between each sprite, the margin amount will depend on what will it be used for, from my tests usually a margin of 1px is okay when not using mips, then you'll want to increase this margin exponentially to the number of mips you'll be using

    to be honest i'm more interested in how are you feeding the shader with the block ids, are you able to batch the cubes together? because if you aren't there's really no point in trying to have all the texture in just one shader

    conditional logic is a bit dangerous to use in a shader, the ideal case you want to have a predictable system, usually i manage to do it with step() lerp() or simply using multiplicative calculations to get what i want out of values

    [edit]
    I just remembered, you can/should also bleed the color over the edges kinda like this technique for the leaves here: http://docs.unity3d.com/Manual/HOWTO-alphamaps.html
     
  5. ciprianbiris

    ciprianbiris

    Joined:
    Oct 11, 2013
    Posts:
    32
    hi. thank you for your reply.
    yes, I batch the cubes together in chunks and the chunks are the game objects. Each chunk is 16x16x128, From what I saw, if I use for example a texture atlas of 8x8 textures and each texture is 128x128, I will have 4 MipMaps which would have the texture for one cube in sub-pixel range - no matter how much padding, no matter how much filtering, steep angles would result into bleeding. the solution here is to feed the block IDs into the shader and feed all 64 small textures of 128x128.
    the block ID is fed into the shader.. via the second uv set :) . I just set the x component of the UV2 to the block ID in the scripts. I now improved a little the switching of cases by including "return" and checking for each section in the shader if I should compare the cases or not.
    In the future I plan to use one texture and shift the color so I could have 8-16 blocks for only one texture. For example, 16 or 32 colors of wool. that would be relatively "cheap" to do in the shader. 64 independent blocks is "fine" for my HD 4600 and definitely fine for GTX 780m.
    I think that by using for example 2-3 textures and blending between them and adding the color in the shader could give me a lot of cubes for different rocks for example. but that is something to think of in the future. I would not use the conditional if I could make an array or 2d samplers and then just use something like:
    c = tex2D(_Tx(blockID), IN.uv_Tx14)* _Color;
    Stil, I am limited to 13 samplers (i know in total 16 but 3 of them seem to be used by unity) so I need to still make those sections.. (except for the case I generate multiple blocks from one small texture).
     
  6. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    there's something i don't get it

    If you had a 32x32 square of pixels and gave it a 1 pixel padding around it and that same padding had the the pixels from the 32x32 extended or repeated (for seamless textures) would it still cause any bleed?

    The interpolation would pick the pixel from the padding and the rendering would stay okay, this should be true for higher dimension textures with higher padding

    This actually reminds me of 2d toolkit that has this very feature to remove the bleeding from the sprites, there you can even pick how the bleeding occurs.

    This way you could have it spend only one sampler and you would simply align the faces uvs to their respective place, this is even how minecraft does it and while they don't have any filtering to worry about it proves how efficient it is, not only in terms of performance but also in terms of "expandability"
     
  7. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589


    Yeah and there's the problem... 1px border is good for the first mip-level, sadly you need another 2px to fully cover the next, another 4px for the next and now you're only at mip level 3 out of perhaps 9 or 10.

    And computing the right texcoords to sample at each level becomes exponentially more painful :D

    Atlasing is still neat though, and tiling atlased-sprites is still worth it even with the tiny (once you get the sampling right which took me over a week the first time I tackled it) seams, if you sprinkle a little local noise over it or do some uv-mixing all the better but you won't get completely "seamless". Unless you add the significant border as you suggest, well actually.... might be totally worth it now that I'm pondering this topic once again :D
     
  8. ciprianbiris

    ciprianbiris

    Joined:
    Oct 11, 2013
    Posts:
    32
    no matter how much padding you do, you still end up in sub-pixel range and you get errors at steep angles. believe me, I tried everything up to nvidia texture tools..
    perhaps if you use fog and if you do some noise, you get rid of it.
    honestly, the game still runs smooth with this shader.
    in minecraft no matter how steep the angle is or how far away you are, the textures render correctly. this proves that they do not loose information on sub-pixel range hence they don't use a texture atlas.
    or, they use one and limit the number of mip-maps. I tried that in Unity3d.. I made the texture with Nvidia Texture Tools and I eliminated the sub-pixel range mip-maps but it still did not work. nothing renders anymore.
    only working method with the atlas is to set the sub-pixel mip-maps to a neutral color (gray works well).
     
  9. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    notch publicly said he hated mipmaps so my guess is he isn't using it

    it's true that the padding increases with power of two, i still believe it's worth it

    it doesn't matter if you end in the subpixel range if that range has the information you need, so it's doesn't matter if it bleeds as long as it's bleeding right, thats the idea of filling the padding with the texture itself. but whatever floats your boat, if it's working for you then its fine