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

Atmospheric Scattering help

Discussion in 'Shaders' started by PRD, Jul 29, 2008.

  1. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    I am trying to implement O'Neils Atmospheric Scattering but I am having no luck. Has anyone successfully implemented atmospheric scattering in Unity?

    Here is the results:



    Here is the code:

    Code (csharp):
    1.  
    2.  
    3. Shader "Test Shader" {
    4.   Properties {
    5.     _CameraPosition("Camera Position",Vector) = (0,0,0,0)
    6.     _LightDir("Light Direction",Vector) = (0,0,0,0)
    7.     _InvWaveLength("Inverse WaveLength",Color) = (0,0,0,0)
    8.     _CameraHeight("Camera Height",Float) = 0
    9.     _CameraHeight2("Camera Height2",Float) = 0
    10.     _OuterRadius("Outer Radius",Float) = 0
    11.     _OuterRadius2("Outer Radius 2",Float) = 0
    12.     _InnerRadius("Inner Radius",Float) = 0
    13.     _InnerRadius2("Inner Radius 2",Float) = 0
    14.     _KrESun("KrESun",Float) = 0
    15.     _KmESun("KmESun",Float) = 0
    16.     _Kr4PI("Kr4PI",Float) = 0
    17.     _Km4PI("Km4PI",Float) = 0
    18.     _Scale("Scale",Float) = 0
    19.     _ScaleDepth("Scale Depth",Float) = 0
    20.     _ScaleOverScaleDepth("Scale Over Scale Depth",Float) = 0
    21.     _Samples("Samples",Float) = 0
    22.     _G("G",Float) = 0
    23.     _G2("G2",Float) = 0
    24.   }
    25.   SubShader {
    26.     Pass {
    27.       Cull Front
    28.       Blend One One
    29.        
    30. CGPROGRAM
    31. #pragma vertex vert
    32. #pragma fragment frag
    33. #include "UnityCG.cginc"
    34.  
    35. float4 _CameraPosition;
    36. float4 _LightDir;
    37. float4 _InvWaveLength;
    38. float _CameraHeight;
    39. float _CameraHeight2;    
    40. float _OuterRadius;
    41. float _OuterRadius2;     
    42. float _InnerRadius;
    43. float _InnerRadius2;
    44. float _KrESun;
    45. float _KmESun;
    46. float _Kr4PI;
    47. float _Km4PI;
    48. float _Scale;
    49. float _ScaleDepth;
    50. float _ScaleOverScaleDepth;
    51. float _Samples;
    52. float _G;
    53. float _G2;
    54.  
    55. struct v2f {
    56.   float4 position : POSITION;
    57.   float3 c0 : COLOR0;
    58.   float3 c1 : COLOR1;
    59.   float3 t0 : TEXCOORD0;
    60. };
    61.  
    62. float getNearIntersection(float3 pos, float3 ray, float distance2, float radius2) {
    63.   float B = 2.0 * dot(pos, ray);
    64.   float C = distance2 - radius2;
    65.   float det = max(0.0, B*B - 4.0 * C);
    66.   return 0.5 * (-B - sqrt(det));
    67. }
    68.  
    69. float expScale (float cos) {
    70.     float x = 1 - cos;
    71.     return _ScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
    72. }
    73.  
    74. v2f vert (float4 vertex : POSITION) {  
    75.  
    76.   float3 pos = vertex.xyz;
    77.   float3 ray = pos - _CameraPosition.xyz;
    78.   float far = length(ray);
    79.      
    80.   ray /= far;  
    81.  
    82.   float B = 2.0 * dot(_CameraPosition.xyz,ray);
    83.   float C = _CameraHeight2 - _InnerRadius2;
    84.   float det = (B*B - 4.0 * C);
    85.   if (det >= 0) {
    86.     far = 0.5 * (-B - sqrt(det));
    87.   }  
    88.  
    89.   float near = getNearIntersection(_CameraPosition.xyz,ray,_CameraHeight2,_OuterRadius2);
    90.  
    91.   float3 start = _CameraPosition.xyz + ray * near;
    92.   far -= near;
    93.  
    94.   float startAngle = dot(ray,start) / _OuterRadius;
    95.   float startDepth = exp(-1.0 / _ScaleDepth);
    96.   float startOffset = startDepth * expScale(startAngle);
    97.   float sampleLength = far / _Samples;
    98.   float scaledLength = sampleLength * _Scale;
    99.   float3 sampleRay = ray * sampleLength;
    100.   float3 samplePoint = start + sampleRay * 0.5f;
    101.  
    102.   float3 frontColor = float3(0,0,0);
    103.  
    104.   for (int i = 0; i < 1; i++) {
    105.     float height = length (samplePoint);
    106.     float depth = exp(_ScaleOverScaleDepth * (_InnerRadius - height));
    107.     float lightAngle = dot(_LightDir.xyz, samplePoint) / height;
    108.     float cameraAngle = dot(-ray, samplePoint) / height;
    109.     float scatter = (startOffset + depth * (expScale (lightAngle) - expScale (cameraAngle)));
    110.  
    111.     float3 attenuate = exp(-scatter * (_InvWaveLength.xyz * _Kr4PI + _Km4PI));
    112.  
    113.     frontColor += attenuate * (depth * scaledLength);
    114.     samplePoint += sampleRay;
    115.   }
    116.  
    117.   v2f OUT;
    118.   OUT.position = mul( glstate.matrix.mvp, vertex);
    119.   OUT.t0 = _CameraPosition.xyz - vertex.xyz;
    120.   OUT.c0.rgb = frontColor * (_InvWaveLength.xyz * _KrESun);
    121.   OUT.c1.rgb = frontColor * _KmESun;
    122.   return OUT;
    123. }
    124.  
    125. float4 frag (v2f INPUT) : COLOR {
    126.   float cos = dot(_LightDir.xyz, INPUT.t0) / length(INPUT.t0);
    127.   float cos2 = cos * cos;
    128.   float miePhase = 1.5 * ((1.0 - _G2) / (2.0 + _G2)) * (1.0 + cos2) / pow(1.0 + _G2 - 2.0*_G*cos, 1.5);
    129.   float rayleighPhase = 0.75 * (1.0 + cos2);
    130.  
    131.   float4 fragColor;
    132.    
    133.   fragColor.xyz = (rayleighPhase * INPUT.c0) + (miePhase * INPUT.c1);
    134.   fragColor.w = fragColor.z;
    135.   return fragColor;
    136. }
    137.  
    138. ENDCG  
    139.     }
    140.   }
    141.   FallBack "None"
    142. }
    143.  
     
  2. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    Ok I found out that my cameraHeight2 wasnt being set correctly. Here is the results so far.

     
  3. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
  4. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Pretty nice! First time I tried it Safari crashed (I had 4 other tabs open, maybe it's time to upgrade this iMac to 2 GB of RAM?). Second time it worked nicely. Do you have antialiasing on? I think I saw some jaggies around the edge of the planet. Not too bad, just a minor thing.
     
  5. housewarmer

    housewarmer

    Joined:
    Apr 18, 2008
    Posts:
    74
    Pretty damn spectacular!
     
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    The edge glow is too bright IMO - needs to be lessened a bit. There should also (to be realistic) be a "halo" of atmosphere that fades more smoothly into space. Other than that it looks very nice.
     
  7. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    Thanks for the suggestions and thanks for looking at the demo.
     
  8. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    Here is the shader code:

    Code (csharp):
    1. Shader "AtmosphereFromSpace" {
    2.     Properties {
    3.       _CameraPosition("Camera Position",Vector) = (0,0,0,0)
    4.       _LightDir("Light Direction",Vector) = (0,0,0,0)
    5.       _InvWaveLength("Inverse WaveLength",Color) = (0,0,0,0)
    6.       _CameraHeight("Camera Height",Float) = 0
    7.       _CameraHeight2("Camera Height2",Float) = 0
    8.       _OuterRadius("Outer Radius",Float) = 0
    9.       _OuterRadius2("Outer Radius 2",Float) = 0
    10.       _InnerRadius("Inner Radius",Float) = 0
    11.       _InnerRadius2("Inner Radius 2",Float) = 0
    12.       _KrESun("KrESun",Float) = 0
    13.       _KmESun("KmESun",Float) = 0
    14.       _Kr4PI("Kr4PI",Float) = 0
    15.       _Km4PI("Km4PI",Float) = 0
    16.       _Scale("Scale",Float) = 0
    17.       _ScaleDepth("Scale Depth",Float) = 0
    18.       _ScaleOverScaleDepth("Scale Over Scale Depth",Float) = 0
    19.       _Samples("Samples",Float) = 0
    20.       _G("G",Float) = 0
    21.       _G2("G2",Float) = 0
    22.     }
    23.     SubShader {
    24.       Pass {
    25.         Cull Front
    26.         Blend One One
    27.        
    28. CGPROGRAM
    29. #pragma vertex vert
    30. #pragma fragment frag
    31. #include "UnityCG.cginc"
    32.  
    33. float4 _CameraPosition;
    34. float4 _LightDir;
    35. float4 _InvWaveLength;
    36. float _CameraHeight;
    37. float _CameraHeight2;    
    38. float _OuterRadius;
    39. float _OuterRadius2;     
    40. float _InnerRadius;
    41. float _InnerRadius2;
    42. float _KrESun;
    43. float _KmESun;
    44. float _Kr4PI;
    45. float _Km4PI;
    46. float _Scale;
    47. float _ScaleDepth;
    48. float _ScaleOverScaleDepth;
    49. float _Samples;
    50. float _G;
    51. float _G2;
    52.  
    53. struct v2f {
    54.   float4 position : POSITION;
    55.   float3 c0 : COLOR0;
    56.   float3 c1 : COLOR1;
    57.   float3 t0 : TEXCOORD0;
    58. };
    59.  
    60. float getNearIntersection(float3 pos, float3 ray, float distance2, float radius2) {
    61.   float B = 2.0 * dot(pos, ray);
    62.   float C = distance2 - radius2;
    63.   float det = max(0.0, B*B - 4.0 * C);
    64.   return 0.5 * (-B - sqrt(det));
    65. }
    66.  
    67. float expScale (float cos) {
    68.     float x = 1 - cos;
    69.     return _ScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
    70. }
    71.  
    72. v2f vert (float4 vertex : POSITION) {  
    73.   float3 pos = vertex.xyz;
    74.   float3 ray = pos - _CameraPosition.xyz;
    75.   float far = length(ray);
    76.   ray /= far;  
    77.  
    78.   float near = getNearIntersection(_CameraPosition.xyz,ray,_CameraHeight2,_OuterRadius2);
    79.   float3 start = _CameraPosition.xyz + ray * near;
    80.   far -= near;
    81.  
    82.   float startAngle = dot(ray,start) / _OuterRadius;
    83.   //float startDepth = exp (_ScaleOverScaleDepth * (_InnerRadius - _CameraHeight));
    84.   float startDepth = exp(-1.0 / _ScaleDepth);
    85.   float startOffset = startDepth * expScale(startAngle);
    86.   float sampleLength = far / _Samples;
    87.   float scaledLength = sampleLength * _Scale;
    88.   float3 sampleRay = ray * sampleLength;
    89.   float3 samplePoint = start + sampleRay * 0.5f;
    90.  
    91.   float3 frontColor = float3(0,0,0);
    92.   float3 attenuate;
    93.  
    94.   for (int i = 0; i < 1; i++) {
    95.     float height = length (samplePoint);
    96.     float depth = exp(_ScaleOverScaleDepth * (_InnerRadius - height));
    97.     float lightAngle = dot(_LightDir.xyz, samplePoint) / height;
    98.     float cameraAngle = dot(-ray, samplePoint) / height;
    99.     float scatter = (startOffset + depth * (expScale (lightAngle) - expScale (cameraAngle)));
    100.  
    101.     attenuate = exp(-scatter * (_InvWaveLength.xyz * _Kr4PI + _Km4PI));
    102.     frontColor += attenuate * (depth * scaledLength);
    103.     samplePoint += sampleRay;
    104.   }
    105.  
    106.   v2f OUT;
    107.   OUT.position = mul( glstate.matrix.mvp, vertex);
    108.   OUT.t0 = _CameraPosition.xyz - vertex.xyz;
    109.   OUT.c0.rgb = frontColor * (_InvWaveLength.xyz * _KrESun);
    110.   OUT.c1.rgb = frontColor * _KmESun;
    111.   return OUT;
    112. }
    113.  
    114. float4 frag (v2f INPUT) : COLOR {
    115.   float cos = dot(_LightDir.xyz, INPUT.t0) / length(INPUT.t0);
    116.   float cos2 = cos * cos;
    117.   float miePhase = 1.5 * ((1.0 - _G2) / (2.0 + _G2)) * (1.0 + cos2) / pow(1.0 + _G2 - 2.0*_G*cos, 1.5);
    118.   float rayleighPhase = 0.75 * (1.0 + cos2);
    119.   float4 fragColor;
    120.  
    121.   fragColor.xyz = (rayleighPhase * INPUT.c0) + (miePhase * INPUT.c1);
    122.   fragColor.w = fragColor.z;
    123.   return fragColor;
    124. }
    125.  
    126. ENDCG  
    127.       }
    128.     }
    129.     FallBack "None"
    130. }
    131.  
    Code (csharp):
    1. Shader "GroundFromSpace" {
    2.     Properties {
    3.       _CameraPosition("Camera Position",Vector) = (0,0,0,0)
    4.       _LightDir("Light Direction",Vector) = (0,0,0,0)
    5.       _InvWaveLength("Inverse WaveLength",Color) = (0,0,0,0)
    6.       _CameraHeight("Camera Height",Float) = 0
    7.       _CameraHeight2("Camera Height2",Float) = 0
    8.       _OuterRadius("Outer Radius",Float) = 0
    9.       _OuterRadius2("Outer Radius 2",Float) = 0
    10.       _InnerRadius("Inner Radius",Float) = 0
    11.       _InnerRadius2("Inner Radius 2",Float) = 0
    12.       _KrESun("KrESun",Float) = 0
    13.       _KmESun("KmESun",Float) = 0
    14.       _Kr4PI("Kr4PI",Float) = 0
    15.       _Km4PI("Km4PI",Float) = 0
    16.       _Scale("Scale",Float) = 0
    17.       _ScaleDepth("Scale Depth",Float) = 0
    18.       _ScaleOverScaleDepth("Scale Over Scale Depth",Float) = 0
    19.       _Samples("Samples",Float) = 0
    20.       _G("G",Float) = 0
    21.       _G2("G2",Float) = 0
    22.     }
    23.     SubShader {
    24.       Pass {
    25.         Cull Back
    26.         Blend SrcAlpha OneMinusSrcAlpha    
    27.        
    28. CGPROGRAM
    29. #pragma vertex vert
    30. #pragma fragment frag
    31. #include "UnityCG.cginc"
    32.  
    33. float4 _CameraPosition;
    34. float4 _LightDir;
    35. float4 _InvWaveLength;
    36. float _CameraHeight;
    37. float _CameraHeight2;    
    38. float _OuterRadius;
    39. float _OuterRadius2;     
    40. float _InnerRadius;
    41. float _InnerRadius2;
    42. float _KrESun;
    43. float _KmESun;
    44. float _Kr4PI;
    45. float _Km4PI;
    46. float _Scale;
    47. float _ScaleDepth;
    48. float _ScaleOverScaleDepth;
    49. float _Samples;
    50. float _G;
    51. float _G2;
    52.  
    53. struct v2f {
    54.   float4 position : POSITION;
    55.   float3 c0 : COLOR0;
    56.   float3 c1 : COLOR1;
    57. };
    58.  
    59. float expScale (float cos) {
    60.     float x = 1 - cos;
    61.     return _ScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
    62. }
    63.  
    64. v2f vert (float4 vertex : POSITION) {  
    65.   float3 pos = vertex.xyz;
    66.   float3 ray = pos - _CameraPosition.xyz;
    67.   float far = length(ray);
    68.      
    69.   ray /= far;  
    70.  
    71.   float B = 2.0 * dot(_CameraPosition.xyz, ray);
    72.   float C = _CameraHeight2 - _OuterRadius2;
    73.   float det = max(0.0, B*B - 4.0 * C);
    74.   float near =  0.5 * (-B - sqrt(det));
    75.  
    76.   float3 start = _CameraPosition.xyz + ray * near;
    77.   far -= near;
    78.  
    79.   float startAngle = dot(ray,start) / _OuterRadius;
    80.   float startDepth = exp ((_InnerRadius - _OuterRadius) / _ScaleDepth);
    81.   float cameraAngle = dot(-ray, pos) / length(pos);
    82.  
    83.   float lightAngle = dot(_LightDir.xyz, pos) / length(pos);
    84.  
    85.   float cameraScale = expScale(cameraAngle);
    86.  
    87.   float lightScale = expScale(lightAngle);
    88.  
    89.   float cameraOffset = startDepth*cameraScale;
    90.  
    91.   float temp = (lightScale + cameraScale);
    92.  
    93.  
    94.  
    95.   float sampleLength = far / _Samples;
    96.  
    97.   float scaledLength = sampleLength * _Scale;
    98.  
    99.   float3 sampleRay = ray * sampleLength;
    100.  
    101.   float3 samplePoint = start + sampleRay * 0.5;
    102.  
    103.  
    104.  
    105.   float3 frontColor = float3(0.0, 0.0, 0.0);
    106.  
    107.   float3 attenuate;
    108.  
    109.  
    110.   for(int i=0; i<2; i++) {
    111.  
    112.     float height = length(samplePoint);
    113.  
    114.     float depth = exp(_ScaleOverScaleDepth * (_InnerRadius - height));
    115.  
    116.     float scatter = depth*temp - cameraOffset;
    117.  
    118.     attenuate = exp(-scatter * (_InvWaveLength.xyz * _Kr4PI + _Km4PI));
    119.  
    120.     frontColor += attenuate * (depth * scaledLength);
    121.  
    122.     samplePoint += sampleRay;
    123.  
    124.   }
    125.  
    126.   v2f OUT;
    127.   OUT.position = mul(glstate.matrix.mvp, vertex);
    128.   OUT.c0.rgb = frontColor * (_InvWaveLength.xyz * _KrESun + _KmESun);
    129.   OUT.c1.rgb = attenuate;
    130.  
    131.   return OUT;
    132. }
    133.  
    134. float4 frag (v2f INPUT) : COLOR {
    135.   float4 fragColor;
    136.  
    137.   fragColor.xyz = INPUT.c0 + 0.25 * INPUT.c1;
    138.   fragColor.w = fragColor.z;
    139.   return fragColor;
    140. }
    141.  
    142. ENDCG  
    143.       }
    144.     }
    145.     FallBack "None"
    146. }
    147.  
     
  9. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Thanks very much for sharing! If you get a moment, this would be a very nice addition to the Wiki!
     
  10. NathanWarden

    NathanWarden

    Joined:
    Oct 4, 2005
    Posts:
    663
    Yeah, looks great!
     
  11. Alpha-Loup

    Alpha-Loup

    Joined:
    Jun 23, 2006
    Posts:
    797
    Very nice work! I especially like the color-effects at the light / dark transitions.

    And thanks for sharing.

    Cheers!

    Frank
     
  12. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Nice effect, very impressive!
     
  13. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Fantastic shaders, I was looking for that for a while!

    It would be great to have a script that sets automatically the camera and the sun into the shaders, so if the camera moves, the datas will be refreshed... or if you ware very close to the sphere, it switches to the ground shaders automatically!

    THANKS A LOT for sharing!
     
  14. ClamsTheCat

    ClamsTheCat

    Joined:
    Apr 16, 2008
    Posts:
    57
    where do you include the textures with these shaders?
     
  15. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
  16. ClamsTheCat

    ClamsTheCat

    Joined:
    Apr 16, 2008
    Posts:
    57
    I realize that they don't have shaders in the posted shaders. I was referring to how in the demo the planet has an earth texture, but the shaders provided do not allow you to place a texture on the material. Were the posted shaders what was used in the demo?
     
  17. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    The posted shaders are just for the atmosphere. You can use the built-in diffuse or specular shaders for the planet's surface. To ensure that the planet is rendered behind the atmosphere, it looks like PRD used a separate camera to render it first.
     
  18. ClamsTheCat

    ClamsTheCat

    Joined:
    Apr 16, 2008
    Posts:
    57
    I must have misunderstood because one of the shaders was called "GroundFromSpace" or something to that effect.
     
  19. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    Daniel Brauer is correct. The earth textures are on another mesh.

    ((()))

    The earth textures are applied to the inner most mesh (the blue circle), the ground shader is applied the the middle mesh (the red circle) and the atmosphere shader is applied to the outer mesh (the indigo circle).

    The final result of shader is shown on http://climate.jpl.nasa.gov/Eyes/eyes.html

    I hope this helps.

    --PRD
     
  20. ClamsTheCat

    ClamsTheCat

    Joined:
    Apr 16, 2008
    Posts:
    57
    I have 3 sphere meshes each slightly larger than another. I apply the 3 shaders in the order you stated but it looks nothing like your result. Do I need some sort of funky camera masking to get this affect to look like yours? Do you have an example scene of some kind available?

    Thanks!
     
  21. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    Sure let me package something up. I will have to do it when I have free time at work, since it was done at work. :)
     
  22. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    Here is that example I promised. Sorry for taking so long. You can simplify the script that sends values to the shader by using the globals available to you like camera position and light position. This was one of the first shaders I wrote for Unity. I hope this helps.

    Just like Daniel Brauer said, documentation on the shader is found here:
    http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html

    --PRD
     

    Attached Files:

  23. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
  24. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
  25. PRD

    PRD

    Joined:
    Jan 31, 2008
    Posts:
    29
    After Unite, my coworker and I wanted to reduce the amount of cameras we use in our project. He used a separate camera for the stars and I used a separate camera for the ground mesh. If you used my example atmospheric scattering project, you probably noticed I have an extra "Ground" camera that rendered the ground mesh, as well as a couple layers to deal with. I managed to simplify the setup to just one camera and no layers.

    We got the idea from one of the talks, I believe it was the Star Wars Trench Talk, at Unite 09.

    I will post an updated project as soon as I can.

    --PRD
     
  26. ClamsTheCat

    ClamsTheCat

    Joined:
    Apr 16, 2008
    Posts:
    57
    Thanks PRD!
     
  27. NodMan

    NodMan

    Joined:
    Apr 22, 2009
    Posts:
    15
    When i set model like you say i see the blue ball. But defuse material disapear from stage.

    HOW IT'S f WORK?! Its for UNITY PRO or not? Can you post some sample stage on unity? I don't understand where i can take parameters for shader. What is "camera height" and "camera height 2"? How i can measure that parameters (in meters, yards or in parsecs)?
     
  28. jeffro11

    jeffro11

    Joined:
    Jan 7, 2010
    Posts:
    185
  29. NodMan

    NodMan

    Joined:
    Apr 22, 2009
    Posts:
    15
  30. Xsnip3rX

    Xsnip3rX

    Joined:
    Aug 29, 2009
    Posts:
    197
    hi im fairly new to unity and was wondering what the values to get this working are?
     
  31. FreelanzerDK

    FreelanzerDK

    Joined:
    Feb 2, 2010
    Posts:
    10
    Hmmm.. I seem to have some issues with the GroundFromSpace shader.

    Problem explained:
    When I disable the "sphere" GameObject I get the full look of the shader, but when I make the "sphere" visible it sort of renders above the GroundFromSpace shader making it impossible to see.
    To test this further I tried to create a new GameObject sphere as a sort of moon.
    I disabled the view of the "sphere" object to make the GroundFromSpace shader come forward again and if I place the moon behind the GroundFromSpace shader it will disappear, as if the black part or the shader isn't transparent.

    Note:
    The skybox seems to get rendered correctly through the GroundFromSpace shader but not other GameObjects.

    Image:


    Question:
    How can I solve this so I can have a diffuse material below the GroundFromSpace shader with an earth texture?
     
  32. FreelanzerDK

    FreelanzerDK

    Joined:
    Feb 2, 2010
    Posts:
    10
    ^^ Bump

    Is additional information needed before anyone can help out?
     
  33. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Please post your project and I will fix it. You have to change the shader so it will render transparently.
    It's been a while since I have worked on this shader, but I remember having the same issue and have to match it with a transparent shader...
     
  34. FreelanzerDK

    FreelanzerDK

    Joined:
    Feb 2, 2010
    Posts:
    10
    Sent you a PM with the scene I'm working on Nikko. :)
     
  35. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Check in PM
     
  36. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Fixed : Check in PM
     

    Attached Files:

  37. FreelanzerDK

    FreelanzerDK

    Joined:
    Feb 2, 2010
    Posts:
    10
    Yeah it looks great now but isn't there a way to add shadows to the unlit part?
    Like a normal Diffuse shader would do.
    It looks so perfect but the lack of shadows on the unlit side kind of ruins the look. :cry:
     
  38. naspino

    naspino

    Joined:
    Feb 14, 2010
    Posts:
    5
    Nikko,

    Could you post the updated ground shader which does the transparency?

    [Edit]

    I added the following to the shader and it seemed to make a big difference, is this the fix?

    Tags {"Queue" = "Transparent" }
     
  39. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    I got several requests in private so I decided to make a commercial version to justify the work put into it.

    Features:
    - day / night (when the Earth rotates, the cities are lightning on and off smoothly)
    - relief shader
    - 2 atmosphere shaders (1 realistic and one with a much larger halo)
    - clouds layer with 4 different cloud maps
    - hi-resolution 4096x4096 maps for everything, lossless.
    - several new parameters into the scripts to change the relief, raleight, phase, daylight, nightlight etc...
    - maps rotation scripts
    - several 4096x4096 realistic space skyboxes
    - works with Indie Pro.

    Support, doc, video etc...

    It will be cheap :)

    Note: I've also licensed the Spaceships (Frigate, Mothership, and others) I used in some video to release them ready for gaming...
     

    Attached Files:

  40. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Looking great!

    Hope you resolved the scale / world position issues. Have done the same myself, but only after the small surprise of moving the earth and seeing the effect disappear :eek:

    Forget what we did there to fix it, but if pressed, could probably dig it up.
     
  41. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    You cannot rotate the sphere, you have to offset the textures, same result visually.
     
    Last edited: Jan 5, 2011
  42. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Was referring not to rotation (easy enough to resolve) but rather the "scale / world position" issues; if I recall, by default, the effect fails if the planet is anywhere other than 0,0,0 and there were some strange scale issues as well.

    As mentioned, already managed to sort them out, but if you're maintaining the code charging for it, might be nice to include similar fixes.
     
  43. nikko

    nikko

    Joined:
    Mar 20, 2009
    Posts:
    436
    Did you successfully solved the rotation issue ( I haven't)
    The scale issue is not really an issue, you have to change proportionally the inside and outside bounds of the ground and atmosphere shaders.
    ( scale : 1000, in 995, out 1100 / scale 500, in 497, out 1050 as an example)
    To resume, if you x2 the size you have to x2 the in and out of the ground and atmosphere.
     
  44. jzaun

    jzaun

    Joined:
    Feb 20, 2010
    Posts:
    26
    Hows this coming? from the images it looks amazing. Nikko - any word on when this will be up for purchase or how much it will cost/license/etc?
     
  45. jc_lvngstn

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508
    Awesome work!
    I don't suppose anyone could post some sample parameters to use, or such? Having trouble getting anything but a black ball.
     
  46. m-a

    m-a

    Joined:
    Apr 28, 2010
    Posts:
    2
  47. Xsnip3rX

    Xsnip3rX

    Joined:
    Aug 29, 2009
    Posts:
    197
  48. jc_lvngstn

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508
    This would be even MORE awesome
    if someone would post a sample project, with values used, for the shaders.
     
  49. gonza

    gonza

    Joined:
    May 9, 2010
    Posts:
    9
    Cool stuff!
    I tryed modified this PRD shader to atmospheric scattering from groung but fail ))
    How port this shader to unity, using PRD shader work ?


    Its original glsl shader "SkyFromAtmosphere"

    Code (csharp):
    1. //
    2. // Atmospheric scattering vertex shader
    3. //
    4. // Author: Sean O'Neil
    5. //
    6. // Copyright (c) 2004 Sean O'Neil
    7. //
    8.  
    9. uniform vec3 v3CameraPos;       // The camera's current position
    10. uniform vec3 v3LightPos;        // The direction vector to the light source
    11. uniform vec3 v3InvWavelength;   // 1 / pow(wavelength, 4) for the red, green, and blue channels
    12. uniform float fCameraHeight;    // The camera's current height
    13. uniform float fCameraHeight2;   // fCameraHeight^2
    14. uniform float fOuterRadius;     // The outer (atmosphere) radius
    15. uniform float fOuterRadius2;    // fOuterRadius^2
    16. uniform float fInnerRadius;     // The inner (planetary) radius
    17. uniform float fInnerRadius2;    // fInnerRadius^2
    18. uniform float fKrESun;          // Kr * ESun
    19. uniform float fKmESun;          // Km * ESun
    20. uniform float fKr4PI;           // Kr * 4 * PI
    21. uniform float fKm4PI;           // Km * 4 * PI
    22. uniform float fScale;           // 1 / (fOuterRadius - fInnerRadius)
    23. uniform float fScaleDepth;      // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
    24. uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
    25.  
    26. uniform int nSamples;
    27. uniform float fSamples;
    28.  
    29. varying vec3 v3Direction;
    30.  
    31.  
    32. float scale(float fCos)
    33. {
    34.     float x = 1.0 - fCos;
    35.     return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
    36. }
    37.  
    38. void main(void)
    39. {
    40.     // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
    41.     vec3 v3Pos = gl_Vertex.xyz;
    42.     vec3 v3Ray = v3Pos - v3CameraPos;
    43.     float fFar = length(v3Ray);
    44.     v3Ray /= fFar;
    45.  
    46.     // Calculate the ray's starting position, then calculate its scattering offset
    47.     vec3 v3Start = v3CameraPos;
    48.     float fHeight = length(v3Start);
    49.     float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fCameraHeight));
    50.     float fStartAngle = dot(v3Ray, v3Start) / fHeight;
    51.     float fStartOffset = fDepth*scale(fStartAngle);
    52.  
    53.     // Initialize the scattering loop variables
    54.     //gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
    55.     float fSampleLength = fFar / fSamples;
    56.     float fScaledLength = fSampleLength * fScale;
    57.     vec3 v3SampleRay = v3Ray * fSampleLength;
    58.     vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
    59.  
    60.     // Now loop through the sample rays
    61.     vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
    62.     for(int i=0; i<nSamples; i++)
    63.     {
    64.         float fHeight = length(v3SamplePoint);
    65.         float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
    66.         float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
    67.         float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
    68.         float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle)));
    69.         vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
    70.         v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
    71.         v3SamplePoint += v3SampleRay;
    72.     }
    73.  
    74.     // Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
    75.     gl_FrontSecondaryColor.rgb = v3FrontColor * fKmESun;
    76.     gl_FrontColor.rgb = v3FrontColor * (v3InvWavelength * fKrESun);
    77.     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    78.     v3Direction = v3CameraPos - v3Pos;
    79. }
    80.  
    Code (csharp):
    1. //
    2. // Atmospheric scattering fragment shader
    3. //
    4. // Author: Sean O'Neil
    5. //
    6. // Copyright (c) 2004 Sean O'Neil
    7. //
    8.  
    9. uniform vec3 v3LightPos;
    10. uniform float g;
    11. uniform float g2;
    12.  
    13. varying vec3 v3Direction;
    14.  
    15.  
    16. void main (void)
    17. {
    18.     float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
    19.     float fRayleighPhase = 0.75 * (1.0 + fCos*fCos);
    20.     float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
    21.     gl_FragColor = fRayleighPhase * gl_Color + fMiePhase * gl_SecondaryColor;
    22.     //gl_FragColor.a = gl_FragColor.b;
    23. }
    Its sources from GpuGems2 ch 16
    http://http.download.nvidia.com/developer/GPU_Gems_2/CD/Content/16.zip
     
  50. gonza

    gonza

    Joined:
    May 9, 2010
    Posts:
    9
    Well done its "work" ))
    But i dont know true parameters for c# script
    Math is not my hobby ))

    Code (csharp):
    1. Shader "AtmosphereFromEarth" {
    2.     Properties {
    3.       _v4CameraPos("Camera Position",Vector) = (0,0,0,0)
    4.       _v4LightDir("Light Direction",Vector) = (0,0,0,0)
    5.       _cInvWaveLength("Inverse WaveLength",Color) = (0,0,0,0)
    6.       _fCameraHeight("Camera Height",Float) = 0
    7.       _fCameraHeight2("Camera Height2",Float) = 0
    8.       _fOuterRadius("Outer Radius",Float) = 0
    9.       _fOuterRadius2("Outer Radius 2",Float) = 0
    10.       _fInnerRadius("Inner Radius",Float) = 0
    11.       _fInnerRadius2("Inner Radius 2",Float) = 0
    12.       _fKrESun("KrESun",Float) = 0
    13.       _fKmESun("KmESun",Float) = 0
    14.       _fKr4PI("Kr4PI",Float) = 0
    15.       _fKm4PI("Km4PI",Float) = 0
    16.       _fScale("Scale",Float) = 0
    17.       _fScaleDepth("Scale Depth",Float) = 0
    18.       _fScaleOverScaleDepth("Scale Over Scale Depth",Float) = 0
    19.       _Samples("Samples",Float) = 0
    20.       _G("G",Float) = 0
    21.       _G2("G2",Float) = 0
    22.     }
    23.     SubShader {
    24.       Tags {"Queue" = "Transparent" }
    25.       Pass {
    26.         Cull Front
    27.         Blend One One
    28.        
    29. CGPROGRAM
    30. #pragma vertex vert
    31. #pragma fragment frag
    32. #include "UnityCG.cginc"
    33.  
    34. float4 _v4CameraPos;
    35. float4 _v4LightDir;
    36. float4 _cInvWaveLength;
    37. float _fCameraHeight;
    38. float _fCameraHeight2;   
    39. float _fOuterRadius;
    40. float _fOuterRadius2;    
    41. float _fInnerRadius;
    42. float _fInnerRadius2;
    43. float _fKrESun;
    44. float _fKmESun;
    45. float _fKr4PI;
    46. float _fKm4PI;
    47. float _fScale;
    48. float _fScaleDepth;
    49. float _fScaleOverScaleDepth;
    50. float _Samples;
    51. float _G;
    52. float _G2;
    53.  
    54. struct v2f {
    55.   float4 position : POSITION;
    56.   float3 c0 : COLOR0;
    57.   float3 c1 : COLOR1;
    58.   float3 t0 : TEXCOORD0;
    59. };
    60.  
    61.  
    62. float expScale (float cos) {
    63.     float x = 1 - cos;
    64.     return _fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
    65. }
    66.  
    67. v2f vert (float4 vertex : POSITION) {  
    68.   float3 v3Pos = vertex.xyz;
    69.   float3 v3Ray = v3Pos - _v4CameraPos.xyz;
    70.   float fFar = length(v3Ray);
    71.   v3Ray /= fFar;   
    72.  
    73.  // Calculate the ray's starting position, then calculate its scattering offset
    74. float3 v3Start = v3Pos;
    75. float v3StartAngle = dot(v3Ray,v3Start) / _fOuterRadius;
    76. float v3StartDepth = exp (_fScaleOverScaleDepth * (_fInnerRadius - _fCameraHeight));
    77. float v3StartOffset = v3StartDepth * expScale(v3StartAngle);
    78.  
    79.   float fSampleLength = fFar / _Samples;
    80.   float fScaledLength = fSampleLength * _fScale;
    81.   float3 sampleRay = v3Ray * fSampleLength;
    82.   float3 samplePoint = v3Start + sampleRay * 0.5f;
    83.  
    84.   float3 frontColor = float3(0,0,0);
    85.   float3 attenuate;
    86.  
    87.   for (int i = 0; i < 1; i++) {
    88.     float height = length (samplePoint);
    89.     float depth = exp(_fScaleOverScaleDepth * (_fInnerRadius - height));
    90.     float lightAngle = dot(_v4LightDir.xyz, samplePoint) / height;
    91.     float cameraAngle = dot(-v3Ray, samplePoint) / height;
    92.     float scatter = (v3StartOffset + depth * (expScale (lightAngle) - expScale (cameraAngle)));
    93.  
    94.     attenuate = exp(-scatter * (_cInvWaveLength.xyz * _fKr4PI + _fKm4PI));
    95.     frontColor += attenuate * (depth * fScaledLength);
    96.     samplePoint += sampleRay;
    97.   }
    98.  
    99.   v2f OUT;
    100.   OUT.position = mul( glstate.matrix.mvp, vertex);
    101.   OUT.t0 = _v4CameraPos.xyz - vertex.xyz;
    102.   OUT.c0.rgb = frontColor * (_cInvWaveLength.xyz * _fKrESun);
    103.   OUT.c1.rgb = frontColor * _fKmESun;
    104.   return OUT;
    105. }
    106. ////// SkyFromAtmos(Space) frag
    107. float4 frag (v2f INPUT) : COLOR {
    108.   float cos = dot(_v4LightDir.xyz, INPUT.t0) / length(INPUT.t0);
    109.   float cos2 = cos * cos;
    110.   float miePhase = 1.5 * ((1.0 - _G2) / (2.0 + _G2)) * (1.0 + cos2) / pow(1.0 + _G2 - 2.0*_G*cos, 1.5);
    111.   float rayleighPhase = 0.75 * (1.0 + cos2);
    112.   float4 fragColor;
    113.  
    114.   fragColor.xyz = (rayleighPhase * INPUT.c0) + (miePhase * INPUT.c1);
    115.   fragColor.w = fragColor.z;
    116.   return fragColor;
    117. }
    118.  
    119. ENDCG  
    120.       }
    121.     }
    122.     FallBack "None"
    123. }
    124.