Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Reflections in custom shader

Discussion in 'Unity 5 Pre-order Beta' started by pixoloco, Nov 11, 2014.

  1. pixoloco

    pixoloco

    Joined:
    Dec 22, 2011
    Posts:
    47
    Hi everyone,

    I've made this shader in Unity 5b12 :
    Code (CSharp):
    1.  
    2. Shader "simple" {
    3. Properties {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _MainTex ("Base (RGB)", 2D) = "white" {}
    6.     _SpecTex ("Spec (RGB) Gloss (A)", 2D) = "white" {}
    7.     _NormTex ("Normal (RGB)", 2D) = "white" {}
    8.     _NormFactor ("Normal Strength", Range (0,2)) = 1
    9. }
    10.  
    11. SubShader {
    12.     Tags { "RenderType"="Opaque" }
    13.     LOD 300
    14.    
    15. CGPROGRAM
    16. #pragma target 3.0
    17. #include "UnityPBSLighting.cginc"
    18. #pragma surface surf Standard
    19.  
    20. sampler2D _MainTex;
    21. sampler2D _NormTex;
    22. sampler2D _SpecTex;
    23. fixed4 _Color;
    24. half _NormFactor;
    25.  
    26. struct Input {
    27.     float2 uv_MainTex;
    28.     float2 uv_SpecTex;
    29.     float2 uv_NormTex;
    30. };
    31.  
    32. void surf (Input IN, inout SurfaceOutputStandard o) {
    33.     fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    34.     fixed4 spectex = tex2D(_SpecTex, IN.uv_SpecTex);
    35.     o.Albedo = tex.rgb * _Color.rgb;
    36.     o.Normal = UnpackScaleNormal(tex2D(_NormTex, IN.uv_NormTex),_NormFactor);
    37.     o.Specular = spectex.rgb;
    38.     o.Smoothness = spectex.a;
    39. }
    40. ENDCG
    41. }
    42.  
    43. Fallback "VertexLit"
    44. }
    45.  
    The lighting seems correct when I remove specular but as you can see, there is no reflections.
    Is there an "easy" way to mimic the standard shader reflections in surface shaders?

    cubes.jpg
    left cube : standard shader
    right cube : my shader with the same images/parameters
    bottom left : why I need reflections :)
     
  2. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,918
    I think there was a bug with surface shaders where reflection information was not being passed in the shader. Wait for 5.0 b13, if it will still not work, please submit a bug.
     
  3. pixoloco

    pixoloco

    Joined:
    Dec 22, 2011
    Posts:
    47
    Great, thanks !
     
  4. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    Has this been fixed as I am having the same problem, can get the lighting working but have no reflections at all.
     
  5. pixoloco

    pixoloco

    Joined:
    Dec 22, 2011
    Posts:
    47
    nope, I have submitted a bug report.
     
  6. Luckymouse

    Luckymouse

    Joined:
    Jan 31, 2010
    Posts:
    484
    I think you need to add the following codes to custom shader to enable the reflection:
    Code (CSharp):
    1.     CGINCLUDE
    2.         #define _GLOSSYENV 1
    3.         #define UNITY_SETUP_BRDF_INPUT SpecularSetup
    4.     ENDCG
    It will also work for Metallic Setup
    Code (CSharp):
    1. #define UNITY_SETUP_BRDF_INPUT MetallicSetup
    Full Shader Example:
    Code (CSharp):
    1. // All textures share the same Tiling and Offset value from Main Texture
    2.  
    3. Shader "Custom/PBS (Specular Setup)" {
    4. Properties {
    5.     _Color ("Main Color", Color) = (1,1,1,1)
    6.     _MainTex ("Base (RGB)", 2D) = "white" {}
    7.     _SpecColor ("Specular Color", Color) = (1,1,1,1)
    8.     _Glossiness("Smoothness", Range(0,1)) = 0.75
    9. [NoScaleOffset] _SpecGlossMap("Specular (RGB) Glossiness (A)", 2D) = "white" {}
    10. [NoScaleOffset] _BumpMap ("Normal Map", 2D) = "bump" {}
    11.     _BumpScale("Bump Scale", Float) = 1.0
    12.  
    13. }
    14.      CGINCLUDE
    15.         //@TODO: should this be pulled into a shader_feature, to be able to turn it off?
    16.         #define _GLOSSYENV 1
    17.         #define UNITY_SETUP_BRDF_INPUT SpecularSetup
    18.     ENDCG
    19.  
    20. SubShader {
    21.     Tags { "RenderType"="Opaque" }
    22.     LOD 300
    23.  
    24. CGPROGRAM
    25. #pragma target 3.0
    26. #include "UnityPBSLighting.cginc"
    27. #pragma surface surf Standard
    28. sampler2D _MainTex;
    29. sampler2D _BumpMap;
    30. sampler2D _SpecGlossMap;
    31. fixed4 _Color ;
    32. half _Glossiness;
    33. half _BumpScale;
    34. struct Input {
    35.     float2 uv_MainTex;
    36. };
    37. void surf (Input IN, inout SurfaceOutputStandard o) {
    38.     fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    39.     fixed4 sg = tex2D(_SpecGlossMap, IN.uv_MainTex);
    40.     o.Albedo = tex.rgb * _Color.rgb;
    41.     o.Normal = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_MainTex),_BumpScale);
    42.     o.Specular = sg.rgb * _SpecColor.rgb;
    43.     o.Smoothness = sg.a *_Glossiness ;
    44. }
    45. ENDCG
    46. }
    47. Fallback "VertexLit"
    48.  
    49. }

    This shader has been tested, it will show either skybox reflection or reflection probe :)

    [Edit] Updated the shader "Properties".
     
    Last edited: Nov 28, 2014
    SAOTA, Killerwhale and pixoloco like this.
  7. pixoloco

    pixoloco

    Joined:
    Dec 22, 2011
    Posts:
    47
    It's working ! Thanks luckymouse.
     
  8. pojoih

    pojoih

    Joined:
    Mar 30, 2013
    Posts:
    226
    did you managed to get transparency working with PBS Surface Shader? I did not find the switch, yet. Am I missing something?
    This is what I've got so far, including a custom light model (currently untouched, just copied from the cginc-files), but it's not working with the "Standard" Lightmodel, either.

    Code (CSharp):
    1.     // All textures share the same Tiling and Offset value from Main Texture
    2.  
    3.     Shader "Custom/PBS (Specular Setup)" {
    4.     Properties {
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Base (RGB)", 2D) = "white" {}
    7.         _SpecColor ("Specular Color", Color) = (1,1,1,1)
    8.         _Glossiness("Smoothness", Range(0,1)) = 0.75
    9.         [NoScaleOffset] _SpecGlossMap("Specular (RGB) Glossiness (A)", 2D) = "white" {}
    10.         [NoScaleOffset] _BumpMap ("Normal Map", 2D) = "bump" {}
    11.         _BumpScale("Bump Scale", Float) = 1.0
    12.     }
    13.     CGINCLUDE
    14.     //@TODO: should this be pulled into a shader_feature, to be able to turn it off?
    15.     #define _GLOSSYENV 1
    16.     #define UNITY_SETUP_BRDF_INPUT SpecularSetup
    17.     ENDCG
    18.  
    19.     SubShader {
    20.         Tags { "RenderType"="Transparent"}
    21.         LOD 300
    22.         ZWrite Off
    23.         ZTest LEqual
    24.         Blend SrcAlpha OneMinusSrcAlpha
    25.          
    26.     CGPROGRAM
    27.     #pragma target 3.0
    28.     #include "UnityPBSLighting.cginc"
    29.     #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON
    30.     #pragma surface surf MyLightModel
    31.  
    32.     sampler2D _MainTex;
    33.     sampler2D _BumpMap;
    34.     sampler2D _SpecGlossMap;
    35.     fixed4 _Color ;
    36.     half _Glossiness;
    37.     half _BumpScale;
    38.  
    39.  
    40. inline half4 LightingMyLightModel (SurfaceOutputStandard s, half3 viewDir, UnityGI gi)
    41. {
    42.     s.Normal = normalize(s.Normal);
    43.  
    44.     // energy conservation
    45.     half oneMinusReflectivity = 1 - SpecularStrength(s.Specular);
    46.     half oneMinusRoughness = s.Smoothness;
    47.     s.Albedo = s.Albedo * oneMinusReflectivity;
    48.     half4 c = UNITY_BRDF_PBS (s.Albedo, s.Specular, oneMinusReflectivity, oneMinusRoughness, s.Normal, viewDir, gi.light, gi.environment);
    49.     #if defined(DIRLIGHTMAP_SEPARATE)
    50.         c += DirectionalLightmapsIndirectBRDF (s.Albedo, s.Specular, oneMinusReflectivity, oneMinusRoughness, s.Normal, viewDir, gi);
    51.     #endif
    52.     return c;
    53. }
    54.  
    55. inline half4 LightingMyLightModel_Deferred (SurfaceOutputStandard s, half3 viewDir, UnityGI gi, out half4 outDiffuse, out half4 outSpecSmoothness, out half4 outNormal)
    56. {
    57.     // energy conservation
    58.     half oneMinusReflectivity = 1 - SpecularStrength(s.Specular);
    59.     half oneMinusRoughness = s.Smoothness;
    60.     s.Albedo = s.Albedo * oneMinusReflectivity;
    61.     half4 c = UNITY_BRDF_PBS (s.Albedo, s.Specular, oneMinusReflectivity, oneMinusRoughness, s.Normal, viewDir, gi.light, gi.environment);
    62.     #if defined(DIRLIGHTMAP_SEPARATE)
    63.         c += DirectionalLightmapsIndirectBRDF (s.Albedo, s.Specular, oneMinusReflectivity, oneMinusRoughness, s.Normal, viewDir, gi);
    64.     #endif
    65.     outDiffuse = half4(s.Albedo, s.Alpha);
    66.     outSpecSmoothness = half4(s.Specular, s.Smoothness);
    67.     outNormal = half4(s.Normal * 0.5 + 0.5, 1);
    68.     half4 emission = half4(s.Emission + c.rgb, 1);
    69.     return emission;
    70. }
    71.     inline void LightingMyLightModel_GI (SurfaceOutputStandard s, UnityGIInputData data, inout UnityGI gi)
    72.     {
    73.         UnityStandardGlobalIllumination (data, s.Occlusion, (1-s.Smoothness), s.Normal, gi);
    74.     }
    75.  
    76.     struct Input {
    77.         float2 uv_MainTex;
    78.     };
    79.     void surf (Input IN, inout SurfaceOutputStandard o) {
    80.         fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    81.         fixed4 sg = tex2D(_SpecGlossMap, IN.uv_MainTex);
    82.         o.Albedo = tex.rgb * _Color.rgb;
    83.         o.Normal = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_MainTex),_BumpScale);
    84.         o.Specular = sg.rgb * _SpecColor.rgb;
    85.         o.Smoothness = sg.a *_Glossiness ;
    86.         o.Alpha = 0.5f;
    87.     }
    88.     ENDCG
    89.     }
    90.     Fallback "VertexLit"
    91.  
    92.     }
     
  9. Luckymouse

    Luckymouse

    Joined:
    Jan 31, 2010
    Posts:
    484
    @ pojoih, You forget to add the alpha word after your MyLightModel:

    It should be:
    Code (Cg):
    1.     #pragma surface surf MyLightModel alpha
    Thats all, the way how alpha works in surface shader is the same since Unity 3.x. Check the doc here.
     
    Last edited: Nov 28, 2014
  10. Genjin

    Genjin

    Joined:
    Oct 17, 2014
    Posts:
    11
    After #define _GLOSSYENV 1 , what variables do you get to use and how are they used? I expected the shader example to use something in o.Emission but I guess it doesn't work like that anymore. Anyone has found out anything yet? I urgently need to set some custom reflection strengths independent of the specular (and without changing the Reflection Probe Inspector strength)

    I'd appreciate your insights.

    EDIT: Small update on what I have found so far:
    It looks like we may need to do it with custom lighting functions? They recently moved more code and now you find reflection related code in UnityPBSLighting.cginc

    It's all a little hard to follow with many things still spread out through tons of files but if I copypaste and base on the UnityPBSLighting.cginc I may be able to achieve what I want. I still need to try it, I havn't touched it yet. I still think I'm missing something though, it seems all a little complicated... what if I want a much simpler Lighting Model but with access to the probes? It goes through so many files with things declared everywhere I don't even know. But yeah that's what I found so far.
     
    Last edited: Dec 5, 2014
  11. Phantomx

    Phantomx

    Joined:
    Oct 30, 2012
    Posts:
    202
    Are you still able to use your custom lighting model with b17 ? I get an error : "Shader error in 'Custom/PBS (Specular Setup)': Syntax error at line 71 (on )"

    It refers to this:
    Code (CSharp):
    1. inline void LightingMyLightModel_GI (SurfaceOutputStandard s, UnityGIInputData data, inout UnityGI gi)
    2.         {
    3.             UnityStandardGlobalIllumination (data, s.Occlusion, (1-s.Smoothness), s.Normal, gi);
    4.         }
    I copy pasted the code posted here and it gives me this error. also I can't get the metalic setup to work, it makes no difference if I use this:
    #define UNITY_SETUP_BRDF_INPUT SpecularSetup
    or this
    #define UNITY_SETUP_BRDF_INPUT MetallicSetup