Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Farfarer is a genius: triplanar projection on built-in terrain

Discussion in 'Made With Unity' started by PrimeDerektive, Dec 1, 2011.

  1. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Well, that seems to narrow it down a bit, thanks.

    I'll have a look around the net and see if there are any similar problems with fixes...
     
  2. Westmark

    Westmark

    Joined:
    Nov 1, 2009
    Posts:
    187
    Hey

    The shader is awesome, I did a tri-planer shader once but never thought of implementing it with the terrain system.

    I do have a slight problem tho. It's nice that you've implementet lightmaps as well, but it seems it doesn't behave the same way the unity standard shaders does:



    This is my terrain with the basemap distance turned down fairly low, and as you can see it's a fair bit lighter with the standard shader.

    Otherwise great work! Keep it up!

    EDIT:

    There also seems to be some unity weirdness going on, I use two directional lights (one sun, and an opposite blue tinted one), and depending on which order I turn them on in the terrain receives different shading. (weird I know, even with both lights off and lightmaps off, it still receives faint shading from the last light that was on. I have to load another scene and then reload the scene to get rid of it).

    EDIT EDIT:

    Does the shader only work with one light source at a time?, cuz that might explain some of it.
     
    Last edited: Dec 12, 2011
  3. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Just to add to the data (and I'll test if you need it) this is from my old mac book:



    Hardware Overview:

    Model Name: MacBook Pro
    Model Identifier: MacBookPro3,1
    Processor Name: Intel Core 2 Duo
    Processor Speed: 2.4 GHz
    Number Of Processors: 1
    Total Number Of Cores: 2
    L2 Cache: 4 MB
    Memory: 4 GB
    Bus Speed: 800 MHz
    Boot ROM Version: MBP31.0070.B07
    SMC Version (system): 1.16f11
    Serial Number (system): W87392NUXAG
    Hardware UUID: 00000000-0000-1000-8000-001B639171C5
    Sudden Motion Sensor:
    State: Enabled

    NVIDIA GeForce 8600M GT:

    Chipset Model: GeForce 8600M GT
    Type: GPU
    Bus: PCIe
    PCIe Lane Width: x16
    VRAM (Total): 256 MB
    Vendor: NVIDIA (0x10de)
    Device ID: 0x0407
    Revision ID: 0x00a1
    ROM Revision: 3175
    Displays:
    Color LCD:
    Resolution: 1440 x 900
    Pixel Depth: 32-Bit Color (ARGB8888)
    Main Display: Yes
    Mirror: Off
    Online: Yes
    Built-In: Yes
    Display Connector:
    Status: No Display Connected
     
  4. d123s404

    d123s404

    Joined:
    Apr 2, 2011
    Posts:
    32
    None of them seem to work. Is it Unity Pro only?
     
  5. Shad

    Shad

    Joined:
    Sep 21, 2011
    Posts:
    61
    Please also make sure it supports substances too! That would be very important for the project I'm working on!

    Thanks
     
  6. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Btw is it just me or when using this shader lightmap baking took longer than usual?
     
  7. Westmark

    Westmark

    Joined:
    Nov 1, 2009
    Posts:
    187
    I'll try and reproduce that tomorrow, could be related to the lightmap issues I'm experiencing.
     
  8. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    So how did it goes? when i'm using standard shader it's only takes minutes to bake with 3-4 resolution, but with this shader it's almost an hour.
     
  9. Westmark

    Westmark

    Joined:
    Nov 1, 2009
    Posts:
    187
    Can't really see any difference here, certainly not anything like minutes versus hours like you're experiencing.
     
  10. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I haven't noticed a difference in lightmap baking times, either.

    Perhaps try setting up the terrain values as you like them, then disable the tri-planar script, bake the lightmap, then enable the script.

    The script re-applies the settings every editorGUI frame (because I don't know of any other way to do it) so it could be that interfering somehow?
     
  11. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Hmm i see... i'll try it.
     
  12. fremachuca

    fremachuca

    Joined:
    Oct 13, 2010
    Posts:
    26
    hey there farfarer. any news on this awesome shader?
     
  13. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Nothing yet. I've been working on my own game and portfolio stuff lately, sorry.

    Too much to do at once :p
     
  14. Demostenes

    Demostenes

    Joined:
    Sep 10, 2010
    Posts:
    1,106
    So this mean, that i can have only 8 textures for whole scene (all terrains there)?
     
  15. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Yes.

    Sadly I can't seem to get access to the shader's individual materials so I've no idea how to set it up per terrain object :/
     
  16. WarpedAxiom

    WarpedAxiom

    Joined:
    Oct 27, 2006
    Posts:
    245
    I think eight textures should be quite enough for a single terrain. I'm just hoping/praying you'll get this working on Mac. I have the same blackness issue.
     
  17. Demostenes

    Demostenes

    Joined:
    Sep 10, 2010
    Posts:
    1,106
    Sure, for single terrain yes. Not for 24.
     
  18. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Well if you can find a way to access the materials, I'll put it in the shader :p
     
  19. Syanyde

    Syanyde

    Joined:
    Jan 4, 2011
    Posts:
    57
    Can't believe I didn't find this thread sooner!

    I'd been having a few ideas for tri-planar shading after reading about it in a Voxel terrain article on NVidia's site and was going to attempt it to see if I could use it to get rid of texture stretching on terrains and possibly so I could disregard UV mapping for procedural cave generation, etc. (It may also be helpful to fix some artifacts I noticed in the textures of a Voxel terrain demo I've seen in another thread here recently too).

    Anyway, nice work, thanks for sharing it. :)
     
  20. KRGraphics

    KRGraphics

    Joined:
    Jan 5, 2010
    Posts:
    4,458
    Wow, I just found this thread...and this is perfect for creating my atlantis island... any progress on this package?
     
  21. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    No updates, sorry. I knocked it up quickly as a request from legend411 and then added a bit more stuff to for user friendliness I wasn't intending it as a package I maintained.

    The code's all there for anyone who wants to play around with it and fix it up some more and release it - feel free to do what you like with it. Included textures are all 100% free, too, use 'em as and where you like.

    Stuff folk might like to add;
    Calculate the tiling of the textures and apply it to the terrain so that the fallback shader lines up with the triplanar one (roughly).
    Fix the black axis stuff on Mac.
     
  22. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,350
    Is this totally compatible with Unity? I mean, lightmaps and everything?
     
  23. MarioRuiz

    MarioRuiz

    Joined:
    Nov 7, 2009
    Posts:
    161
    just HOW THE HELL did I miss this for the last year and a half??
     
  24. MacroManJr

    MacroManJr

    Joined:
    Jun 3, 2012
    Posts:
    11
    Same here! Hahaha!
     
  25. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi there,

    as many people noticed some problems on their macs here comes a version working at least on my mac book pro:


    $triplanarBump.jpg


    please note that the shader only works correctly in forward rendering. having a camera using deferred rendering you will not have smoothly fading real time shadows. also lightmapping is not supported.

    next to the shader you will need farfarer’s setup script to make the shader work.


    lars


    Code (csharp):
    1.  
    2. Shader "Hidden/TerrainEngine/Splatmap/Lightmap-FirstPass" {
    3.     Properties {
    4.         _Control ("Control (RGBA)", 2D) = "red" {}
    5.         _Splat3 ("Layer 3 (A)", 2D) = "white" {}
    6.         _Splat2 ("Layer 2 (B)", 2D) = "white" {}
    7.         _Splat1 ("Layer 1 (G)", 2D) = "white" {}
    8.         _Splat0 ("Layer 0 (R)", 2D) = "white" {}
    9.         // used in fallback on old cards
    10.         _Color ("Main Color", Color) = (1,1,1,1)
    11.         _MainTex ("Base (RGB)", 2D) = "white" {}
    12.     }
    13.     SubShader {
    14.         Tags {"SplatCount" = "4" "Queue" = "Geometry-100" "RenderType" = "Opaque"}
    15.        
    16.         CGPROGRAM
    17.             #pragma surface surf Terrain vertex:vert exclude_path:prepass nolightmap
    18.             #pragma target 3.0
    19.    
    20.             sampler2D _Control;
    21.  
    22.             struct SurfaceOutputTerrain {
    23.                 fixed3 Albedo;
    24.                 fixed3 Normal;
    25.                 fixed4 Light;
    26.                 fixed3 Emission;
    27.                 fixed Specular;
    28.                 fixed Alpha;
    29.             };
    30.  
    31.             inline fixed4 LightingTerrain (SurfaceOutputTerrain s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    32.             {
    33.                 float4 result;
    34.                 result.rgb = (s.Albedo * s.Light.x) + ( pow(s.Light.y, s.Light.w * 128) * s.Light.z );
    35.                 result.rgb *= _LightColor0.rgb * atten * 2;
    36.                 result.a = 0.0;
    37.                 return result;
    38.             }
    39.            
    40.             struct Input {
    41.                 float2  uv_Control;
    42.                 float3  worldPos;
    43.                 float3  worldNormal;
    44.                 float3  lightDir;
    45.                 float3  viewDir;
    46.             };
    47.    
    48.             void vert(inout appdata_full v, out Input o) {
    49.                 o.worldPos = mul(_Object2World, v.vertex).xyz;
    50.                 o.worldNormal = mul(_Object2World, float4(v.normal, 0.0)).xyz;
    51.                 o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
    52.                 o.viewDir = normalize(ObjSpaceViewDir(v.vertex));
    53.             }
    54.  
    55.             sampler2D _Splat0, _Splat1, _Splat2, _Splat3;
    56.             sampler2D _BumpMap0, _BumpMap1, _BumpMap2, _BumpMap3;
    57.             sampler2D _SpecMap0, _SpecMap1, _SpecMap2, _SpecMap3;
    58.             float _TerrainTexScale0, _TerrainTexScale1, _TerrainTexScale2, _TerrainTexScale3;
    59.    
    60.             void surf (Input IN, inout SurfaceOutputTerrain o) {
    61.             // INITIALISE THE CONTROL SPLAT FOR TERRAIN
    62.                 fixed4 splat_control = tex2D(_Control, IN.uv_Control);
    63.    
    64.             // INITIALISE THE VARIABLES FOR TRIPLANAR PROJECTION
    65.                 float3 worldNormal = normalize(IN.worldNormal);
    66.                 float3 projNormal = saturate(pow(worldNormal * 1.4, 4));
    67.    
    68.             // INITIALISE VARIABLES WE'LL NEED
    69.                 float3 tangent;
    70.                 float3 binormal;
    71.                 float3x3 rotation;
    72.                 float3 lightDirT;
    73.                 float3 viewDirT;
    74.                
    75.                 float2 uv;
    76.                 float2 uv0;
    77.                 float2 uv1;
    78.                 float2 uv2;
    79.                 float2 uv3;
    80.                
    81.                 float3 h;
    82.                 float4 tempNormal;
    83.                 float3 normal;
    84.                
    85.                 fixed3 albedoX;
    86.                 fixed3 albedoY;
    87.                 fixed3 albedoZ;
    88.                 fixed4 lightX;
    89.                 fixed4 lightY;
    90.                 fixed4 lightZ;
    91.    
    92.             // CALCULATE X FOR ALL
    93.            
    94.                 // UV
    95.                 uv = IN.worldPos.zy;
    96.                 uv0 = uv * _TerrainTexScale0;
    97.                 uv1 = uv * _TerrainTexScale1;
    98.                 uv2 = uv * _TerrainTexScale2;
    99.                 uv3 = uv * _TerrainTexScale3;
    100.    
    101.                 // Tangent
    102.                 tangent = float3(0, 0, 1);
    103.                
    104.                 // Light and View Vectors
    105.                 binormal = cross(worldNormal, tangent) * (step(worldNormal.x, 0) * 2 - 1);
    106.                 rotation = float3x3(tangent, binormal, worldNormal);
    107.                 lightDirT = mul(rotation, IN.lightDir);
    108.                 viewDirT = mul(rotation, IN.viewDir);
    109.                
    110.                 // Albedo
    111.                
    112.                 albedoX = tex2D(_Splat0, uv0).rgb * splat_control.r;
    113.                 albedoX += tex2D(_Splat1, uv1).rgb * splat_control.g;
    114.                 albedoX += tex2D(_Splat2, uv2).rgb * splat_control.b;
    115.                 albedoX += tex2D(_Splat3, uv3).rgb * splat_control.a;
    116.                
    117.                 // Normal
    118.                 tempNormal = tex2D (_BumpMap0, uv0) * splat_control.r;
    119.                 tempNormal += tex2D (_BumpMap1, uv1) * splat_control.g;
    120.                 tempNormal += tex2D (_BumpMap2, uv2) * splat_control.b;
    121.                 tempNormal += tex2D (_BumpMap3, uv3) * splat_control.a;
    122.                 normal = UnpackNormal(tempNormal);
    123.                
    124.                 // Specular
    125.                 lightX.zw = tex2D (_SpecMap0, uv0).rg * splat_control.r;
    126.                 lightX.zw += tex2D (_SpecMap1, uv1).rg * splat_control.g;
    127.                 lightX.zw += tex2D (_SpecMap2, uv2).rg * splat_control.b;
    128.                 lightX.zw += tex2D (_SpecMap3, uv3).rg * splat_control.a;
    129.                
    130.                 // Lighting Values
    131.                 lightX.x = saturate(dot(normal, lightDirT));
    132.                 h = normalize(lightDirT + viewDirT);
    133.                 lightX.y = saturate(dot(normal, h));
    134.    
    135.             // CALCULATE Y FOR ALL
    136.            
    137.                 // UV
    138.                 uv = IN.worldPos.xz;
    139.                 uv0 = uv * _TerrainTexScale0;
    140.                 uv1 = uv * _TerrainTexScale1;
    141.                 uv2 = uv * _TerrainTexScale2;
    142.                 uv3 = uv * _TerrainTexScale3;
    143.    
    144.                 // Tangent
    145.                 tangent = float3(1, 0, 0);
    146.                
    147.                 // Light and View Vectors
    148.                 binormal = cross(worldNormal, tangent) * (step(worldNormal.y, 0) * 2 - 1);
    149.                 rotation = float3x3(tangent, binormal, worldNormal);
    150.                 lightDirT = mul(rotation, IN.lightDir);
    151.                 viewDirT = mul(rotation, IN.viewDir);
    152.                
    153.                 // Albedo
    154.                 albedoY = tex2D(_Splat0, uv0).rgb * splat_control.r;
    155.                 albedoY += tex2D(_Splat1, uv1).rgb * splat_control.g;
    156.                 albedoY += tex2D(_Splat2, uv2).rgb * splat_control.b;
    157.                 albedoY += tex2D(_Splat3, uv3).rgb * splat_control.a;
    158.                
    159.                 // Normal
    160.                 tempNormal = tex2D (_BumpMap0, uv0) * splat_control.r;
    161.                 tempNormal += tex2D (_BumpMap1, uv1) * splat_control.g;
    162.                 tempNormal += tex2D (_BumpMap2, uv2) * splat_control.b;
    163.                 tempNormal += tex2D (_BumpMap3, uv3) * splat_control.a;
    164.                 normal = UnpackNormal(tempNormal);
    165.                
    166.                 // Specular
    167.                 lightY.zw = tex2D (_SpecMap0, uv0).rg * splat_control.r;
    168.                 lightY.zw += tex2D (_SpecMap1, uv1).rg * splat_control.g;
    169.                 lightY.zw += tex2D (_SpecMap2, uv2).rg * splat_control.b;
    170.                 lightY.zw += tex2D (_SpecMap3, uv3).rg * splat_control.a;
    171.                
    172.                 // Lighting Values
    173.                 lightY.x = saturate(dot(normal, lightDirT));
    174.                 h = normalize(lightDirT + viewDirT);
    175.                 lightY.y = saturate(dot(normal, h));
    176.    
    177.             // CALCULATE Z FOR ALL
    178.            
    179.                 // UV
    180.                 uv = IN.worldPos.xy;
    181.                 uv.x *= -1;
    182.                 uv0 = uv * _TerrainTexScale0;
    183.                 uv1 = uv * _TerrainTexScale1;
    184.                 uv2 = uv * _TerrainTexScale2;
    185.                 uv3 = uv * _TerrainTexScale3;
    186.    
    187.                 // Tangent
    188.                 tangent = float3(-1, 0, 0);
    189.                
    190.                 // Light and View Vectors
    191.                 binormal = cross(worldNormal, tangent) * (step(worldNormal.z, 0) * 2 - 1);
    192.                 rotation = float3x3(tangent, binormal, worldNormal);
    193.                 lightDirT = mul(rotation, IN.lightDir);
    194.                 viewDirT = mul(rotation, IN.viewDir);
    195.                
    196.                 // Albedo
    197.                 albedoZ = tex2D(_Splat0, uv0).rgb * splat_control.r;
    198.                 albedoZ += tex2D(_Splat1, uv1).rgb * splat_control.g;
    199.                 albedoZ += tex2D(_Splat2, uv2).rgb * splat_control.b;
    200.                 albedoZ += tex2D(_Splat3, uv3).rgb * splat_control.a;
    201.                
    202.                 // Normal
    203.                 tempNormal = tex2D (_BumpMap0, uv0) * splat_control.r;
    204.                 tempNormal += tex2D (_BumpMap1, uv1) * splat_control.g;
    205.                 tempNormal += tex2D (_BumpMap2, uv2) * splat_control.b;
    206.                 tempNormal += tex2D (_BumpMap3, uv3) * splat_control.a;
    207.                 normal = UnpackNormal(tempNormal);
    208.                
    209.                 // Specular
    210.                 lightZ.zw = tex2D (_SpecMap0, uv0).rg * splat_control.r;
    211.                 lightZ.zw += tex2D (_SpecMap1, uv1).rg * splat_control.g;
    212.                 lightZ.zw += tex2D (_SpecMap2, uv2).rg * splat_control.b;
    213.                 lightZ.zw += tex2D (_SpecMap3, uv3).rg * splat_control.a;
    214.                
    215.                 // Lighting Values
    216.                 lightZ.x = saturate(dot(normal, lightDirT));
    217.                 h = normalize(lightDirT + viewDirT);
    218.                 lightZ.y = saturate(dot(normal, h));
    219.    
    220.                
    221.                 //composition
    222.                 float3 blend_weights = abs(worldNormal);
    223.    
    224.                     // original nvidia term
    225.                     blend_weights = (blend_weights - 0.2) * 7;
    226.                     blend_weights = max(blend_weights, 0);
    227.                     blend_weights = (blend_weights) / (blend_weights.x + blend_weights.y + blend_weights.z ).xxx;
    228.                
    229.                 o.Albedo = albedoX * blend_weights.xxx + albedoY * blend_weights.yyy + albedoZ * blend_weights.zzz;
    230.                     o.Light = lightX * blend_weights.xxxx + lightY * blend_weights.yyyy + lightZ * blend_weights.zzzz;
    231.                
    232.                     o.Alpha = 0.0;
    233.             }
    234.    
    235.         ENDCG
    236.     }
    237.     Fallback "VertexLit"
    238. }
    239.  
    240.  
     
  26. TomAce

    TomAce

    Joined:
    Jan 11, 2013
    Posts:
    2
    Is there anything I can reference on how to use this?
     
  27. Steamroller

    Steamroller

    Joined:
    Jan 2, 2013
    Posts:
    71
    I was able to get rid of the black edges between splat maps by "borrowing" a bit of code from the new unity 4.0 terrain bumped specular shader

    By putting the following code into the triPlanarTerrain.shader, right before it unpacks the normals, gets rid of the black edge:

    I'm not really a shader writer, so I'm not sure why this "fixes" it, but it does.

    Before:


    After:


    Hope this helps :)
     
    Last edited: Jan 23, 2013
  28. Kubold

    Kubold

    Joined:
    May 10, 2012
    Posts:
    359
    Hey guys, This script is awesome! Is it possible to bake lightmapping with this triplanar shader script? I mean, when I bake lighmaps on my terrain, I loose normal and specular maps. It just truns to diffuse only. Do I do something wrong? I read here that it supports lightmaps...


    Update:

    "please note that the shader only works correctly in forward rendering. having a camera using deferred rendering you will not have smoothly fading real time shadows. also lightmapping is not supported."

    Is that the case in Windows too?
     
    Last edited: Apr 18, 2013
  29. Steven-1

    Steven-1

    Joined:
    Sep 11, 2010
    Posts:
    455
    Is this supposed to work with Unity 4?
    I tried using it (downloaded it from Farfarer's site), but the specular is not working correctly.
    Also, after using this on 1 terrain in a scene, the other terrains in other scenes are messed up, even though they don't use this shader and never have.
    How do I fix this now? I don't get how/why they are messed up.

    EDIT:

    deleting the the entire triplanar folder fixed this.
    So do these triplanar-shaders automatically replace the default terrain shaders or something? weird
     
    Last edited: Jul 15, 2013
  30. J-F

    J-F

    Joined:
    Nov 8, 2012
    Posts:
    101
    I also have trouble running this on 4.3

    Assuming it no longer works. Please update!
     
  31. Sk8rseth

    Sk8rseth

    Joined:
    Aug 4, 2013
    Posts:
    13
    @steamroller,
    where exactly in the shader did you drop that code. i placed it where i thought it should go and still get the black line. where did you place yours?
     
    Alverik likes this.
  32. rethunk

    rethunk

    Joined:
    Jan 14, 2014
    Posts:
    1
    Hi guys!

    I discovered the Triplanar package yesterday and it looks really promising! I have an issue similar to what others have described, with black patches appearing when the camera begins to move in closer to my terrain object, both in-editor and in-game:

    $Screen shot 2014-01-14 at 12.49.08.png

    I'm also on a mid-2008 MacBook Pro with a GeForce 8600M GT GPU. I have tried a couple of the suggestions posted in this thread, but I'm not really into the code side of things so I'm admittedly a little lost.

    The scene above is at it's most basic - I created a new terrain object, painted a bit of height and the problem manifests. No textures applied at this stage. If I delete the Triplanar package from my project, the patches disappear.

    Any tips will be massively appreciated! Thanks!

    UPDATE: I think this is almost certainly a graphics card issue. Looking around for other Triplanar options I came across this demo:

    http://dl.dropboxusercontent.com/u/8933990/Webplayers/Triplanar/ShaderDisplay/WebPlayer.html

    ...and I'm seeing the same black areas on the bunnies. Upgrade time!
     
    Last edited: Jan 14, 2014
  33. praethin

    praethin

    Joined:
    May 30, 2013
    Posts:
    2
    For those of you that would rather work with C# i've converted both scripts into C#.
    TriplanarTerrain script
    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class TriPlanarTerrain : MonoBehaviour
    5. {
    6.     public Texture2D[] BumpTextures = new Texture2D[8];
    7.     public Texture2D[] SpecTextures = new Texture2D[8];
    8.     public float[] TilesPerMeter = new float[8];
    9.     public TerrainData TerDat;
    10.  
    11.     private Texture2D blankNormal;
    12.     private Texture2D blankSpec;
    13.  
    14.     public void Start()
    15.     {
    16.         SetTerrainValues();
    17.     }
    18.  
    19.     public void SetTerrainValues()
    20.     {
    21.  
    22.         if (blankNormal == null)
    23.         {
    24.             blankNormal = GenerateBlankNormal();
    25.         }
    26.  
    27.         if (blankSpec == null)
    28.         {
    29.             blankSpec = GenerateBlankSpec();
    30.         }
    31.  
    32.         if ((GetComponent<Terrain>() != null)  (TerDat == null))
    33.         {
    34.             TerDat = GetComponent<Terrain>().terrainData;
    35.         }
    36.  
    37.         if (TerDat != null)
    38.         {
    39.             var splatLength = TerDat.splatPrototypes.Length;
    40.             for (int i = 0; i < splatLength; i++)
    41.             {
    42.                 if (BumpTextures[i] != null)
    43.                 {
    44.                     Shader.SetGlobalTexture("_BumpMap" + i, BumpTextures[i]);
    45.                 }
    46.                 else
    47.                 {
    48.                     Shader.SetGlobalTexture("_BumpMap" + i, blankNormal);
    49.                 }
    50.  
    51.                 if (SpecTextures[i] != null)
    52.                 {
    53.                     Shader.SetGlobalTexture("_SpecMap" + i, SpecTextures[i]);
    54.                 }
    55.                 else
    56.                 {
    57.                     Shader.SetGlobalTexture("_SpecMap" + i, blankSpec);
    58.                 }
    59.  
    60.                 if (TilesPerMeter[i] != null)
    61.                 {
    62.                     Shader.SetGlobalFloat("_TerrainTexScale" + i, (1.0f / TilesPerMeter[i]));
    63.                 }
    64.                 else
    65.                 {
    66.                     Shader.SetGlobalFloat("_TerrainTexScale" + i, 1.0f);
    67.                 }
    68.             }
    69.             for (int i = 0; i < 8; i++)
    70.             {
    71.                 BumpTextures[i] = null;
    72.                 SpecTextures[i] = null;
    73.                 TilesPerMeter[i] = 1.0f;
    74.                 i++;
    75.             }
    76.         }
    77.     }
    78.  
    79.     public Texture2D GenerateBlankNormal()
    80.     {
    81.         var texture = new Texture2D(16, 16, TextureFormat.ARGB32, false);
    82.         var cols = texture.GetPixels32(0);
    83.         var colsLength = cols.Length;
    84.  
    85.         for (int i = 0; i < colsLength; i++)
    86.         {
    87.             cols[i] = new Color(0, 0.5f, 0, 0.5f);
    88.         }
    89.         texture.SetPixels32(cols, 0);
    90.         texture.Apply(false);
    91.         texture.Compress(false);
    92.         return texture;
    93.     }
    94.  
    95.     public Texture2D GenerateBlankSpec()
    96.     {
    97.         var texture = new Texture2D(16, 16, TextureFormat.RGB24, false);
    98.         var cols = texture.GetPixels(0);
    99.         for (int i = 0; i < cols.Length; i++)
    100.         {
    101.             cols[i] = new Color(0.1f, 0.1f, 0, 0);
    102.         }
    103.         texture.SetPixels(cols, 0);
    104.         texture.Apply(false);
    105.         texture.Compress(false);
    106.         return texture;
    107.     }
    108. }
    109.  
    TriPlanarTerrainEditor Script
    Code (csharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. [CustomEditor(typeof(TriPlanarTerrain))]
    6. class TriPlanarTerrainEditor : UnityEditor.Editor
    7. {
    8.  
    9.     public TriPlanarTerrain terScript;
    10.     public Terrain terrain;
    11.     public TerrainData terDat;
    12.     public bool[] showTextures = new bool[8];
    13.     public bool showHelp = false;
    14.  
    15.     public override void OnInspectorGUI()
    16.     {
    17.  
    18.         terScript = (TriPlanarTerrain)target;
    19.  
    20.         if (terrain == null)
    21.         {
    22.             EditorGUI.indentLevel = 0;
    23.             GUILayout.Label("Attach this script to a terrain.");
    24.             terrain = terScript.GetComponent<Terrain>();
    25.         }
    26.  
    27.         if ((terrain != null)  (terDat == null))
    28.         {
    29.             EditorGUI.indentLevel = 0;
    30.             GUILayout.Label("Attach terrain data to this terrain.");
    31.             terDat = terrain.terrainData;
    32.         }
    33.  
    34.         if (terDat != null)
    35.         {
    36.             EditorGUI.indentLevel = 0;
    37.             showHelp = EditorGUILayout.Foldout(showHelp, "Help");
    38.             if (showHelp)
    39.             {
    40.                 EditorGUI.indentLevel = 1;
    41.                 GUILayout.Label(
    42.                 "  Diffuse textures:\n   These are assigned in the regular Terrain script.\n   They are shown here only for reference.\n\n  Specular/gloss textures:\n   Specular value is taken from the red channel.\n   Gloss value is taken from the green channel.\n   The blue channel is unused."
    43.                 );
    44.             }
    45.             for (int i = 0; i < terDat.splatPrototypes.Length; i++)
    46.             {
    47.                 EditorGUI.indentLevel = 0;
    48.                 showTextures[i] = EditorGUILayout.Foldout(showTextures[i], "Layer " + i + " (" + terDat.splatPrototypes[i].texture.name + ")");
    49.                 if (showTextures[i])
    50.                 {
    51.                     EditorGUI.indentLevel = 1;
    52.                     terScript.TilesPerMeter[i] = EditorGUILayout.Slider("Tiling Amount", terScript.TilesPerMeter[i], 0.1f, 100.0f);
    53.                     EditorGUILayout.ObjectField("Diffuse", terDat.splatPrototypes[i].texture, typeof(Texture), false);
    54.                     terScript.BumpTextures[i] = (Texture2D)EditorGUILayout.ObjectField("Normal", terScript.BumpTextures[i], typeof(Texture), false);
    55.                     terScript.SpecTextures[i] = (Texture2D)EditorGUILayout.ObjectField("Spec / Gloss", terScript.SpecTextures[i], typeof(Texture), false);
    56.                     EditorGUILayout.Space();
    57.                 }
    58.             }
    59.         }
    60.  
    61.         terScript.SetTerrainValues();
    62.     }
    63.  
    64. }
    65.  
     
  34. CatOnTheRoof

    CatOnTheRoof

    Joined:
    Dec 8, 2011
    Posts:
    112
    Hello!

    Can anyone help me uninstall the Triplanar Terrain plugin? I send it to the trash once it started getting buggy (whenever I created a new terrain and added a texture, it would appear plain colour). So, I dumped it to the trash, but I still have the same bug. How do I completely get rid of it?

    Thanks!
     
  35. NightmarexGR

    NightmarexGR

    Joined:
    Jun 7, 2012
    Posts:
    217
    It works perfectly but everytime i save the scene i get :
    Cleaning up leaked objects in scene since no game object, component or manager is referencing them
    Texture2D has been leaked 2 times.
    any idea on how to fix it ?
     
  36. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    That notification is a generic Unity notice informing the user about an event. It is not harmful. I can't remember the situations that cause this, but Unity detects something it feels needs to be cleaned up, so it does.

    You might want to do a search on the warning and see what you can find.

    Don't forget that this is a relatively stale thread on an older system, which I don't believe is being supported. (FWIW
    YMMV)
     
  37. NightmarexGR

    NightmarexGR

    Joined:
    Jun 7, 2012
    Posts:
    217
    Well i downloaded that one :
    And it works perfectly on Unity 4.3.4 Pro,
    The only drawback is that error, i mean i want always to have an error clear scene/project cause i am aiming high and so far i am victorious and i just dont want to waste a week trying to figure out what is going on because i am not good with shaders :( I will try to find the source and i will let everyone know but in case so1 already knows how to fix it plz inform me :)
     
  38. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    It's been a long time since I followed this topic in detail. The only "gotcha" when it first came out was it wasn't all platform enabled. I can't remember if it was fixed. Test this on all your target platforms before you commit this to your workflow.
     
  39. NightmarexGR

    NightmarexGR

    Joined:
    Jun 7, 2012
    Posts:
    217
    Thnx for the advise i will keep an eye on it ! I will try to fix the error within the next 2 days and reupload if i make it.
     
  40. Amichel252

    Amichel252

    Joined:
    Jan 16, 2014
    Posts:
    7
    how can i fix this?

     

    Attached Files:

  41. TerraUnity

    TerraUnity

    Joined:
    Aug 3, 2012
    Posts:
    1,247
    Only god knows how! looool
     
    Amichel252 likes this.
  42. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,350
    Violet = missing shader.
     
  43. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    And/or missing material...
     
  44. Luka2811

    Luka2811

    Joined:
    Mar 14, 2013
    Posts:
    2
    I have question, can you extend it to 16 textures instead of 8. I have tried to do that but I have problem only with tile on textures that are bigger than 8 in indexing (index of texture is 8 or more).
     
  45. Helienio

    Helienio

    Joined:
    Sep 11, 2014
    Posts:
    29
    it's look great. im new, how this work?
     
  46. Helienio

    Helienio

    Joined:
    Sep 11, 2014
    Posts:
    29
    This is awesome, I try this and is so good to paint. no more strech. good. good. yeahhh.
    But, have a mode to add a heightmap in the blue chanel unused?
     
  47. OP3NGL

    OP3NGL

    Joined:
    Dec 10, 2013
    Posts:
    267
    hi all,

    in regards to "TriPlanarTerrainEditor Script", i got this error:

    TriPlanarTerrainEditor Script.cs(26,22): error CS0119: Expression denotes a `value', where a `method group' was expected

    how do i fixed this?
     
  48. challlen

    challlen

    Joined:
    Apr 11, 2014
    Posts:
    10
    I know this is an old topic, but someone in my group was using this script. There is a subtle bug in the C# version of TriPlanarTerrain posted by praethin. In particular, the switch to the for loop caused a new bug.
    Here is the fix:

    TriplanarTerrain script
    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class TriPlanarTerrain : MonoBehaviour
    5. {
    6.     public Texture2D[] BumpTextures = new Texture2D[8];
    7.     public Texture2D[] SpecTextures = new Texture2D[8];
    8.     public float[] TilesPerMeter = new float[8];
    9.     public TerrainData TerDat;
    10.  
    11.     private Texture2D blankNormal;
    12.     private Texture2D blankSpec;
    13.  
    14.     public void Start()
    15.     {
    16.         SetTerrainValues();
    17.     }
    18.  
    19.     public void SetTerrainValues()
    20.     {
    21.  
    22.         if (blankNormal == null)
    23.         {
    24.             blankNormal = GenerateBlankNormal();
    25.         }
    26.  
    27.         if (blankSpec == null)
    28.         {
    29.             blankSpec = GenerateBlankSpec();
    30.         }
    31.  
    32.         if ((GetComponent<Terrain>() != null)  (TerDat == null))
    33.         {
    34.             TerDat = GetComponent<Terrain>().terrainData;
    35.         }
    36.  
    37.         if (TerDat != null)
    38.         {
    39.             var splatLength = TerDat.splatPrototypes.Length;
    40.             int i = 0;
    41.             for (i = 0; i < splatLength; i++)
    42.             {
    43.                 if (BumpTextures[i] != null)
    44.                 {
    45.                     Shader.SetGlobalTexture("_BumpMap" + i, BumpTextures[i]);
    46.                 }
    47.                 else
    48.                 {
    49.                     Shader.SetGlobalTexture("_BumpMap" + i, blankNormal);
    50.                 }
    51.  
    52.                 if (SpecTextures[i] != null)
    53.                 {
    54.                     Shader.SetGlobalTexture("_SpecMap" + i, SpecTextures[i]);
    55.                 }
    56.                 else
    57.                 {
    58.                     Shader.SetGlobalTexture("_SpecMap" + i, blankSpec);
    59.                 }
    60.  
    61.                 if (TilesPerMeter[i] != 0.0f)
    62.                 {
    63.                     Shader.SetGlobalFloat("_TerrainTexScale" + i, (1.0f / TilesPerMeter[i]));
    64.                 }
    65.                 else
    66.                 {
    67.                     Shader.SetGlobalFloat("_TerrainTexScale" + i, 1.0f);
    68.                 }
    69.             }
    70.             while ( i < 8 )
    71.             {
    72.                 BumpTextures[i] = null;
    73.                 SpecTextures[i] = null;
    74.                 TilesPerMeter[i] = 1.0f;
    75.                 i++;
    76.             }
    77.         }
    78.     }
    79.  
    80.     public Texture2D GenerateBlankNormal()
    81.     {
    82.         var texture = new Texture2D(16, 16, TextureFormat.ARGB32, false);
    83.         var cols = texture.GetPixels32(0);
    84.         var colsLength = cols.Length;
    85.  
    86.         for (int i = 0; i < colsLength; i++)
    87.         {
    88.             cols[i] = new Color(0, 0.5f, 0, 0.5f);
    89.         }
    90.         texture.SetPixels32(cols, 0);
    91.         texture.Apply(false);
    92.         texture.Compress(false);
    93.         return texture;
    94.     }
    95.  
    96.     public Texture2D GenerateBlankSpec()
    97.     {
    98.         var texture = new Texture2D(16, 16, TextureFormat.RGB24, false);
    99.         var cols = texture.GetPixels(0);
    100.         for (int i = 0; i < cols.Length; i++)
    101.         {
    102.             cols[i] = new Color(0.1f, 0.1f, 0, 0);
    103.         }
    104.         texture.SetPixels(cols, 0);
    105.         texture.Apply(false);
    106.         texture.Compress(false);
    107.         return texture;
    108.     }
    109. }
    110.  
    TriPlanarTerrainEditor Script
    Code (csharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. [CustomEditor(typeof(TriPlanarTerrain))]
    6. class TriPlanarTerrainEditor : UnityEditor.Editor
    7. {
    8.  
    9.     public TriPlanarTerrain terScript;
    10.     public Terrain terrain;
    11.     public TerrainData terDat;
    12.     public bool[] showTextures = new bool[8];
    13.     public bool showHelp = false;
    14.  
    15.     public override void OnInspectorGUI()
    16.     {
    17.  
    18.         terScript = (TriPlanarTerrain)target;
    19.  
    20.         if (terrain == null)
    21.         {
    22.             EditorGUI.indentLevel = 0;
    23.             GUILayout.Label("Attach this script to a terrain.");
    24.             terrain = terScript.GetComponent<Terrain>();
    25.         }
    26.  
    27.         if ((terrain != null)  (terDat == null))
    28.         {
    29.             EditorGUI.indentLevel = 0;
    30.             GUILayout.Label("Attach terrain data to this terrain.");
    31.             terDat = terrain.terrainData;
    32.         }
    33.  
    34.         if (terDat != null)
    35.         {
    36.             EditorGUI.indentLevel = 0;
    37.             showHelp = EditorGUILayout.Foldout(showHelp, "Help");
    38.             if (showHelp)
    39.             {
    40.                 EditorGUI.indentLevel = 1;
    41.                 GUILayout.Label(
    42.                 "  Diffuse textures:\n   These are assigned in the regular Terrain script.\n   They are shown here only for reference.\n\n  Specular/gloss textures:\n   Specular value is taken from the red channel.\n   Gloss value is taken from the green channel.\n   The blue channel is unused."
    43.                 );
    44.             }
    45.             for (int i = 0; i < terDat.splatPrototypes.Length; i++)
    46.             {
    47.                 EditorGUI.indentLevel = 0;
    48.                 showTextures[i] = EditorGUILayout.Foldout(showTextures[i], "Layer " + i + " (" + terDat.splatPrototypes[i].texture.name + ")");
    49.                 if (showTextures[i])
    50.                 {
    51.                     EditorGUI.indentLevel = 1;
    52.                     terScript.TilesPerMeter[i] = EditorGUILayout.Slider("Tiling Amount", terScript.TilesPerMeter[i], 0.1f, 100.0f);
    53.                     EditorGUILayout.ObjectField("Diffuse", terDat.splatPrototypes[i].texture, typeof(Texture), false);
    54.                     terScript.BumpTextures[i] = (Texture2D)EditorGUILayout.ObjectField("Normal", terScript.BumpTextures[i], typeof(Texture), false);
    55.                     terScript.SpecTextures[i] = (Texture2D)EditorGUILayout.ObjectField("Spec / Gloss", terScript.SpecTextures[i], typeof(Texture), false);
    56.                     EditorGUILayout.Space();
    57.                 }
    58.             }
    59.         }
    60.  
    61.         terScript.SetTerrainValues();
    62.     }
    63.  
    64. }
    65.  
     
    Last edited by a moderator: Apr 13, 2015
  49. zelmund

    zelmund

    Joined:
    Mar 2, 2012
    Posts:
    437
    Assets/Scripts/LampsControl/TriPlanarTerrain.cs(31,22): error CS0119: Expression denotes a `value', where a `method group' was expected
     
  50. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Please be aware that this is a very very old thread that has long since past it's life expectancy. Do not expect interest or support from any of the original members.