Search Unity

Raymarching clouds shader VR LWRP

Discussion in 'VR' started by plangiewicz, Mar 5, 2020.

  1. plangiewicz

    plangiewicz

    Joined:
    Aug 22, 2017
    Posts:
    1
    Hello.
    i am try to import into my project this :

    and this is in Standard Unity project without new render pipeline.
    I reproduced it but i have reflections in oculus rift

    upload_2020-3-5_14-51-56.png

    upload_2020-3-5_14-52-12.png


    This is just black background and clouds without sun. First photo is from editor (without oculus it work) and second from game (oculus) and I really don't know why this is happend :<

    Code (CSharp):
    1.  
    2. Shader "Hidden/Clouds"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex("Texture", 2D) = "white" {}
    7.     }
    8.     SubShader
    9.     {
    10.         Cull Off ZWrite Off ZTest Always
    11.  
    12.         Pass
    13.         {
    14.             HLSLPROGRAM
    15.  
    16.             #pragma target 3.5
    17.  
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.  
    21.             #include "UnityCG.cginc"
    22.  
    23.             #define DEBUG_MODE 1
    24.             #define TEST 0
    25.             #define DRAWDEPTH 0
    26.  
    27.             // vertex input: position, UV
    28.             struct appdata {
    29.                 float4 vertex : POSITION;
    30.                 float2 uv : TEXCOORD0;
    31.             };
    32.  
    33.             struct v2f {
    34.                 float4 pos : SV_POSITION;
    35.                 float2 uv : TEXCOORD0;
    36.                 float3 viewVector : TEXCOORD1;
    37.             };
    38.  
    39.             v2f vert(appdata v) {
    40.                 v2f output;
    41.                 output.pos = UnityWorldToClipPos(v.vertex);
    42.                 output.uv = v.uv;
    43.                 // Camera space matches OpenGL convention where cam forward is -z. In unity forward is positive z.
    44.                 // (https://docs.unity3d.com/ScriptReference/Camera-cameraToWorldMatrix.html)
    45.                 float3 viewVector = mul(unity_CameraInvProjection, float4(v.uv * 2 - 1, 0, -1));
    46.                 output.viewVector = mul(unity_CameraToWorld, float4(viewVector,0));
    47.                 return output;
    48.             }
    49.  
    50.             uniform sampler2D _MainTex;
    51.             half4 _MainTex_ST;
    52.             uniform sampler2D_float _CameraDepthTexture;
    53.  
    54.             // Textures
    55.             Texture3D<float4> NoiseTex;
    56.             Texture3D<float4> DetailNoiseTex;
    57.             Texture2D<float4> WeatherMap;
    58.             Texture2D<float4> BlueNoise;
    59.  
    60.             SamplerState samplerNoiseTex;
    61.             SamplerState samplerDetailNoiseTex;
    62.             SamplerState samplerWeatherMap;
    63.             SamplerState samplerBlueNoise;
    64.  
    65.  
    66.             // Shape settings
    67.             float4 params;
    68.             int3 mapSize;
    69.             float densityMultiplier;
    70.             float densityOffset;
    71.             float scale;
    72.             float detailNoiseScale;
    73.             float detailNoiseWeight;
    74.             float3 detailWeights;
    75.             float4 shapeNoiseWeights;
    76.             float4 phaseParams;
    77.  
    78.             // March settings
    79.             int numStepsLight;
    80.             float rayOffsetStrength;
    81.  
    82.             float3 boundsMin;
    83.             float3 boundsMax;
    84.  
    85.             float3 shapeOffset;
    86.             float3 detailOffset;
    87.  
    88.             // Light settings
    89.             float lightAbsorptionTowardSun;
    90.             float lightAbsorptionThroughCloud;
    91.             float darknessThreshold;
    92.             float4 _LightColor0;
    93.             float4 colA;
    94.             float4 colB;
    95.  
    96.             // Animation settings
    97.             float timeScale;
    98.             float baseSpeed;
    99.             float detailSpeed;
    100.  
    101.             // Debug settings:
    102.             int debugViewMode; // 0 = off; 1 = shape tex; 2 = detail tex; 3 = weathermap
    103.             int debugGreyscale;
    104.             int debugShowAllChannels;
    105.             float debugNoiseSliceDepth;
    106.             float4 debugChannelWeight;
    107.             float debugTileAmount;
    108.             float viewerSize;
    109.  
    110.             float remap(float v, float minOld, float maxOld, float minNew, float maxNew) {
    111.                 return minNew + (v - minOld) * (maxNew - minNew) / (maxOld - minOld);
    112.             }
    113.  
    114.             float2 squareUV(float2 uv) {
    115.                 float width = _ScreenParams.x;
    116.                 float height = _ScreenParams.y;
    117.                 //float minDim = min(width, height);
    118.                 float scale = 1000;
    119.                 float x = uv.x * width;
    120.                 float y = uv.y * height;
    121.                 return float2 (x / scale, y / scale);
    122.             }
    123.  
    124.             // Returns (dstToBox, dstInsideBox). If ray misses box, dstInsideBox will be zero
    125.             float2 rayBoxDst(float3 boundsMin, float3 boundsMax, float3 rayOrigin, float3 invRaydir) {
    126.                 // Adapted from: http://jcgt.org/published/0007/03/04/
    127.                 float3 t0 = (boundsMin - rayOrigin) * invRaydir;
    128.                 float3 t1 = (boundsMax - rayOrigin) * invRaydir;
    129.                 float3 tmin = min(t0, t1);
    130.                 float3 tmax = max(t0, t1);
    131.  
    132.                 float dstA = max(max(tmin.x, tmin.y), tmin.z);
    133.                 float dstB = min(tmax.x, min(tmax.y, tmax.z));
    134.  
    135.                 // CASE 1: ray intersects box from outside (0 <= dstA <= dstB)
    136.                 // dstA is dst to nearest intersection, dstB dst to far intersection
    137.  
    138.                 // CASE 2: ray intersects box from inside (dstA < 0 < dstB)
    139.                 // dstA is the dst to intersection behind the ray, dstB is dst to forward intersection
    140.  
    141.                 // CASE 3: ray misses box (dstA > dstB)
    142.  
    143.                 float dstToBox = max(0, dstA);
    144.                 float dstInsideBox = max(0, dstB - dstToBox);
    145.                 return float2(dstToBox, dstInsideBox);
    146.             }
    147.  
    148.             // Henyey-Greenstein
    149.             float hg(float a, float g) {
    150.                 float g2 = g * g;
    151.                 return (1 - g2) / (4 * 3.1415 * pow(1 + g2 - 2 * g * (a), 1.5));
    152.             }
    153.  
    154.             float phase(float a) {
    155.                 float blend = .5;
    156.                 float hgBlend = hg(a,phaseParams.x) * (1 - blend) + hg(a,-phaseParams.y) * blend;
    157.                 return phaseParams.z + hgBlend * phaseParams.w;
    158.             }
    159.  
    160.             float beer(float d) {
    161.                 float beer = exp(-d);
    162.                 return beer;
    163.             }
    164.  
    165.             float remap01(float v, float low, float high) {
    166.                 return (v - low) / (high - low);
    167.             }
    168.  
    169.             float sampleDensity(float3 rayPos) {
    170.                 // Constants:
    171.                 const int mipLevel = 0;
    172.                 const float baseScale = 1 / 1000.0;
    173.                 const float offsetSpeed = 1 / 100.0;
    174.  
    175.                 // Calculate texture sample positions
    176.                 float time = _Time.x * timeScale;
    177.                 float3 size = boundsMax - boundsMin;
    178.                 float3 boundsCentre = (boundsMin + boundsMax) * .5;
    179.                 float3 uvw = (size * .5 + rayPos) * baseScale * scale;
    180.                 float3 shapeSamplePos = uvw + shapeOffset * offsetSpeed + float3(time,time * 0.1,time * 0.2) * baseSpeed;
    181.  
    182.                 // Calculate falloff at along x/z edges of the cloud container
    183.                 const float containerEdgeFadeDst = 50;
    184.                 float dstFromEdgeX = min(containerEdgeFadeDst, min(rayPos.x - boundsMin.x, boundsMax.x - rayPos.x));
    185.                 float dstFromEdgeZ = min(containerEdgeFadeDst, min(rayPos.z - boundsMin.z, boundsMax.z - rayPos.z));
    186.                 float edgeWeight = min(dstFromEdgeZ,dstFromEdgeX) / containerEdgeFadeDst;
    187.  
    188.                 // Calculate height gradient from weather map
    189.                 float2 weatherUV = (size.xz * .5 + (rayPos.xz - boundsCentre.xz)) / max(size.x,size.z);
    190.                 float weatherMap = WeatherMap.SampleLevel(samplerWeatherMap, weatherUV, mipLevel).x;
    191.                 float gMin = remap(weatherMap.x,0,1,0.1,0.5);
    192.                 float gMax = remap(weatherMap.x,0,1,gMin,0.9);
    193.                 float heightPercent = (rayPos.y - boundsMin.y) / size.y;
    194.                 float heightGradient = saturate(remap(heightPercent, 0.0, gMin, 0, 1)) * saturate(remap(heightPercent, 1, gMax, 0, 1));
    195.                 heightGradient *= edgeWeight;
    196.  
    197.                 // Calculate base shape density
    198.                 float4 shapeNoise = NoiseTex.SampleLevel(samplerNoiseTex, shapeSamplePos, mipLevel);
    199.                 float4 normalizedShapeWeights = shapeNoiseWeights / dot(shapeNoiseWeights, 1);
    200.                 float shapeFBM = dot(shapeNoise, normalizedShapeWeights) * heightGradient;
    201.                 float baseShapeDensity = shapeFBM + densityOffset * .1;
    202.  
    203.                 // Save sampling from detail tex if shape density <= 0
    204.                 if (baseShapeDensity > 0) {
    205.                     // Sample detail noise
    206.                     float3 detailSamplePos = uvw * detailNoiseScale + detailOffset * offsetSpeed + float3(time * .4,-time,time * 0.1) * detailSpeed;
    207.                     float4 detailNoise = DetailNoiseTex.SampleLevel(samplerDetailNoiseTex, detailSamplePos, mipLevel);
    208.                     float3 normalizedDetailWeights = detailWeights / dot(detailWeights, 1);
    209.                     float detailFBM = dot(detailNoise, normalizedDetailWeights);
    210.  
    211.                     // Subtract detail noise from base shape (weighted by inverse density so that edges get eroded more than centre)
    212.                     float oneMinusShape = 1 - shapeFBM;
    213.                     float detailErodeWeight = oneMinusShape * oneMinusShape * oneMinusShape;
    214.                     float cloudDensity = baseShapeDensity - (1 - detailFBM) * detailErodeWeight * detailNoiseWeight;
    215.  
    216.                     return cloudDensity * densityMultiplier * 0.1;
    217.                 }
    218.                 return 0;
    219.             }
    220.  
    221.             // Calculate proportion of light that reaches the given point from the lightsource
    222.             float lightmarch(float3 p) {
    223.                 float3 dirToLight = _WorldSpaceLightPos0.xyz;
    224.                 float dstInsideBox = rayBoxDst(boundsMin, boundsMax, p, 1 / dirToLight).y;
    225.  
    226.                 float transmittance = 1;
    227.                 float stepSize = dstInsideBox / numStepsLight;
    228.                 p += dirToLight * stepSize * .5;
    229.                 float totalDensity = 0;
    230.  
    231.                 for (int step = 0; step < numStepsLight; step++) {
    232.                     float density = sampleDensity(p);
    233.                     totalDensity += max(0, density * stepSize);
    234.                     p += dirToLight * stepSize;
    235.                 }
    236.  
    237.                 transmittance = beer(totalDensity * lightAbsorptionTowardSun);
    238.  
    239.                 float clampedTransmittance = darknessThreshold + transmittance * (1 - darknessThreshold);
    240.                 return clampedTransmittance;
    241.             }
    242.  
    243.             float4 debugDrawNoise(float2 uv) {
    244.  
    245.                 float4 channels = 0;
    246.                 float3 samplePos = float3(uv.x,uv.y, debugNoiseSliceDepth);
    247.  
    248.                 if (debugViewMode == 1) {
    249.                     channels = NoiseTex.SampleLevel(samplerNoiseTex, samplePos, 0);
    250.                 }
    251.                 else if (debugViewMode == 2) {
    252.                     channels = DetailNoiseTex.SampleLevel(samplerDetailNoiseTex, samplePos, 0);
    253.                 }
    254.                 else if (debugViewMode == 3) {
    255.                     channels = WeatherMap.SampleLevel(samplerWeatherMap, samplePos.xy, 0);
    256.                 }
    257.  
    258.                 if (debugShowAllChannels) {
    259.                     return channels;
    260.                 }
    261.                 else {
    262.                     float4 maskedChannels = (channels * debugChannelWeight);
    263.                     if (debugGreyscale || debugChannelWeight.w == 1) {
    264.                         return dot(maskedChannels,1);
    265.                     }
    266.                     else {
    267.                         return maskedChannels;
    268.                     }
    269.                 }
    270.             }
    271.  
    272.  
    273.             float4 frag(v2f i) : SV_Target
    274.             {
    275.                 #if DEBUG_MODE == 1
    276.                 if (debugViewMode != 0) {
    277.                     float width = _ScreenParams.x;
    278.                     float height = _ScreenParams.y;
    279.                     float minDim = min(width, height);
    280.                     float x = i.uv.x * width;
    281.                     float y = (1 - i.uv.y) * height;
    282.  
    283.                     if (x < minDim * viewerSize && y < minDim * viewerSize) {
    284.                         return debugDrawNoise(float2(x / (minDim * viewerSize) * debugTileAmount, y / (minDim * viewerSize) * debugTileAmount));
    285.                     }
    286.                 }
    287.                 #endif
    288.  
    289.             // Create ray
    290.             float3 rayPos = _WorldSpaceCameraPos;
    291.             float viewLength = length(i.viewVector);
    292.             float3 rayDir = i.viewVector / viewLength;
    293.  
    294.             // Depth and cloud container intersection info:
    295.             float nonlin_depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
    296.             float depth = LinearEyeDepth(nonlin_depth)* viewLength;
    297.             float2 rayToContainerInfo = rayBoxDst(boundsMin, boundsMax, rayPos, 1 / rayDir);
    298.             float dstToBox = rayToContainerInfo.x;
    299.             float dstInsideBox = rayToContainerInfo.y;
    300.  
    301.             // point of intersection with the cloud container
    302.             float3 entryPoint = rayPos + rayDir * dstToBox;
    303.  
    304.             // random starting offset (makes low-res results noisy rather than jagged/glitchy, which is nicer)
    305.             float randomOffset = BlueNoise.SampleLevel(samplerBlueNoise, squareUV(i.uv * 3), 0);
    306.             randomOffset *= rayOffsetStrength;
    307.  
    308.             // Phase function makes clouds brighter around sun
    309.             float cosAngle = dot(rayDir, _WorldSpaceLightPos0.xyz);
    310.             float phaseVal = phase(cosAngle);
    311.  
    312.             float dstTravelled = randomOffset;
    313.             float dstLimit = min(depth - dstToBox, dstInsideBox);
    314.  
    315.  
    316.             // March through volume:
    317.             const float stepSize = 11;
    318.             float transmittance = 1;
    319.             float3 lightEnergy = 0;
    320.  
    321.             while (dstTravelled < dstLimit) {
    322.                 rayPos = entryPoint + rayDir * dstTravelled;
    323.                 float density = sampleDensity(rayPos);
    324.  
    325.                 if (density > 0) {
    326.  
    327.                     float lightTransmittance = lightmarch(rayPos);
    328.                     lightEnergy += density * stepSize * transmittance * lightTransmittance * phaseVal;
    329.                     transmittance *= exp(-density * stepSize * lightAbsorptionThroughCloud);
    330.  
    331.                     // Early exit
    332.                     if (transmittance < 0.01) {
    333.                         break;
    334.                     }
    335.                 }
    336.  
    337.                 dstTravelled += stepSize;
    338.             }
    339.  
    340.  
    341.             // Composite sky + background
    342.             float3 skyColBase = lerp(colA,colB, sqrt(abs(saturate(rayDir.y))));
    343.             float3 backgroundCol = tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv, _MainTex_ST));
    344.             float dstFog = 1 - exp(-max(0,depth) * 8 * .0001);
    345.             float3 sky = dstFog * skyColBase;
    346.             backgroundCol = backgroundCol;// *(1 - dstFog) + sky;
    347.  
    348.             // Sun
    349.             float focusedEyeCos = pow(saturate(cosAngle), params.x);
    350.             float sun = saturate(hg(focusedEyeCos, .9995)) * transmittance;
    351.  
    352.             // Add clouds
    353.             float3 cloudCol = lightEnergy * _LightColor0;
    354.             float3 col = backgroundCol * transmittance + cloudCol;
    355.             col = saturate(col) * (1 - sun) + _LightColor0 * sun;
    356.  
    357.             return float4(col, 0);
    358.             //return float4(cloudCol, 0);
    359.             //return float4(backgroundCol, 0);
    360.             //return float4(tex2D(_MainTex, i.uv));
    361.             //return float4(depth * 100, depth * 100, depth * 100, 1);
    362.         }
    363.  
    364.             ENDHLSL
    365.         }
    366.     }
    367.  
    368.  
    369. }
    370.  
     
  2. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    What rendering mode are you using (project settings > XR Plugin Management > Oculus) ? If you're trying single-pass, the shader has to be specifically written for it.