Guest User

SkyboxProceduralStars.shader

a guest
Jan 21st, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "Custom/SkyboxProceduralStars"
  2. {
  3.     Properties {
  4.     [KeywordEnum(None, Simple, High Quality)] _SunDisk ("Sun", Int) = 2
  5.     _SunSize ("Sun Size", Range(0,1)) = 0.04
  6.     _SunSizeConvergence("Sun Size Convergence", Range(1,10)) = 5
  7.  
  8.     _AtmosphereThickness ("Atmosphere Thickness", Range(0,5)) = 1.0
  9.     _SkyTint ("Sky Tint", Color) = (.5, .5, .5, 1)
  10.     _GroundColor ("Ground", Color) = (.369, .349, .341, 1)
  11.  
  12.     _Exposure("Exposure", Range(0, 8)) = 1.3
  13.  
  14.     _StarDensity("Star Density", Range(0, 100)) = 5.0
  15.     _StarBrightness("Star Brightness", Range(0,100)) = 2.0
  16.     _TwinkleSpeed("Twinkle Speed", Range(0, 1.0)) = 0.5
  17. }
  18.  
  19. SubShader {
  20.     Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
  21.     Cull Off ZWrite Off
  22.  
  23.     Pass {
  24.  
  25.         CGPROGRAM
  26.         #pragma vertex vert
  27.         #pragma fragment frag
  28.  
  29.         #include "UnityCG.cginc"
  30.         #include "Lighting.cginc"
  31.  
  32.         #pragma multi_compile _SUNDISK_NONE _SUNDISK_SIMPLE _SUNDISK_HIGH_QUALITY
  33.  
  34.         uniform half _Exposure;     // HDR exposure
  35.         uniform half3 _GroundColor;
  36.         uniform half _SunSize;
  37.         uniform half _SunSizeConvergence;
  38.         uniform half3 _SkyTint;
  39.         uniform half _AtmosphereThickness;
  40.         uniform float _StarDensity;
  41.         uniform float _StarBrightness;
  42.         uniform float _TwinkleSpeed;
  43.  
  44.     #if defined(UNITY_COLORSPACE_GAMMA)
  45.         #define GAMMA 2
  46.         #define COLOR_2_GAMMA(color) color
  47.         #define COLOR_2_LINEAR(color) color*color
  48.         #define LINEAR_2_OUTPUT(color) sqrt(color)
  49.     #else
  50.         #define GAMMA 2.2
  51.         // HACK: to get gfx-tests in Gamma mode to agree until UNITY_ACTIVE_COLORSPACE_IS_GAMMA is working properly
  52.         #define COLOR_2_GAMMA(color) ((unity_ColorSpaceDouble.r>2.0) ? pow(color,1.0/GAMMA) : color)
  53.         #define COLOR_2_LINEAR(color) color
  54.         #define LINEAR_2_LINEAR(color) color
  55.     #endif
  56.  
  57.         // RGB wavelengths
  58.         // .35 (.62=158), .43 (.68=174), .525 (.75=190)
  59.         static const float3 kDefaultScatteringWavelength = float3(.65, .57, .475);
  60.         static const float3 kVariableRangeForScatteringWavelength = float3(.15, .15, .15);
  61.  
  62.         #define OUTER_RADIUS 1.025
  63.         static const float kOuterRadius = OUTER_RADIUS;
  64.         static const float kOuterRadius2 = OUTER_RADIUS*OUTER_RADIUS;
  65.         static const float kInnerRadius = 1.0;
  66.         static const float kInnerRadius2 = 1.0;
  67.  
  68.         static const float kCameraHeight = 0.0001;
  69.  
  70.         #define kRAYLEIGH (lerp(0.0, 0.0025, pow(_AtmosphereThickness,2.5)))      // Rayleigh constant
  71.         #define kMIE 0.0010             // Mie constant
  72.         #define kSUN_BRIGHTNESS 20.0    // Sun brightness
  73.  
  74.         #define kMAX_SCATTER 50.0 // Maximum scattering value, to prevent math overflows on Adrenos
  75.  
  76.         static const half kHDSundiskIntensityFactor = 15.0;
  77.         static const half kSimpleSundiskIntensityFactor = 27.0;
  78.  
  79.         static const half kSunScale = 400.0 * kSUN_BRIGHTNESS;
  80.         static const float kKmESun = kMIE * kSUN_BRIGHTNESS;
  81.         static const float kKm4PI = kMIE * 4.0 * 3.14159265;
  82.         static const float kScale = 1.0 / (OUTER_RADIUS - 1.0);
  83.         static const float kScaleDepth = 0.25;
  84.         static const float kScaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25;
  85.         static const float kSamples = 2.0; // THIS IS UNROLLED MANUALLY, DON'T TOUCH
  86.  
  87.         #define MIE_G (-0.990)
  88.         #define MIE_G2 0.9801
  89.  
  90.         #define SKY_GROUND_THRESHOLD 0.02
  91.  
  92.         // fine tuning of performance. You can override defines here if you want some specific setup
  93.         // or keep as is and allow later code to set it according to target api
  94.  
  95.         // if set vprog will output color in final color space (instead of linear always)
  96.         // in case of rendering in gamma mode that means that we will do lerps in gamma mode too, so there will be tiny difference around horizon
  97.         // #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 0
  98.  
  99.         // sun disk rendering:
  100.         // no sun disk - the fastest option
  101.         #define SKYBOX_SUNDISK_NONE 0
  102.         // simplistic sun disk - without mie phase function
  103.         #define SKYBOX_SUNDISK_SIMPLE 1
  104.         // full calculation - uses mie phase function
  105.         #define SKYBOX_SUNDISK_HQ 2
  106.  
  107.         // uncomment this line and change SKYBOX_SUNDISK_SIMPLE to override material settings
  108.         // #define SKYBOX_SUNDISK SKYBOX_SUNDISK_SIMPLE
  109.  
  110.     #ifndef SKYBOX_SUNDISK
  111.         #if defined(_SUNDISK_NONE)
  112.             #define SKYBOX_SUNDISK SKYBOX_SUNDISK_NONE
  113.         #elif defined(_SUNDISK_SIMPLE)
  114.             #define SKYBOX_SUNDISK SKYBOX_SUNDISK_SIMPLE
  115.         #else
  116.             #define SKYBOX_SUNDISK SKYBOX_SUNDISK_HQ
  117.         #endif
  118.     #endif
  119.  
  120.     #ifndef SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
  121.         #if defined(SHADER_API_MOBILE)
  122.             #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 1
  123.         #else
  124.             #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 0
  125.         #endif
  126.     #endif
  127.  
  128.         // Calculates the Rayleigh phase function
  129.         half getRayleighPhase(half eyeCos2)
  130.         {
  131.             return 0.75 + 0.75*eyeCos2;
  132.         }
  133.         half getRayleighPhase(half3 light, half3 ray)
  134.         {
  135.             half eyeCos = dot(light, ray);
  136.             return getRayleighPhase(eyeCos * eyeCos);
  137.         }
  138.  
  139.  
  140.         struct appdata_t
  141.         {
  142.             float4 vertex : POSITION;
  143.             float2 uv : TEXCOORD0;
  144.             UNITY_VERTEX_INPUT_INSTANCE_ID
  145.         };
  146.  
  147.         struct v2f
  148.         {
  149.             float4  pos             : SV_POSITION;
  150.             float2 uv : TEXCOORD0;
  151.  
  152.         #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ
  153.             // for HQ sun disk, we need vertex itself to calculate ray-dir per-pixel
  154.             float3  vertex          : TEXCOORD4;
  155.         #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
  156.             half3   rayDir          : TEXCOORD0;
  157.         #else
  158.             // as we dont need sun disk we need just rayDir.y (sky/ground threshold)
  159.             half    skyGroundFactor : TEXCOORD0;
  160.         #endif
  161.  
  162.             // calculate sky colors in vprog
  163.             half3   groundColor     : TEXCOORD1;
  164.             half3   skyColor        : TEXCOORD2;
  165.  
  166.         #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
  167.             half3   sunColor        : TEXCOORD3;
  168.         #endif
  169.  
  170.             UNITY_VERTEX_OUTPUT_STEREO
  171.         };
  172.  
  173.  
  174.         float scale(float inCos)
  175.         {
  176.             float x = 1.0 - inCos;
  177.         #if defined(SHADER_API_N3DS)
  178.             // The polynomial expansion here generates too many swizzle instructions for the 3DS vertex assembler
  179.             // Approximate by removing x^1 and x^2
  180.             return 0.25 * exp(-0.00287 + x*x*x*(-6.80 + x*5.25));
  181.         #else
  182.             return 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
  183.         #endif
  184.         }
  185.  
  186.         v2f vert (appdata_t v)
  187.         {
  188.             v2f OUT;
  189.             UNITY_SETUP_INSTANCE_ID(v);
  190.             UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
  191.             OUT.pos = UnityObjectToClipPos(v.vertex);
  192.             OUT.uv = v.uv;
  193.  
  194.             float3 kSkyTintInGammaSpace = COLOR_2_GAMMA(_SkyTint); // convert tint from Linear back to Gamma
  195.             float3 kScatteringWavelength = lerp (
  196.                 kDefaultScatteringWavelength-kVariableRangeForScatteringWavelength,
  197.                 kDefaultScatteringWavelength+kVariableRangeForScatteringWavelength,
  198.                 half3(1,1,1) - kSkyTintInGammaSpace); // using Tint in sRGB gamma allows for more visually linear interpolation and to keep (.5) at (128, gray in sRGB) point
  199.             float3 kInvWavelength = 1.0 / pow(kScatteringWavelength, 4);
  200.  
  201.             float kKrESun = kRAYLEIGH * kSUN_BRIGHTNESS;
  202.             float kKr4PI = kRAYLEIGH * 4.0 * 3.14159265;
  203.  
  204.             float3 cameraPos = float3(0,kInnerRadius + kCameraHeight,0);    // The camera's current position
  205.  
  206.             // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
  207.             float3 eyeRay = normalize(mul((float3x3)unity_ObjectToWorld, v.vertex.xyz));
  208.  
  209.             float far = 0.0;
  210.             half3 cIn, cOut;
  211.  
  212.             if(eyeRay.y >= 0.0)
  213.             {
  214.                 // Sky
  215.                 // Calculate the length of the "atmosphere"
  216.                 far = sqrt(kOuterRadius2 + kInnerRadius2 * eyeRay.y * eyeRay.y - kInnerRadius2) - kInnerRadius * eyeRay.y;
  217.  
  218.                 float3 pos = cameraPos + far * eyeRay;
  219.  
  220.                 // Calculate the ray's starting position, then calculate its scattering offset
  221.                 float height = kInnerRadius + kCameraHeight;
  222.                 float depth = exp(kScaleOverScaleDepth * (-kCameraHeight));
  223.                 float startAngle = dot(eyeRay, cameraPos) / height;
  224.                 float startOffset = depth*scale(startAngle);
  225.  
  226.  
  227.                 // Initialize the scattering loop variables
  228.                 float sampleLength = far / kSamples;
  229.                 float scaledLength = sampleLength * kScale;
  230.                 float3 sampleRay = eyeRay * sampleLength;
  231.                 float3 samplePoint = cameraPos + sampleRay * 0.5;
  232.  
  233.                 // Now loop through the sample rays
  234.                 float3 frontColor = float3(0.0, 0.0, 0.0);
  235.                 // Weird workaround: WP8 and desktop FL_9_3 do not like the for loop here
  236.                 // (but an almost identical loop is perfectly fine in the ground calculations below)
  237.                 // Just unrolling this manually seems to make everything fine again.
  238. //              for(int i=0; i<int(kSamples); i++)
  239.                 {
  240.                     float height = length(samplePoint);
  241.                     float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
  242.                     float lightAngle = dot(_WorldSpaceLightPos0.xyz, samplePoint) / height;
  243.                     float cameraAngle = dot(eyeRay, samplePoint) / height;
  244.                     float scatter = (startOffset + depth*(scale(lightAngle) - scale(cameraAngle)));
  245.                     float3 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI));
  246.  
  247.                     frontColor += attenuate * (depth * scaledLength);
  248.                     samplePoint += sampleRay;
  249.                 }
  250.                 {
  251.                     float height = length(samplePoint);
  252.                     float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
  253.                     float lightAngle = dot(_WorldSpaceLightPos0.xyz, samplePoint) / height;
  254.                     float cameraAngle = dot(eyeRay, samplePoint) / height;
  255.                     float scatter = (startOffset + depth*(scale(lightAngle) - scale(cameraAngle)));
  256.                     float3 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI));
  257.  
  258.                     frontColor += attenuate * (depth * scaledLength);
  259.                     samplePoint += sampleRay;
  260.                 }
  261.  
  262.  
  263.  
  264.                 // Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
  265.                 cIn = frontColor * (kInvWavelength * kKrESun);
  266.                 cOut = frontColor * kKmESun;
  267.             }
  268.             else
  269.             {
  270.                 // Ground
  271.                 far = (-kCameraHeight) / (min(-0.001, eyeRay.y));
  272.  
  273.                 float3 pos = cameraPos + far * eyeRay;
  274.  
  275.                 // Calculate the ray's starting position, then calculate its scattering offset
  276.                 float depth = exp((-kCameraHeight) * (1.0/kScaleDepth));
  277.                 float cameraAngle = dot(-eyeRay, pos);
  278.                 float lightAngle = dot(_WorldSpaceLightPos0.xyz, pos);
  279.                 float cameraScale = scale(cameraAngle);
  280.                 float lightScale = scale(lightAngle);
  281.                 float cameraOffset = depth*cameraScale;
  282.                 float temp = (lightScale + cameraScale);
  283.  
  284.                 // Initialize the scattering loop variables
  285.                 float sampleLength = far / kSamples;
  286.                 float scaledLength = sampleLength * kScale;
  287.                 float3 sampleRay = eyeRay * sampleLength;
  288.                 float3 samplePoint = cameraPos + sampleRay * 0.5;
  289.  
  290.                 // Now loop through the sample rays
  291.                 float3 frontColor = float3(0.0, 0.0, 0.0);
  292.                 float3 attenuate;
  293. //              for(int i=0; i<int(kSamples); i++) // Loop removed because we kept hitting SM2.0 temp variable limits. Doesn't affect the image too much.
  294.                 {
  295.                     float height = length(samplePoint);
  296.                     float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
  297.                     float scatter = depth*temp - cameraOffset;
  298.                     attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI));
  299.                     frontColor += attenuate * (depth * scaledLength);
  300.                     samplePoint += sampleRay;
  301.                 }
  302.  
  303.                 cIn = frontColor * (kInvWavelength * kKrESun + kKmESun);
  304.                 cOut = clamp(attenuate, 0.0, 1.0);
  305.             }
  306.  
  307.         #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ
  308.             OUT.vertex          = -v.vertex;
  309.         #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
  310.             OUT.rayDir          = half3(-eyeRay);
  311.         #else
  312.             OUT.skyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD;
  313.         #endif
  314.  
  315.             // if we want to calculate color in vprog:
  316.             // 1. in case of linear: multiply by _Exposure in here (even in case of lerp it will be common multiplier, so we can skip mul in fshader)
  317.             // 2. in case of gamma and SKYBOX_COLOR_IN_TARGET_COLOR_SPACE: do sqrt right away instead of doing that in fshader
  318.  
  319.             OUT.groundColor = _Exposure * (cIn + COLOR_2_LINEAR(_GroundColor) * cOut);
  320.             OUT.skyColor    = _Exposure * (cIn * getRayleighPhase(_WorldSpaceLightPos0.xyz, -eyeRay));
  321.  
  322.         #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
  323.             // The sun should have a stable intensity in its course in the sky. Moreover it should match the highlight of a purely specular material.
  324.             // This matching was done using the standard shader BRDF1 on the 5/31/2017
  325.             // Finally we want the sun to be always bright even in LDR thus the normalization of the lightColor for low intensity.
  326.             half lightColorIntensity = clamp(length(_LightColor0.xyz), 0.25, 1);
  327.             #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
  328.                 OUT.sunColor    = kSimpleSundiskIntensityFactor * saturate(cOut * kSunScale) * _LightColor0.xyz / lightColorIntensity;
  329.             #else // SKYBOX_SUNDISK_HQ
  330.                 OUT.sunColor    = kHDSundiskIntensityFactor * saturate(cOut) * _LightColor0.xyz / lightColorIntensity;
  331.             #endif
  332.  
  333.         #endif
  334.  
  335.         #if defined(UNITY_COLORSPACE_GAMMA) && SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
  336.             OUT.groundColor = sqrt(OUT.groundColor);
  337.             OUT.skyColor    = sqrt(OUT.skyColor);
  338.             #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
  339.                 OUT.sunColor= sqrt(OUT.sunColor);
  340.             #endif
  341.         #endif
  342.  
  343.             return OUT;
  344.         }
  345.  
  346.  
  347.         // Calculates the Mie phase function
  348.         half getMiePhase(half eyeCos, half eyeCos2)
  349.         {
  350.             half temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos;
  351.             temp = pow(temp, pow(_SunSize,0.65) * 10);
  352.             temp = max(temp,1.0e-4); // prevent division by zero, esp. in half precision
  353.             temp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp;
  354.             #if defined(UNITY_COLORSPACE_GAMMA) && SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
  355.                 temp = pow(temp, .454545);
  356.             #endif
  357.             return temp;
  358.         }
  359.  
  360.         // Calculates the sun shape
  361.         half calcSunAttenuation(half3 lightPos, half3 ray)
  362.         {
  363.         #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
  364.             half3 delta = lightPos - ray;
  365.             half dist = length(delta);
  366.             half spot = 1.0 - smoothstep(0.0, _SunSize, dist);
  367.             return spot * spot;
  368.         #else // SKYBOX_SUNDISK_HQ
  369.             half focusedEyeCos = pow(saturate(dot(lightPos, ray)), _SunSizeConvergence);
  370.             return getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos);
  371.         #endif
  372.         }
  373.  
  374.         float nrand(float2 uv)
  375.         {
  376.             return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
  377.         }
  378.  
  379.                 //
  380. // Noise Shader Library for Unity - https://github.com/keijiro/NoiseShader
  381. //
  382. // Original work (webgl-noise) Copyright (C) 2011 Ashima Arts.
  383. // Translation and modification was made by Keijiro Takahashi.
  384. //
  385. // This shader is based on the webgl-noise GLSL shader. For further details
  386. // of the original shader, please see the following description from the
  387. // original source code.
  388. //
  389.  
  390. //
  391. // Description : Array and textureless GLSL 2D simplex noise function.
  392. //      Author : Ian McEwan, Ashima Arts.
  393. //  Maintainer : ijm
  394. //     Lastmod : 20110822 (ijm)
  395. //     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
  396. //               Distributed under the MIT License. See LICENSE file.
  397. //               https://github.com/ashima/webgl-noise
  398. //
  399.  
  400. float3 mod289(float3 x)
  401. {
  402.     return x - floor(x / 289.0) * 289.0;
  403. }
  404.  
  405. float2 mod289(float2 x)
  406. {
  407.     return x - floor(x / 289.0) * 289.0;
  408. }
  409.  
  410. float3 permute(float3 x)
  411. {
  412.     return mod289((x * 34.0 + 1.0) * x);
  413. }
  414.  
  415. float3 taylorInvSqrt(float3 r)
  416. {
  417.     return 1.79284291400159 - 0.85373472095314 * r;
  418. }
  419.  
  420. float snoise(float2 v)
  421. {
  422.     const float4 C = float4( 0.211324865405187,  // (3.0-sqrt(3.0))/6.0
  423.                              0.366025403784439,  // 0.5*(sqrt(3.0)-1.0)
  424.                             -0.577350269189626,  // -1.0 + 2.0 * C.x
  425.                              0.024390243902439); // 1.0 / 41.0
  426.     // First corner
  427.     float2 i  = floor(v + dot(v, C.yy));
  428.     float2 x0 = v -   i + dot(i, C.xx);
  429.  
  430.     // Other corners
  431.     float2 i1;
  432.     i1.x = step(x0.y, x0.x);
  433.     i1.y = 1.0 - i1.x;
  434.  
  435.     // x1 = x0 - i1  + 1.0 * C.xx;
  436.     // x2 = x0 - 1.0 + 2.0 * C.xx;
  437.     float2 x1 = x0 + C.xx - i1;
  438.     float2 x2 = x0 + C.zz;
  439.  
  440.     // Permutations
  441.     i = mod289(i); // Avoid truncation effects in permutation
  442.     float3 p =
  443.       permute(permute(i.y + float3(0.0, i1.y, 1.0))
  444.                     + i.x + float3(0.0, i1.x, 1.0));
  445.  
  446.     float3 m = max(0.5 - float3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0);
  447.     m = m * m;
  448.     m = m * m;
  449.  
  450.     // Gradients: 41 points uniformly over a line, mapped onto a diamond.
  451.     // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
  452.     float3 x = 2.0 * frac(p * C.www) - 1.0;
  453.     float3 h = abs(x) - 0.5;
  454.     float3 ox = floor(x + 0.5);
  455.     float3 a0 = x - ox;
  456.  
  457.     // Normalise gradients implicitly by scaling m
  458.     m *= taylorInvSqrt(a0 * a0 + h * h);
  459.  
  460.     // Compute final noise value at P
  461.     float3 g;
  462.     g.x = a0.x * x0.x + h.x * x0.y;
  463.     g.y = a0.y * x1.x + h.y * x1.y;
  464.     g.z = a0.z * x2.x + h.z * x2.y;
  465.     return 130.0 * dot(m, g);
  466. }
  467.  
  468.  
  469.         half4 frag (v2f IN) : SV_Target
  470.         {
  471.             half3 col = half3(0.0, 0.0, 0.0);
  472.  
  473.         // if y > 1 [eyeRay.y < -SKY_GROUND_THRESHOLD] - ground
  474.         // if y >= 0 and < 1 [eyeRay.y <= 0 and > -SKY_GROUND_THRESHOLD] - horizon
  475.         // if y < 0 [eyeRay.y > 0] - sky
  476.         #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ
  477.             half3 ray = normalize(mul((float3x3)unity_ObjectToWorld, IN.vertex));
  478.             half y = ray.y / SKY_GROUND_THRESHOLD;
  479.         #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
  480.             half3 ray = IN.rayDir.xyz;
  481.             half y = ray.y / SKY_GROUND_THRESHOLD;
  482.         #else
  483.             half y = IN.skyGroundFactor;
  484.         #endif
  485.  
  486.             // if we did precalculate color in vprog: just do lerp between them
  487.             col = lerp(IN.skyColor, IN.groundColor, saturate(y));
  488.  
  489.         #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
  490.             if(y < 0.0)
  491.             {
  492.                 col += IN.sunColor * calcSunAttenuation(_WorldSpaceLightPos0.xyz, -ray);
  493.             }
  494.         #endif
  495.        
  496.         if (y < 0.0) {
  497.             //sky
  498.             float isStar = max(0.0, _StarBrightness * (snoise(IN.uv * 60) * snoise(IN.uv * 100) * snoise(IN.uv * 50) ));
  499.             isStar = pow(isStar, _StarDensity);
  500.             // dunno how to get "time of day" so to speak so just reduce magnitude based
  501.             // on how light the col already is.
  502.             col += max(0.0, 0.05 - col) * isStar * max(0.1, snoise(_Time * _TwinkleSpeed + IN.uv * 60));
  503.         }
  504.            
  505.         #if defined(UNITY_COLORSPACE_GAMMA) && !SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
  506.             col = LINEAR_2_OUTPUT(col);
  507.         #endif
  508.            
  509.             return half4(col,1.0);
  510.  
  511.         }
  512.  
  513.  
  514.         ENDCG
  515.     }
  516. }
  517.  
  518.  
  519. Fallback Off
  520. //CustomEditor "SkyboxProceduralShaderGUI"
  521. }
Advertisement
Add Comment
Please, Sign In to add comment