Search Unity

Question Best way to use unityar camera direction (rotation) to lock shader 'direction'

Discussion in 'Shaders' started by nosarious, Aug 16, 2022.

  1. nosarious

    nosarious

    Joined:
    May 14, 2014
    Posts:
    16
    I have a shader which I transferred from shadertoy of relatively simple clouds. This shader is intended to be inside a building on the interior walls and ceiling so one can feel like they are outside, yet any window or doors will be 'floating' in the clouds. Since this is an AR app, you will be able to see your physical surroundings through the windows and doors.

    I am having trouble getting the camera angles to use for this. Right now the clouds are almost like a green screen, but their direction (on the ceiling) doesn't change with the model which is interesting, but not for this project. It would be better if the angle of the camera to the plane made one see clouds receding into the horizon, and if the direction of the clouds was consistent with the direction you were facing (ie, they travel away from you in one direction, and towards you in the opposite)

    If I concentrate on the different aspects, the direction of the camera (the phone representation) on a ground plane should let me rotate the current result of the shader, letting me have the direction. The angle of the camera TO the ground plane should let me figure out the horizon.

    I have tried several different shaders, but the logic of this escapes me.

    The shadertoy of just clouds (no mouse controls) which should still let me rotate according to x-y camera direction: https://www.shadertoy.com/view/4tdSWr

    A shadertoy of similar clouds, but with grass and mouse control on a separate buffer (grass is easily removed from code on an additional buffer)
    https://www.shadertoy.com/view/4dBcDV

    And an additional shader which does everything within one file (but the clouds are not as nice): https://www.shadertoy.com/view/wslyWs

    Am I asking the right question? Is there a better way to do this? Right now I am concentrating on daytime clouds, but I would like to explore having one experience the milky way when entering a building, stretching from one side to another, but the openings in the walls still let you see through.

    Images of how 'flat' the clouds appear right now are here. The are animated within the shader:
    https://cathoderayministry.tumblr.c...200/placeholder-for-images-of-clouds-inside-a


     
  2. nosarious

    nosarious

    Joined:
    May 14, 2014
    Posts:
    16
    For the record, the first cloud shader code is here. I am unsure how to use the camera in this instance:
    Code (CSharp):
    1. Shader "Unlit/cloud-ceiling"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 100
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.             // make fog work
    18.             #pragma multi_compile_fog
    19.  
    20.             #include "UnityCG.cginc"
    21.  
    22.             struct appdata
    23.             {
    24.                 float4 vertex : POSITION;
    25.                 float2 uv : TEXCOORD0;
    26.             };
    27.  
    28.             struct v2f
    29.             {
    30.                 float2 uv : TEXCOORD0;
    31.                 UNITY_FOG_COORDS(1)
    32.                 float4 vertex : SV_POSITION;
    33.             };
    34.  
    35.            
    36.  
    37.             sampler2D _MainTex;
    38.             float4 _MainTex_ST;
    39.  
    40.             static const float cloudscale = 1.75;//1.1;
    41.             static const float speed = 0.1;//0.07;
    42.             static const float clouddark = 0.5;
    43.             static const float cloudlight = 0.3;
    44.             static const float cloudcover = 0.2;
    45.             static const float cloudalpha = 8.0;
    46.             static const float skytint = 0.5;
    47.             static const float3 skycolour1 = float3(0.2, 0.4, 0.6);
    48.             static const float3 skycolour2 = float3(0.4, 0.7, 1.0);
    49.  
    50.             static const float2x2 m = float2x2( 1.6,  1.2, -1.2,  1.6 );
    51.  
    52.             float2 hash( float2 p ) {
    53.                 p = float2(dot(p,float2(127.1,311.7)), dot(p,float2(269.5,183.3)));
    54.                 return -1.0 + 2.0*frac(sin(p)*43758.5453123);
    55.             }
    56.  
    57.             float noise( in float2 p ) {
    58.                 const float K1 = 0.366025404; // (sqrt(3)-1)/2;
    59.                 const float K2 = 0.211324865; // (3-sqrt(3))/6;
    60.                 float test = p.x+p.y;
    61.                 float2 i = floor(p + (test*K1));  
    62.                 float2 a = p - i + (i.x+i.y)*K2;
    63.                 float2 o = (a.x>a.y) ? float2(1.0,0.0) : float2(0.0,1.0); //float2 of = 0.5 + 0.5*float2(sign(a.x-a.y), sign(a.y-a.x));
    64.                 float2 b = a - o + K2;
    65.                 float2 c = a - 1.0 + 2.0*K2;
    66.                 float3 h = max(0.5-float3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
    67.                 float3 n = h*h*h*h*float3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
    68.                 return dot(n, float3(70.0, 70.0, 70.0));
    69.             }
    70.  
    71.             float fbm(float2 n) {
    72.                 float total = 0.0, amplitude = 0.1;
    73.                 for (int i = 0; i < 7; i++) {
    74.                     total += noise(n) * amplitude;
    75.                     n = mul(m , n);
    76.                     amplitude *= 0.4;
    77.                 }
    78.                 return total;
    79.             }
    80.  
    81.             // -----------------------------------------------
    82.  
    83.             void mainImage( out float4 color, in float2 position ) {
    84.                
    85.             }
    86.  
    87.             v2f vert (appdata v)
    88.             {
    89.                 v2f o;
    90.                 o.vertex = UnityObjectToClipPos(v.vertex);
    91.                 //float3x3 forward = mul((float3x3)unity_CameraToWorld,float(0,0,1));
    92.                 //o*= forward;
    93.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    94.                 UNITY_TRANSFER_FOG(o,o.vertex);
    95.                 return o;
    96.             }
    97.  
    98.             fixed4 frag (v2f i) : SV_Target
    99.             {
    100.                 float2 p =  i.vertex.xy / _ScreenParams.xy;
    101.                 float2 uv = p*float2(_ScreenParams.x/_ScreenParams.y,1.0);  
    102.                 float time = _Time.y* speed;
    103.                 float q = fbm(uv * cloudscale * 0.5);
    104.  
    105.  
    106.                
    107.                 //ridged noise shape
    108.                 float r = 0.0;
    109.                 uv *= cloudscale;
    110.                 uv -= q - time;
    111.                 float weight = 0.8;
    112.                 for (int iv=0; iv<8; iv++){
    113.                     r += abs(weight*noise( uv ));
    114.                     uv = mul(m, uv) + time;
    115.                     weight *= 0.7;
    116.                 }
    117.                
    118.                 //noise shape
    119.                 float f = 0.0;
    120.                 uv = p*float2(_ScreenParams.x/_ScreenParams.y,1.0);
    121.                 uv *= cloudscale;
    122.                 uv -= q - time;
    123.                 weight = 0.7;
    124.                 for (int i=0; i<8; i++){
    125.                     f += weight*noise( uv );
    126.                     uv = mul(m, uv) + time;
    127.                     weight *= 0.6;
    128.                 }
    129.                
    130.                 f *= r + f;
    131.                
    132.                 //noise colour
    133.                 float c = 0.0;
    134.                 time = _Time.y * speed * 2.0;
    135.                 uv = p*float2(_ScreenParams.x/_ScreenParams.y,1.0);
    136.                 uv *= cloudscale*2.0;
    137.                 uv -= q - time;
    138.                 weight = 0.4;
    139.                 for (int ii=0; ii<7; ii++){
    140.                     c += weight*noise( uv );
    141.                     uv = mul(m, uv) + time;
    142.                     weight *= 0.6;
    143.                 }
    144.                
    145.                 //noise ridge colour
    146.                 float c1 = 0.0;
    147.                 time = _Time.y * speed * 3.0;
    148.                 uv = p*float2(_ScreenParams.x/_ScreenParams.y,1.0);
    149.                 uv *= cloudscale*3.0;
    150.                 uv -= q - time;
    151.                 weight = 0.4;
    152.                 for (int iii=0; iii<7; iii++){
    153.                     c1 += abs(weight*noise( uv ));
    154.                     uv = mul(m, uv) + time;
    155.                     weight *= 0.6;
    156.                 }
    157.                
    158.                 c += c1;
    159.                
    160.                 float3 skycolour = lerp(skycolour2, skycolour1, p.y);
    161.                 float3 cloudcolour = float3(1.1, 1.1, 0.9) * clamp((clouddark + cloudlight*c), 0.0, 1.0);
    162.              
    163.                 f = cloudcover + cloudalpha*f*r;
    164.                
    165.                 float3 result = lerp(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 1.0), clamp(f + c, 0.0, 1.0));
    166.  
    167.                
    168.  
    169.                
    170.                 return float4( result, 1.0 );
    171.             }
    172.             ENDCG
    173.         }
    174.     }
    175. }
    176.  
     
  3. nosarious

    nosarious

    Joined:
    May 14, 2014
    Posts:
    16
    I have tried to convert the third shader, (https://www.shadertoy.com/view/wslyWs) to see if I could isolate the mouse to camera direction, but the material is purple, which indicates a problem. When the AR app is built to my phone it is just white. I did manage to get the noise texture, iChannel0 as a drag/droppable image, so I am unsure what the problem could be.

    Code (CSharp):
    1.  
    2.  
    3. Shader "Unlit/skybox"
    4. {
    5.     Properties
    6.     {
    7.         _MainTex ("Texture", 2D) = "white" {}
    8.         _iChannel0 ("iChannel0", 2D) = "white" {}
    9.         //_iChannel0("iChannel0", 2D) = "white"{}
    10.     }
    11.     SubShader
    12.     {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 100
    15.  
    16.         Pass
    17.         {
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             // make fog work
    22.             #pragma multi_compile_fog
    23.  
    24.             #include "UnityCG.cginc"
    25.  
    26.             struct appdata
    27.             {
    28.                 float4 vertex : POSITION;
    29.                 float2 uv : TEXCOORD0;
    30.             };
    31.  
    32.             struct v2f
    33.             {
    34.                 float2 uv : TEXCOORD0;
    35.                 UNITY_FOG_COORDS(1)
    36.                 float4 vertex : SV_POSITION;
    37.             };
    38.  
    39.             sampler2D _MainTex;
    40.             sampler2D _iChannel0;
    41.             float4 _MainTex_ST;
    42.             float4 _iChannel0_ST;
    43.  
    44.  
    45.  
    46.  
    47. float random(in float2 uv)
    48. {
    49.     return tex2D(_iChannel0, uv / 64.).r;
    50.    
    51.    /*
    52.    //alternative noise function - no image
    53.     float2 K1 = float2(23.14069263277926, 2.665144142690225);
    54.     float thisDot = dot(uv, K1);
    55.     return frac( cos( dot(uv,K1) ) * 12345.6789 );
    56.     */
    57. }
    58.  
    59.  
    60. float noise(in float2 uv)
    61. {
    62.     float2 i = floor(uv);
    63.     float2 f = frac(uv);
    64.     f = f * f * (3. - 2. * f);
    65.    
    66.     float lb = random(i + float2(0., 0.));
    67.     float rb = random(i + float2(1., 0.));
    68.     float lt = random(i + float2(0., 1.));
    69.     float rt = random(i + float2(1., 1.));
    70.    
    71.     return lerp(lerp(lb, rb, f.x),
    72.                lerp(lt, rt, f.x), f.y);
    73. }
    74.  
    75. #define OCTAVES 8
    76. float fbm(in float2 uv)
    77. {
    78.     float value = 0.;
    79.     float amplitude = .5;
    80.    
    81.     for (int i = 0; i < OCTAVES; i++)
    82.     {
    83.         value += noise(uv) * amplitude;
    84.        
    85.         amplitude *= .5;
    86.        
    87.         uv *= 2.;
    88.     }
    89.    
    90.     return value;
    91. }
    92.  
    93. float3 Sky(in float3 ro, in float3 rd)
    94. {
    95.     const float SC = 1e5;
    96.  
    97.      // Calculate sky plane
    98.     float dist = (SC - ro.y) / rd.y;
    99.     float2 p = (ro + dist * rd).xz;
    100.     p *= 1.2 / SC;
    101.    
    102.     // from iq's shader, https://www.shadertoy.com/view/MdX3Rr
    103.     float3 lightDir = normalize(float3(-.8, .15, -.3));
    104.     float sundot = clamp(dot(rd, lightDir), 0.0, 1.0);
    105.    
    106.     float3 cloudCol = float3(1.,1.0,1.0);
    107.     //float3 skyCol = float3(.6, .71, .85) - rd.y * .2 * float3(1., .5, 1.) + .15 * .5;
    108.     float3 skyCol = float3(0.3,0.5,0.85) - rd.y*rd.y*0.5;
    109.     skyCol = lerp( skyCol, mul(0.85, float3(0.7,0.75,0.85)), pow( 1.0 - max(rd.y, 0.0), 4.0 ) );
    110.    
    111.     // sun
    112.     float3 sun = mul(mul(0.25 , float3(1.0,0.7,0.4)) , pow( sundot,5.0 ));
    113.     sun += mul(mul(0.25 , float3(1.0,0.8,0.6)) , pow( sundot,64.0 ));
    114.     sun += mul(mul(0.2 , float3(1.0,0.8,0.6)) , pow( sundot,512.0 ));
    115.     skyCol += sun;
    116.    
    117.     // clouds
    118.     float t = mul(_Time.y , 0.1);
    119.     float den = fbm(float2(p.x - t, p.y - t));
    120.     skyCol = lerp( skyCol, cloudCol, smoothstep(.4, .8, den));
    121.    
    122.     // horizon
    123.     skyCol = lerp( skyCol, mul(0.68 , float3(.418, .394, .372)), pow( 1.0 - max(rd.y, 0.0), 16.0 ) );
    124.    
    125.     return skyCol;
    126. }
    127.  
    128. float3x3 setCamera( in float3 ro, in float3 ta, float cr )
    129. {
    130.     float3 cw = normalize(ta-ro);
    131.     float3 cp = float3(sin(cr), cos(cr),0.0);
    132.     float3 cu = normalize( cross(cw,cp) );
    133.     float3 cv = normalize( cross(cu,cw) );
    134.     return float3x3( cu, cv, cw );
    135. }
    136.  
    137. struct Ray
    138. {
    139.     float3 origin;
    140.     float3 direction;
    141. };
    142.  
    143. Ray CreateRay(float3 origin, float3 direction)
    144. {
    145.     Ray ray;
    146.     ray.origin = origin;
    147.     ray.direction = direction;
    148.     return ray;
    149. }
    150.  
    151. Ray CreateCameraRay(float2 uv)
    152. {
    153.     // Transform the camera origin to world space
    154.     float3 origin = mul(unity_CameraToWorld, float4(0.0f, 0.0f, 0.0f, 1.0f)).xyz;
    155.    
    156.     // Invert the perspective projection of the view-space position
    157.     float3 direction = mul(unity_CameraInvProjection, float4(uv, 0.0f, 1.0f)).xyz;
    158.     // Transform the direction from camera to world space and normalize
    159.     direction = mul(unity_CameraToWorld, float4(direction, 0.0f)).xyz;
    160.     direction = normalize(direction);
    161.  
    162.     return CreateRay(origin, direction);
    163. }
    164.  
    165. void mainImage( out float4 fragColor, in float2 fragCoord )
    166. {
    167.     ///proportion of frag to screen What needs to be drawn over where
    168.     float2 uv = fragCoord.xy / _ScreenParams.xy;
    169.     //is uv values between 0 and 1? does this centre it?
    170.     uv -= 0.5;
    171.     //uv.x is proportional to screen x/y ...~1.2? ish
    172.     uv.x *= _ScreenParams.x / _ScreenParams.y;
    173.     //mouse is proportional to screen for rotation, etc
    174.     //float2 mouse = iMouse.xy/_ScreenParams.xy;
    175.  
    176.     Ray ray = CreateCameraRay(uv);
    177.  
    178.     float3 thisMouse = ray.direction;
    179.     float2 mouse = normalize(thisMouse.xy)*2;
    180.  
    181.     float3 ro = float3(0.0, 0.0, 0.0);
    182.     //mouse.x rotates the shader
    183.     //mouse.y lets you see the horizon
    184.  
    185.     float3 ta = float3(cos(mul(mouse.x , 6.28)), mul(mouse.y , 2.0), sin(mul(mouse.x , 6.28)));
    186.     float3x3 cam = setCamera(ro, ta, 0.0);
    187.     float3 rd = normalize(mul(cam , float3(uv, 1.0)));
    188.    
    189.     float3 col = Sky(ro, rd);
    190.    
    191.     fragColor = float4(float3(col),1.0);
    192.     //fragColor = float4(float3(normalize(mouse.x), normalize(mouse.y), 1.0),1.0);
    193. }
    194.  
    195.  
    196.             v2f vert (appdata v)
    197.             {
    198.                 v2f o;
    199.                 o.vertex = UnityObjectToClipPos(v.vertex);
    200.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    201.                 UNITY_TRANSFER_FOG(o,o.vertex);
    202.                 return o;
    203.             }
    204.  
    205.             fixed4 frag (v2f i) : SV_Target
    206.             {
    207.                 // sample the texture
    208.                 fixed4 col = tex2D(_MainTex, i.uv);
    209.                 // apply fog
    210.                 UNITY_APPLY_FOG(i.fogCoord, col);
    211.                 return col;
    212.             }
    213.             ENDCG
    214.         }
    215.     }
    216. }
    217.