Shader "FullScreen/Botany" { Properties { _SpectrumTexture("SpectrumTexture", 2D) = "white" {} _ThemeTexture("ThemeTexture", 2D) = "white" {} _SpectrumSize("SpectrumSize", float) = 16 _Zoom("Zoom", range(1, 10)) = 5 _Wildness("Wildness", range(0.2, 2.0)) = 0.8 _Brightness("Brightness", range(1, 10)) = 4.0 } HLSLINCLUDE // HDRP stuff #pragma vertex Vert #pragma target 4.5 #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl" // here we go... sampler2D _SpectrumTexture; sampler2D _ThemeTexture; float _Zoom; float _Wildness; float _Brightness; float material; float time; float rng; float sub; float bass; float mids; float highs; // ------------------------------------- // https://www.shadertoy.com/view/NddSWs // source // Dave Hoskins // https://www.shadertoy.com/view/4djSRW float hash13(float3 p3) { p3 = frac(p3 * .420); p3 += dot(p3, p3.zyx + 322.8); return frac((p3.x + p3.y) * p3.z); } // Inigo Quilez // https://iquilezles.org/articles/distfunctions float smin(float d1, float d2, float k) { float h = clamp(0.5 + bass * (d2-d1) / k, 0.0, 1.0); return lerp(d2, d1, h) - k*h*(1.0-h); } float smoothing(float d1, float d2, float k) { return clamp( 0.5 + 0.5 *(d2-d1)/k, 0.0, 1.0 ); } // rotation matrix float2x2 rot(float a) { float2x2 rm = { cos(a), -sin(a), sin(a), cos(a) }; return rm; } #define mod(x, y) (x - y * floor(x / y)) float3 repeat(float3 p, float3 r) { return mod(p , r) - r / 2.0; } // sdf float map (float3 p) { // time stretched with noise float t = time * 1.0 + rng * 2.9; // domain repetition float3 grid = float3(_Zoom, _Zoom, _Zoom); float3 cell = floor(p/grid); p = repeat(p, grid); // distance from origin float dp = length(p); // rotation parameter float3 angle = float3(.1,-.5,.1) + dp*.5 + p*.1 + cell; // shrink sphere size float size = sin(rng*3.14); // stretch sphere float wave = sin(-dp*1.+t+hash13(cell)*6.28)*.5; // kaleidoscopic iterated function const int count = 4; // float a = 1.0; float a = 2.0; float scene = 1000.0; float shape = 1000.0; for (int index = 0; index < count; ++index) { // fold and translate p.xz = abs(p.xz) - (_Wildness + wave) * a; // p.xz = abs(p.xz) - (0.5 + wave) * a; // rotate // p.xz = mul(rot(angle.y/a), p.xz); // p.yz = mul(rot(angle.x/a), p.yz); // p.yx = mul(rot(angle.z/a), p.yx); p.xz = mul(p.xz, rot(angle.y/a)); p.yz = mul(p.yz, rot(angle.x/a)); p.yx = mul(p.yx, rot(angle.z/a)); // sphere shape = length(p)-0.2*a*size; // material blending // material = lerp(material, float(index), smoothing(shape, scene, 0.3*a)); material = lerp(material, float(index), smoothing(shape, scene, mids*a)); // add with a blend // scene = smin(scene, shape, 1.0 * a); scene = smin(scene, shape, 2.0 * sub * a); // falloff transformations a /= 1.9; } return scene; } float4 FullScreenPass(Varyings varyings) : SV_Target { float depth = LoadCameraDepth(varyings.positionCS.xy); PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V); float2 ndc = posInput.positionNDC; // convert to glsl mode and fix aspect ratio float2 guv = posInput.positionNDC - 0.5; guv.x *= _ScreenParams.x / _ScreenParams.y; // musique sub = tex2D(_SpectrumTexture, 0.0); bass = tex2D(_SpectrumTexture, 0.25); mids = tex2D(_SpectrumTexture, 0.50); highs = tex2D(_SpectrumTexture, 0.75); // float4 spectrum = float4(sub, bass, mids, highs); time = _Time.y; float4 colour = float4(0.0, 0.0, 0.0, 1.0); material = 0.0; // camera coordinates float2 uv = guv * 2.5; float3 eye = float3(sin(time * 0.1) * 5.0, cos(time * 0.1) * 5.0, 1.0); // float3 eye = float3(5.0, 5.0, 1.0); float3 at = float3(0.0, 0.0, 0.0); float3 z = normalize(at-eye); float3 x = normalize(cross(z, float3(0.0,1.0,0.0))); float3 y = cross(x, z); float3 ray = normalize(float3(z + uv.x * x + uv.y * y)); float3 pos = eye; // // camera control // float2 M = 6.28 * float2(1.0, 1.0); // ray.xz = mul(ray.xz, rot(M.x)); // pos.xz = mul(pos.xz, rot(M.x)); // ray.xy = mul(ray.xy, rot(M.y)); // pos.xy = mul(pos.xy, rot(M.y)); // white noise float3 seed = float3(ndc, highs * 420.0); float rng = hash13(seed); // raymarch float steps = 30.0; float index; for (index = steps; index > 0.0; --index) { // volume estimation float dist = map(pos); if (dist < 0.01) { break; } // dithering // dist *= 0.9 + .1 * rng; // raymarch pos += ray * dist; } // ambient occlusion from steps count float shade = index / steps; // compute normal by NuSan (https://www.shadertoy.com/view/3sBGzV) float2 off=float2(.001,0); float3 normal = normalize(map(pos)-float3(map(pos-off.xyy), map(pos-off.yxy), map(pos-off.yyx))); float3 tint = tex2D(_ThemeTexture, material); // lighting float ld = dot(reflect(ray, normal), float3(0.0,1.0,0.0))*0.5+0.5; float3 light = float3(1.000,0.502,0.502) * sqrt(ld); ld = dot(reflect(ray, normal), float3(0,0,-1))*0.5+0.5; light += float3(0.400,0.714,0.145) * sqrt(ld)*.5; // pixel color colour.rgb = (tint + light) * shade; // temporal buffer // colour = max(colour, texture(iChannel0, fragCoord/iResolution.xy) - 0.01); return colour; } ENDHLSL SubShader { Tags{ "RenderPipeline" = "HDRenderPipeline" } Pass { Name "Botany" ZWrite Off ZTest Always // Blend SrcAlpha OneMinusSrcAlpha Cull Off HLSLPROGRAM #pragma fragment FullScreenPass ENDHLSL } } Fallback Off }