Files
kaiju/Assets/Scenes/MDNA_GeneDrive/GeneDrive 1.shader

234 lines
6.8 KiB
GLSL

Shader "FullScreen/GeneDrive"
{
Properties
{
_SpectrumTexture("SpectrumTexture", 2D) = "white" {}
_ThemeTexture("ThemeTexture", 2D) = "white" {}
_SpectrumSize("SpectrumSize", float) = 16
_SphereSize("SphereSize", range(0, 3)) = 1
_SphereStretch("SphereStretch", range(0, 3)) = 1
}
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 _SphereSize;
float _SphereStretch;
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.802872);
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 + 0.5 * (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) {
const float Grid = 8.0;
const int Iterations = 4;
// time stretched with noise
float t = time * 1.0 + rng * 0.9;
// float t = highs;
// domain repetition
float3 grid = float3(Grid, Grid, Grid);
float3 cell = floor(p/grid);
p = repeat(p, grid);
// distance from origin
float dp = length(p);
// rotation parameter
float3 angle = float3(1.1,-.5,.1) + dp*.1 + p*.1 + cell;
// shrink sphere size
float size = sin(_SphereSize * rng); //sin(rng*3.14);
// stretch sphere
// float wave = sin(-dp*1.+t+hash13(cell)*6.28)*.5;
float wave = sin(-dp*_SphereStretch+hash13(cell) * Grid) * _SphereStretch;
// float a = 1.0;
// float a = smoothstep(0.0, 1.0, mids) * 0.5;
float freq = length(cell) % 4;
float a = tex2D(_SpectrumTexture, 1 / freq);
// a = 1.0 / freq;
// float a = highs;
float scene = 1000.0;
float shape = 1000.0;
for (int index = 0; index < Iterations; ++index) {
// fold and translate
p.xz = abs(p.xz) - (0.5 + 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)+a*size * 2.0;
// material blending
// material = lerp(material, float(index), smoothing(shape, scene, 0.3*a));
material = lerp(material, float(index), smoothing(shape, scene, a));
// add with a blend
// scene = smin(scene, shape, 1.0 * a);
scene = smin(scene, shape, _SphereSize * 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;
time = _Time.y;
float4 colour = float4(0.0, 0.0, 0.0, 1.0);
material = 0.0;
// camera coordinates
float2 uv = guv;
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, shade);
// 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;
return colour;
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Name "GeneDrive"
ZWrite Off
ZTest Always
// Blend SrcAlpha OneMinusSrcAlpha
Cull Off
HLSLPROGRAM
#pragma fragment FullScreenPass
ENDHLSL
}
}
Fallback Off
}