Search Unity

Gem/Diamond shader - broken in Unity 5

Discussion in 'Shaders' started by copperrobot, Mar 4, 2015.

  1. copperrobot

    copperrobot

    Joined:
    May 22, 2013
    Posts:
    69
  2. varfare

    varfare

    Joined:
    Feb 12, 2013
    Posts:
    227
  3. copperrobot

    copperrobot

    Joined:
    May 22, 2013
    Posts:
    69
    Thanks for the tip!

    Sorry to be a pain - is this Unity 5 friendly?
     
  4. varfare

    varfare

    Joined:
    Feb 12, 2013
    Posts:
    227
    What do you mean by that? If it works with GI? Or is it PBR diamond shader?
     
  5. copperrobot

    copperrobot

    Joined:
    May 22, 2013
    Posts:
    69
    Not sure :)

    Not written shaders before. Was hoping there was some code that Unity may be able to tweak for the shader to work in 5.
     
  6. varfare

    varfare

    Joined:
    Feb 12, 2013
    Posts:
    227
    Ahhh... Nope, you will have to translate some of the code snippets from the link above to get this working inside Unity. If you need quick solution I recomment using built-in PBR shaders, just tweak them as needed :)
     
  7. SilverAura

    SilverAura

    Joined:
    Jan 24, 2013
    Posts:
    9
    As far as I can see, the PBR shaders don't have any sort of refraction techniques. Unless I'm mistaken, it doesn't look like there's any way to achieve a similar affect in Unity 5 without writing your own shader - something a lot of us can't even begin to wrap our heads around.
     
  8. varfare

    varfare

    Joined:
    Feb 12, 2013
    Posts:
    227
    Yea. I've just installed Unity5 and you are right. There is not built-in PBR shader with refraction. That is a thing I can adress when I'll find some free time. Meanwhile, you can use built-in refractive glass shader. It does not look like a diamond but it should be fine as a placeholder.
     
  9. gamer2300

    gamer2300

    Joined:
    Jan 16, 2013
    Posts:
    31
    yes why this? who know solution?
     
  10. Kjell-Andersson

    Kjell-Andersson

    Joined:
    Oct 15, 2014
    Posts:
    14
    I remade the diamond shader so it works in Unity 5 using custom shader code. I guess it's not exactly the same, but it works ok I think. You are free to improve it...

    Code (CSharp):
    1.  
    2. Shader "FX/Diamond"
    3. {
    4.     Properties {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _Shininess ("Shininess", Range (0, 10)) = 1
    7.         _ReflectTex ("Reflection Texture", Cube) = "dummy.jpg"
    8.         _RefractTex ("Refraction Texture", Cube) = "dummy.jpg"
    9.     }  
    10.     SubShader {
    11.         Tags {
    12.             "RenderType" = "Transparent"
    13.              "Queue" = "Transparent"
    14.         }
    15.         // First pass - here we render the backfaces of the diamonds. Since those diamonds are more-or-less
    16.         // convex objects, this is effectively rendering the inside of them
    17.         Cull Front
    18.         ZWrite Off
    19.         Blend SrcAlpha Zero
    20.         CGPROGRAM
    21.             #pragma surface surf BlinnPhong
    22.  
    23.             samplerCUBE _ReflectTex;
    24.             samplerCUBE _RefractTex;
    25.          
    26.             fixed4 _Color;
    27.          
    28.             struct Input {
    29.                 float3 worldRefl;
    30.             };
    31.          
    32.             void surf (Input IN, inout SurfaceOutput o) {
    33.                 o.Albedo = texCUBE(_RefractTex, IN.worldRefl) * _Color;
    34.                 o.Emission = texCUBE(_ReflectTex, IN.worldRefl);
    35.             }
    36.         ENDCG
    37.  
    38.         // Second pass - here we render the front faces of the diamonds.
    39.         Cull Back
    40.         Blend One One
    41.         ZWrite On
    42.  
    43.         CGPROGRAM
    44.             #pragma surface surf BlinnPhong
    45.  
    46.             samplerCUBE _ReflectTex;
    47.          
    48.             fixed4 _Color;
    49.             half _Shininess;
    50.          
    51.             struct Input {
    52.                 float3 worldRefl;
    53.             };
    54.             samplerCUBE _RefractTex;
    55.          
    56.             void surf (Input IN, inout SurfaceOutput o) {
    57.                 o.Albedo = texCUBE(_RefractTex, IN.worldRefl) * _Color;
    58.                 o.Emission = texCUBE(_ReflectTex, IN.worldRefl) * _Shininess;
    59.             }
    60.  
    61.         ENDCG
    62.     }
    63.  
    64.     Fallback "VertexLit"
    65. }
    66.  
     
    gecko and srmols like this.
  11. Kronnect

    Kronnect

    Joined:
    Nov 16, 2014
    Posts:
    2,906
    Thank you very much!
     
  12. srmols

    srmols

    Joined:
    Nov 3, 2014
    Posts:
    10
    Wow, thank you very much Kjell Andersson. I was following the tutorial that needed those assets and your code worked perfectly.
     
  13. KnewK

    KnewK

    Joined:
    Sep 2, 2012
    Posts:
    19
    Thank you so much. Works like a gem.
     
  14. AgentParsec

    AgentParsec

    Joined:
    May 5, 2012
    Posts:
    403
    I tried this, and it SEEMED to work at first, but there's still a problem I'm having with it. Previously, the gem shader would be visible in the dark without any other light sources needed to illuminate it. Now, if it's dark it will show up as solid black (although the shine will still show). Is there any way to tweak it so that it's still visible in the dark and doesn't require lighting to see?
     
  15. AgentParsec

    AgentParsec

    Joined:
    May 5, 2012
    Posts:
    403
    Ok, messing around with it, I found that if I replaced the o.albedo with o.emission, it made the textures stand out, but it also means having to remove the illumination layer. At this point I also noticed another problem, which is that none of the textures seem to align themselves to the player like the original one did. Previously, if you stood directly under it and rotated your view around, on a sphere it would rotate the textures with you and almost look like it isn't changing (just some slight changes in the edge where the mesh differs), but with this newer one, it keeps the textures stationary.

    Since the gem shader was made by Unity Technologies, it'd be nice if they could release an updated version that works with Unity 5, or at least explain how to achieve the exact same effect.
     
  16. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,241
    Thank you so, so much for this updated shader!
     
  17. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    I actually rewrote the Gem shader the other day making an exact copy ( I think ) of the original fixed function pipeline version that Unity released. The only exception is the alpha component, which in the original used the primary lighting value, but that didn't make much sense to me, so I left that part out, but still used the alpha from the reflection cubemap.

    As far as I could tell, in a quick, simple test scene this shader produces 1:1 results with the original fixed function shader.

    Interesting looking at the original pdf paper the Unity version is highly simplified. Might be fun to implement the full paper for Gem stones sometime.


    Code (CSharp):
    1. Shader "FX/Gemstone/V5"
    2. {
    3.     Properties
    4.     {
    5.         _Color         ("Color", Color)              = (1,1,1,1)
    6.         _ReflectTex ("Reflection Texture", Cube) = ""
    7.         _RefractTex ("Refraction Texture", Cube) = ""
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue" = "Transparent"
    15.         }
    16.  
    17.         Pass
    18.         {
    19.             Cull Front
    20.             ZWrite Off
    21.      
    22.             CGPROGRAM
    23.             #pragma vertex vert
    24.             #pragma fragment frag
    25.             #include "UnityCG.cginc"
    26.      
    27.             float4         _Color;
    28.             samplerCUBE _ReflectTex;
    29.             samplerCUBE _RefractTex;
    30.      
    31.             struct v2f
    32.             {
    33.                 float4 pos     : SV_POSITION;
    34.                 float3 uv     : TEXCOORD0;
    35.             };
    36.      
    37.             v2f vert (float4 v : POSITION, float3 n : NORMAL)
    38.             {
    39.                 v2f o;
    40.                 o.pos = mul(UNITY_MATRIX_MVP, v);
    41.          
    42.                 // TexGen CubeReflect: Reflect view direction along the normal, in view space
    43.                 float3 viewDir = normalize(ObjSpaceViewDir(v));
    44.                 o.uv = reflect(-viewDir, n);
    45.                 o.uv = mul(UNITY_MATRIX_MV, float4(o.uv, 0));
    46.                 return o;
    47.             }
    48.      
    49.             half4 frag (v2f i) : SV_Target
    50.             {
    51.                 float4 col = texCUBE(_RefractTex, i.uv) * _Color;          
    52.                 col.a = texCUBE(_ReflectTex, i.uv) - 0.5f;
    53.                 return col;
    54.             }
    55.             ENDCG
    56.         }
    57.  
    58.  
    59.         Pass
    60.         {
    61.             Cull     Back
    62.             ZWrite     On
    63.             Blend     One One
    64.      
    65.             CGPROGRAM
    66.             #pragma vertex vert
    67.             #pragma fragment frag
    68.             #include "UnityCG.cginc"
    69.      
    70.             float4         _Color;
    71.             samplerCUBE _ReflectTex;
    72.             samplerCUBE _RefractTex;
    73.      
    74.             struct v2f
    75.             {
    76.                 float4 pos     : SV_POSITION;
    77.                 float3 uv     : TEXCOORD0;
    78.             };
    79.      
    80.             v2f vert (float4 v : POSITION, float3 n : NORMAL)
    81.             {
    82.                 v2f o;
    83.                 o.pos = mul(UNITY_MATRIX_MVP, v);
    84.          
    85.                 // TexGen CubeReflect: Reflect view direction along the normal, in view space
    86.                 float3 viewDir = normalize(ObjSpaceViewDir(v));
    87.                 o.uv = reflect(-viewDir, n);
    88.                 o.uv = mul(UNITY_MATRIX_MV, float4(o.uv, 0));
    89.                 return o;
    90.             }
    91.      
    92.             half4 frag (v2f i) : SV_Target
    93.             {
    94.                 float4 col = texCUBE(_RefractTex, i.uv) * _Color + texCUBE(_ReflectTex, i.uv);          
    95.                 col.a += texCUBE(_ReflectTex, i.uv) - 0.5f;
    96.                 return col;
    97.             }
    98.             ENDCG
    99.         }
    100.  
    101.     }
    102.     FallBack "Diffuse"
    103. }
    104.  
     
    Last edited: May 30, 2015
    Deozaan, Naphier and hopeful like this.
  18. Luckymouse

    Luckymouse

    Joined:
    Jan 31, 2010
    Posts:
    484
    Updated the gem shader for Unity 5. The reflection code is based on unity builtin shader "Legacy Shaders/Reflective/VertexLit" and simplified the code a little bit (compares with the shader above).

    Code (CSharp):
    1. Shader "FX/Diamond U5"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _ReflectTex ("Reflection Texture", Cube) = ""{}
    7.         _RefractTex ("Refraction Texture", Cube) = ""{}
    8.     }
    9.     SubShader
    10.     {
    11.         Tags
    12.         { "Queue" = "Transparent" }
    13.  
    14.         CGINCLUDE
    15.         #pragma vertex vert
    16.         #include "UnityCG.cginc"
    17.         float4      _Color;
    18.         samplerCUBE _ReflectTex;
    19.         samplerCUBE _RefractTex;
    20.         struct v2f
    21.         {
    22.             float4 pos    : SV_POSITION;
    23.             float3 uv     : TEXCOORD0;
    24.         };
    25.         v2f vert (appdata_base v)
    26.         {
    27.             v2f o;
    28.             o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    29.  
    30.             // calculate world space reflection vector
    31.             float3 viewDir = WorldSpaceViewDir( v.vertex );
    32.             float3 worldN = UnityObjectToWorldNormal( v.normal );
    33.             o.uv = reflect( -viewDir, worldN );
    34.             return o;
    35.         }
    36.         half4 fragBack (v2f i) : SV_Target
    37.         {
    38.             float4 col = texCUBE(_RefractTex, i.uv) * _Color;
    39.             return col;
    40.         }
    41.         half4 fragFront (v2f i) : SV_Target
    42.         {
    43.             float4 reflcol = texCUBE(_ReflectTex, i.uv);
    44.             float4 col = texCUBE(_RefractTex, i.uv) * _Color + reflcol;
    45.             return col;
    46.         }
    47.         ENDCG
    48.    
    49. //---------------------------------------------------------------------------------------------
    50.         // First pass - here we render the backfaces of the diamonds. Since those diamonds are more-or-less
    51.         // convex objects, this is effectively rendering the inside of them
    52.         Pass
    53.         {
    54.             Cull Front
    55.             ZWrite Off
    56.    
    57.             CGPROGRAM
    58.             #pragma fragment fragBack
    59.             ENDCG
    60.         }
    61.         // Second pass - here we render the front faces of the diamonds.      
    62.         Pass
    63.         {
    64.             ZWrite On
    65.             Blend One One
    66.    
    67.             CGPROGRAM
    68.             #pragma fragment fragFront
    69.             ENDCG
    70.         }
    71.     }
    72.     Fallback "Legacy Shaders/VertexLit"
    73. }
    [Edit]
    Add a gem shader (file attached below) that supports the Transparent. The transparent controls by the Color Alpha.
     

    Attached Files:

    Last edited: Jul 16, 2015
  19. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    The original Gem Shader package has now been updated to support Unity 5. Better late than never.

    https://www.assetstore.unity3d.com/en/#!/content/3

    The new version does not look exactly the same, though it can be made to look very close. It has a few settings that lets you make it glow in the dark like the old one, take light from the environment (reflection probes) for a bit more realism, or a combination.

    GemShader.png
     
    Noisecrime and hopeful like this.
  20. Kronnect

    Kronnect

    Joined:
    Nov 16, 2014
    Posts:
    2,906
    Thank you.
     
  21. ViralArt

    ViralArt

    Joined:
    Apr 17, 2015
    Posts:
    11
    Great work so far. However i have found one little drawback in one of the setups
    First I would like the gem reflection to behave the same way as Noisecrime. Having the gem reflect the same way from all angles. The problem with his solution is when you rig & skin the mesh the reflection does no longer scale with the object which it does do correctly in the other exsamples presented.

    Currently i use Luckymouse's Transparent version of the shader with a few replaced lines from Noisecrime to get it into objectspace instead of worldspace. Ofc i still have the scale problem, which is hurting me alot.

    Replaced code: Im fighting back and forth between these lines.

    v2f vert (appdata_base v)
    {
    v2f o;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

    // calculate world space reflection vector
    //float3 viewDir = WorldSpaceViewDir( v.vertex );
    float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));

    float3 worldN = normalize(UnityObjectToWorldNormal( v.normal ));
    //float3 worldN = v.normal;

    o.uv = reflect( -viewDir, worldN );

    o.uv = mul(UNITY_MATRIX_MV, float4(o.uv, 0));
    return o;


    I'm having a hard time wraping my head around all these vector and matrix calculations
    If somebody can help me out I would much appreciated it.
     
    Last edited: Jul 15, 2016
  22. TheRedGuy90

    TheRedGuy90

    Joined:
    Dec 5, 2014
    Posts:
    117
    The difference, it seems, between these and other meshes is that each face refracts on its own?.......

    I could do this myself, theoretically, in 3D programs, correct?

    These are fantastic!!!