Search Unity

Sphere Projected Cubemapping or Parallax Corrected Cubemap on a Sphere Volume

Discussion in 'Shaders' started by Harry64, Mar 15, 2014.

  1. Harry64

    Harry64

    Joined:
    Jan 21, 2013
    Posts:
    18
    I have tryed to get the Sphere Projected Cubemapping working in my shader.

    but I failed at it and thats because I think that the math described on the internet for this is not 100% correct or a part is missing. (or I am too stupid...)

    It should work like the Box Projected Cubemapping described in this post:
    http://forum.unity3d.com/threads/113784-Has-any-one-experimented-with-Box-Projection-Correction-Environment-Mapping

    but instead using a AABB volume I would use just a Sphere Volume.

    the math description is from this site. (you need to scroll down after half of the page.)
    http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/

    here is a picture that should show how it should work.
    $howitworks_01.png

    V = View Direction
    N = Normal Vector
    R = Reflect Direction
    P = Intersection Point
    C = The position where the cubemap was rendered
    D = the corrected Vector

    and the original math for this is:
    D = normalize(K * (Pp - C) + R)
    or this

    ReflDirectionWS= EnvMapOffset * (PositionWS - CubemapPositionWS) + ReflDirectionWS;

    I am not good at shader coding so I played around with the code but all I get is pinched to a point mirrors or way too big mirrors or almost perfect mapped cubemap without mirroring so like you would put a the same texture over a texture....
    it should look like the Box Projected Cubemap so when a mirroring object gets to the edge of the sphere volume it should look like the object would be next to a wall. but I cant get it to work...

    the only thing this code does correct is the positioning of the cubemap. this seems to work. but the reflection and the resizing dont work...

    here is the important part of my shader.
    I give my shader the info where in world space the cubemap was recorded, then the position of the sphere volumen and then how big the radius is.
    I hope some of you can correct my code so that it works.

    Code (csharp):
    1.  
    2.     CGPROGRAM
    3.     #pragma surface surf BlinnPhong
    4.     #pragma target 3.0
    5.      
    6.     sampler2D _MainTex;
    7.     sampler2D _BumpMap;
    8.     samplerCUBE _Cube;
    9.    
    10.     fixed4 _CubemapPos;
    11.     fixed4 _SpherePos;
    12.     float _SphereSize;
    13.      
    14.     struct Input {
    15.         float2 uv_MainTex;
    16.         float2 uv_BumpMap;
    17.         float3 viewDir;
    18.         fixed3 worldPos;
    19.         float3 worldRefl;
    20.         fixed3 worldNormal;
    21.         INTERNAL_DATA
    22.     };
    23.  
    24.        
    25.        
    26.     void surf (Input IN, inout SurfaceOutput o) {
    27.  
    28.         fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    29.         fixed4 c = tex * _Color;
    30.  
    31.         o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    32.        
    33.         float3 dir = IN.worldPos - _WorldSpaceCameraPos;
    34.         float3 worldNorm = WorldNormalVector (IN, o.Normal);
    35.  
    36.     float4 env = texCUBE (_Cube, ((IN.worldPos - _CubemapPos) + reflect (dir, worldNorm)) *  (1/_SphereSize));
    37.  
     
    Last edited: Mar 15, 2014