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

Question How do i put color on this triplanar shader

Discussion in 'Shaders' started by AllieVizla, Jul 17, 2022.

  1. AllieVizla

    AllieVizla

    Joined:
    Mar 25, 2021
    Posts:
    1
    Now this is just a simple help me question as i'm completely inexperienced in shaders, i have been trying to find a good triplanar shader for a Social VR game world i am working on, however ive noticed that all shaders but one that i have found online cause annoying stretching and lines everywhere, exept for one of them, however this one, doesnt apply color, usually this wouldnt be an issue, but this project doesnt have any colored textures, they are all greyscale, using the material to color the object

    the stretching in question

    the working shader i found online but has no way to set any colors, Now i tried to add it in myself but i only got the UI element working, but the shader doesnt actually apply the coloration

    heres the shader thats colorless, i tried to splice together my own way to color it and failed many times
    Code (CSharp):
    1. Shader "Triplanar/Surface Shader (RNM)" {
    2.     Properties {
    3.         _Color("Color", Color) = (1,1,1,1)
    4.         _MainTex("Albedo", 2D) = "white" {}
    5.         [NoScaleOffset] _BumpMap("Normal Map", 2D) = "bump" {}
    6.         _Glossiness("Smoothness", Range(0, 1)) = 0.5
    7.         [Gamma] _Metallic("Metallic", Range(0, 1)) = 0
    8.         [NoScaleOffset] _OcclusionMap("Occlusion", 2D) = "white" {}
    9.         _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    10.     }
    11.     SubShader {
    12.         Tags { "RenderType"="Opaque" }
    13.         LOD 200
    14.    
    15.         CGPROGRAM
    16.         // Physically based Standard lighting model, and enable shadows on all light types
    17.         #pragma surface surf Standard fullforwardshadows
    18.         // Use shader model 3.0 target, to get nicer looking lighting
    19.         #pragma target 3.0
    20.         #include "UnityStandardUtils.cginc"
    21.         // flip UVs horizontally to correct for back side projection
    22.         #define TRIPLANAR_CORRECT_PROJECTED_U
    23.         // offset UVs to prevent obvious mirroring
    24.         // #define TRIPLANAR_UV_OFFSET
    25.         // Reoriented Normal Mapping
    26.         // http://blog.selfshadow.com/publications/blending-in-detail/
    27.         // Altered to take normals (-1 to 1 ranges) rather than unsigned normal maps (0 to 1 ranges)
    28.         half3 blend_rnm(half3 n1, half3 n2)
    29.         {
    30.             n1.z += 1;
    31.             n2.xy = -n2.xy;
    32.             return n1 * dot(n1, n2) / n1.z - n2;
    33.         }
    34.         sampler2D _MainTex;
    35.         float4 _MainTex_ST;
    36.         sampler2D _BumpMap;
    37.         sampler2D _OcclusionMap;
    38.         half _Glossiness;
    39.         half _Metallic;
    40.    
    41.         half _OcclusionStrength;
    42.         struct Input {
    43.             float3 worldPos;
    44.             float3 worldNormal;
    45.             INTERNAL_DATA
    46.         };
    47.         float3 WorldToTangentNormalVector(Input IN, float3 normal) {
    48.             float3 t2w0 = WorldNormalVector(IN, float3(1,0,0));
    49.             float3 t2w1 = WorldNormalVector(IN, float3(0,1,0));
    50.             float3 t2w2 = WorldNormalVector(IN, float3(0,0,1));
    51.             float3x3 t2w = float3x3(t2w0, t2w1, t2w2);
    52.             return normalize(mul(t2w, normal));
    53.         }
    54.         void surf (Input IN, inout SurfaceOutputStandard o) {
    55.             // work around bug where IN.worldNormal is always (0,0,0)!
    56.             IN.worldNormal = WorldNormalVector(IN, float3(0,0,1));
    57.             // calculate triplanar blend
    58.             half3 triblend = saturate(pow(IN.worldNormal, 4));
    59.             triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);
    60.             // calculate triplanar uvs
    61.             // applying texture scale and offset values ala TRANSFORM_TEX macro
    62.             float2 uvX = IN.worldPos.zy * _MainTex_ST.xy + _MainTex_ST.zy;
    63.             float2 uvY = IN.worldPos.xz * _MainTex_ST.xy + _MainTex_ST.zy;
    64.             float2 uvZ = IN.worldPos.xy * _MainTex_ST.xy + _MainTex_ST.zy;
    65.             // offset UVs to prevent obvious mirroring
    66.         #if defined(TRIPLANAR_UV_OFFSET)
    67.             uvY += 0.33;
    68.             uvZ += 0.67;
    69.         #endif
    70.             // minor optimization of sign(). prevents return value of 0
    71.             half3 axisSign = IN.worldNormal < 0 ? -1 : 1;
    72.        
    73.             // flip UVs horizontally to correct for back side projection
    74.         #if defined(TRIPLANAR_CORRECT_PROJECTED_U)
    75.             uvX.x *= axisSign.x;
    76.             uvY.x *= axisSign.y;
    77.             uvZ.x *= -axisSign.z;
    78.         #endif
    79.             // albedo textures
    80.             fixed4 colX = tex2D(_MainTex, uvX);
    81.             fixed4 colY = tex2D(_MainTex, uvY);
    82.             fixed4 colZ = tex2D(_MainTex, uvZ);
    83.             fixed4 col = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
    84.             // occlusion textures
    85.             half occX = tex2D(_OcclusionMap, uvX).g;
    86.             half occY = tex2D(_OcclusionMap, uvY).g;
    87.             half occZ = tex2D(_OcclusionMap, uvZ).g;
    88.             half occ = LerpOneTo(occX * triblend.x + occY * triblend.y + occZ * triblend.z, _OcclusionStrength);
    89.             // tangent space normal maps
    90.             half3 tnormalX = UnpackNormal(tex2D(_BumpMap, uvX));
    91.             half3 tnormalY = UnpackNormal(tex2D(_BumpMap, uvY));
    92.             half3 tnormalZ = UnpackNormal(tex2D(_BumpMap, uvZ));
    93.             // flip normal maps' x axis to account for flipped UVs
    94.         #if defined(TRIPLANAR_CORRECT_PROJECTED_U)
    95.             tnormalX.x *= axisSign.x;
    96.             tnormalY.x *= axisSign.y;
    97.             tnormalZ.x *= -axisSign.z;
    98.         #endif
    99.             half3 absVertNormal = abs(IN.worldNormal);
    100.             // swizzle world normals to match tangent space and apply reoriented normal mapping blend
    101.             tnormalX = blend_rnm(half3(IN.worldNormal.zy, absVertNormal.x), tnormalX);
    102.             tnormalY = blend_rnm(half3(IN.worldNormal.xz, absVertNormal.y), tnormalY);
    103.             tnormalZ = blend_rnm(half3(IN.worldNormal.xy, absVertNormal.z), tnormalZ);
    104.             // apply world space sign to tangent space Z
    105.             tnormalX.z *= axisSign.x;
    106.             tnormalY.z *= axisSign.y;
    107.             tnormalZ.z *= axisSign.z;
    108.             // sizzle tangent normals to match world normal and blend together
    109.             half3 worldNormal = normalize(
    110.                 tnormalX.zyx * triblend.x +
    111.                 tnormalY.xzy * triblend.y +
    112.                 tnormalZ.xyz * triblend.z
    113.                 );
    114.             // set surface ouput properties
    115.             o.Albedo = col.rgb;
    116.             o.Metallic = _Metallic;
    117.             o.Smoothness = _Glossiness;
    118.             o.Occlusion = occ;
    119.             // convert world space normals into tangent normals
    120.             o.Normal = WorldToTangentNormalVector(IN, worldNormal);
    121.         }
    122.         ENDCG
    123.     }
    124.     FallBack "Diffuse"
    125. }
    if anyone understands this and has a solution i would apriciate help as ive found no other shaders that project properly and i really dont want to keep this thing on hold for much longer than it has been

    note the shader isnt mine, i just found it on github somewhere on a very old post, but it works kinda