// This shader draws a texture on the mesh. Shader "custom/tunnel" { // The _BaseMap variable is visible in the Material's Inspector, as a field // called Base Map. Properties { [HDR] _NebulaColor1("Nebula Color 1", Color) = (1,1,1,1) [HDR] _NebulaColor2("Nebula Color 2", Color) = (1,1,1,1) [HDR] _FractalColor("Fractal Color", Color) = (1,1,1,1) _NebulaMap("Nebula Map", 2D) = "black" _StarMap("Star Map", 2D) = "black" _FractalMap("Fractal Map", 2D) = "black" _OverallPower("Overall Power", Float) = 1.0 } SubShader { Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalRenderPipeline" } Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes { float4 positionOS : POSITION; // The uv variable contains the UV coordinate on the texture for the // given vertex. float2 uv : TEXCOORD0; }; struct Varyings { float4 positionHCS : SV_POSITION; // The uv variable contains the UV coordinate on the texture for the // given vertex. float2 uv : TEXCOORD0; }; float4 _NebulaColor1; float4 _NebulaColor2; float4 _FractalColor; float _OverallPower; TEXTURE2D(_NebulaMap); SAMPLER(sampler_NebulaMap); TEXTURE2D(_StarMap); SAMPLER(sampler_StarMap); TEXTURE2D(_FractalMap); SAMPLER(sampler_FractalMap); CBUFFER_START(UnityPerMaterial) // The following line declares the _BaseMap_ST variable, so that you // can use the _BaseMap variable in the fragment shader. The _ST // suffix is necessary for the tiling and offset function to work. float4 _NebulaMap_ST; float4 _StarMap_ST; float4 _FractalMap_ST; CBUFFER_END Varyings vert(Attributes IN) { Varyings OUT; OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.uv = IN.uv; return OUT; } float2 rotateUV(float2 uv, float rotation) { float mid = 0.5; return float2( cos(rotation) * (uv.x - mid) + sin(rotation) * (uv.y - mid) + mid, cos(rotation) * (uv.y - mid) - sin(rotation) * (uv.x - mid) + mid ); } half4 frag(Varyings IN) : SV_Target { float2 res = _ScreenParams; float2 p = -1.0+2.0*IN.positionHCS.xy/res.xy; p.x *= res.x/res.y; // shared tunnel vars float r = length(p); float a = atan(p.y/p.x); // sample nebula 1 float n1_stretch = 1.0/50.0; float n1_speed = 20.0; float n1_spin = 10.0; float n1_power = 2.0; float n1_cutoff = 0.5; float2 nuv1; nuv1.x = n1_stretch/(r*r) + _Time * n1_speed; nuv1.y = a/PI + _Time * n1_spin; half4 nebula1 = SAMPLE_TEXTURE2D(_NebulaMap, sampler_NebulaMap, nuv1); nebula1 *= _NebulaColor1; nebula1 *= max(0,n1_power*r-n1_cutoff); // sample nebula 2 - same as nebula 1 but in another direction float n2_stretch = 1.0/100.0; float n2_speed = 30.0; float n2_spin = -5.0; float n2_power = 4.0; float n2_cutoff = 0.5; float2 nuv2; nuv2.x = n2_stretch/(r*r) + _Time * n2_speed; nuv2.y = a/PI + _Time * n2_spin; half4 nebula2 = SAMPLE_TEXTURE2D(_NebulaMap, sampler_NebulaMap, nuv2.yx); nebula2 *= _NebulaColor2; nebula2 *= max(0,n2_power*r - n2_cutoff); // sample stars float starStretch = 1.0/100.0; float starSpeed = 10.0; int starWrap = 3; // star uv float2 suv; // use the root to make them into radial lines instead of a tunnel suv.x = starStretch/sqrt(r) + _Time * starSpeed; suv.y = (float)starWrap*a/PI; half4 star = SAMPLE_TEXTURE2D(_StarMap, sampler_StarMap, suv); star *= r * r * 2.0; // sample fractal float fractalScale = 4.0; float fractalRotateSpeed = 20.0; float fractalPower = 1.0; float fractal_inner = 0.2; // fractal uv float2 fuv = p / fractalScale + float2(0.5,0.5); fuv = rotateUV(fuv,_Time*fractalRotateSpeed); half4 fractal = SAMPLE_TEXTURE2D(_FractalMap, sampler_FractalMap, fuv); fractal *= _FractalColor; fractal *= max(0, r-fractal_inner); fractal *= fractalPower; half4 color = half4(0,0,0,0); color += nebula1; color += nebula2; color += fractal; color += star; saturate(color); color *= _OverallPower; return color; } ENDHLSL } } }