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

Help with a box projected environment mapping shader

Discussion in 'Shaders' started by Temporaro, May 28, 2013.

  1. Temporaro

    Temporaro

    Joined:
    Dec 21, 2012
    Posts:
    27
    I have found this excellent shader made by Steva from this thread. I was wondering if anyone could help me? The shader works fine but the reflection strength map isn't having any effect. I am not particularly experienced with writing shaders but it appears that everything should be set up correctly yet the alpha mask isn't having any effect.

    Also this technique is excellent and cheap and deserves the extra exposure.

    The shader is posted below:

    Code (csharp):
    1. Shader "Custom/Reflective BPCEM Diffuse" {
    2.  
    3. Properties {
    4.  
    5.     //Box Projected Cubemap Environment Mapping
    6.  
    7.     _Color ("Main Color", Color) = (1,1,1,1)
    8.  
    9.     _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
    10.  
    11.     _MainTex ("Base (RGB) RefStrength (A)", 2D) = "white" {}
    12.  
    13.     _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect }
    14.  
    15.     _BumpMap ("Normalmap", 2D) = "bump" {}
    16.  
    17.    
    18.  
    19.     _EnvBoxStart ("Env Box Start", Vector) = (0, 0, 0)
    20.  
    21.     _EnvBoxSize ("Env Box Size", Vector) = (10, 10, 10)
    22.  
    23. }
    24.  
    25.  
    26.  
    27. SubShader {
    28.  
    29.     Tags { "RenderType"="Opaque" }
    30.  
    31.     LOD 300
    32.  
    33.    
    34.  
    35. CGPROGRAM
    36.  
    37. #pragma surface surf Lambert
    38.  
    39.  
    40.  
    41. sampler2D _MainTex;
    42.  
    43. sampler2D _BumpMap;
    44.  
    45. samplerCUBE _Cube;
    46.  
    47.  
    48.  
    49. fixed4 _Color;
    50.  
    51. fixed4 _ReflectColor;
    52.  
    53. fixed4 _EnvBoxStart;
    54.  
    55. fixed4 _EnvBoxSize;
    56.  
    57.  
    58.  
    59. struct Input {
    60.  
    61.     float2 uv_MainTex;
    62.  
    63.     float2 uv_BumpMap;
    64.  
    65.     float3 worldRefl;
    66.  
    67.     fixed3 worldPos;
    68.  
    69.     float3 worldNormal;
    70.  
    71.     INTERNAL_DATA
    72.  
    73. };
    74.  
    75.  
    76.  
    77. void surf (Input IN, inout SurfaceOutput o) {
    78.  
    79.    
    80.  
    81.    
    82.  
    83.    
    84.  
    85.     fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    86.  
    87.     fixed4 c = tex * _Color;
    88.  
    89.     o.Albedo = c.rgb;
    90.  
    91.    
    92.  
    93.     fixed3 n = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    94.  
    95.    
    96.  
    97.     float3 dir = IN.worldPos - _WorldSpaceCameraPos;                            // pos fragment relativo a pos camera
    98.  
    99.     float3 worldNorm = IN.worldNormal;
    100.  
    101.     worldNorm.xy -= n;
    102.  
    103.     float3 rdir = reflect (dir, worldNorm);                             // vettore riflesso da normale
    104.  
    105.    
    106.  
    107.     //BPCEM
    108.  
    109.     float3 nrdir = normalize (rdir);                                            // vettore riflesso normalizzato
    110.  
    111.     float3 rbmax = (_EnvBoxStart + _EnvBoxSize - IN.worldPos)/nrdir;            // AABB max value +...
    112.  
    113.     float3 rbmin = (_EnvBoxStart - IN.worldPos)/nrdir;                          // AABB min value +...
    114.  
    115.     float3 rbminmax = (nrdir>0.0f)?rbmax:rbmin;                                 // ...?
    116.  
    117.     float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z);                    // ...?
    118.  
    119.     float3 posonbox = IN.worldPos + nrdir*fa;                                   // ...?
    120.  
    121.     rdir = posonbox - (_EnvBoxStart +_EnvBoxSize/2);                            // ...? - posizione (centro) del box
    122.  
    123.     //PBCEM end
    124.  
    125.    
    126.  
    127.     float3 env = texCUBE (_Cube, rdir);
    128.  
    129.    
    130.  
    131.     float3 luminosity = float3 (0.30, 0.59, 0.11);
    132.  
    133.     float reflectivity = dot(luminosity, env.rgb);
    134.  
    135.     o.Emission = env.rgb *reflectivity *_ReflectColor;
    136.  
    137.    
    138.  
    139. }
    140.  
    141. ENDCG
    142.  
    143. }
    144.  
    145.  
    146.  
    147. FallBack "Reflective/VertexLit"
    148.  
    149. }
     
    Last edited: Jul 21, 2013
  2. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    Normally when people are having problems with the alpha channel not giving out any effect, it is not the shader, but the texture file having problems. If you are using photoshop files, it is CRUCIAL to have a "background layer" at the buttom of the layer stack. Unity have a choice when look at the content of the file. It can either use the summed transparency of the layer stack, or it can use the alpha channel. And the way it handles this is by the presence of a "background layer". If there is one, it will use the alpha channel. If there is none, it will use whatever summed transparency is present it the layer stack. And it seems this could be your problem.
    Select the buttom layer, and do this in the menu (if it doesnt say background in italic on the layer):

    Layer> New> Background from layer

    If this is not the problem, I can take a look at the shader. For now it just sounds more plausible the texture file is the problem :) If not, sorry for wasting your time with this long answer...
     
  3. Temporaro

    Temporaro

    Joined:
    Dec 21, 2012
    Posts:
    27
    I tried both ways of generating the alpha but there is no effect regardless. The mask works flawlessly in the standard Unity reflective shader but as soon as I change the shader to this one, the masking disappears. Thanks for your interest and help anyway.
     
  4. MADmarine

    MADmarine

    Joined:
    Aug 31, 2010
    Posts:
    627
    You're missing a few lines to activate alpha in the shader:

    Line 29 should be:
    Code (csharp):
    1.  
    2. Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    3.  
    Line 37 should be:
    Code (csharp):
    1.  
    2.  #pragma surface surf Lambert alpha
    3.  
    You also need to assign o.Alpha in your surf function, which I couldn't see happening.

    Insert on line 90 to get alpha from main texture and colour:
    Code (csharp):
    1.  
    2.   o.Alpha = c.a;
    3.  
     
    Last edited: May 30, 2013
  5. Temporaro

    Temporaro

    Joined:
    Dec 21, 2012
    Posts:
    27
    Thanks for the help MADmarine but I don't want to make a shader with alpha blending. The shader is opaque but reflective. I simply want an alpha map to modulate the strength of the reflection.
     
  6. Temporaro

    Temporaro

    Joined:
    Dec 21, 2012
    Posts:
    27
    ,
     
    Last edited: May 30, 2013
  7. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    Change line 33 to this:

    Code (csharp):
    1. float reflectivity = dot(luminosity, env.rgb)*c.a;
    ?
    As I'm not completely sure what the effect of this shader is, I have no idea if this does what you expect it to do. But at least now the fourth dimension of the texture color sample is taken into account on one of the components of the emission calculation. In the existing version of your shader the alpha component is not used anywhere, so no wonder no effect is present :)
     
    Last edited: Jun 3, 2013