shader_type spatial; render_mode cull_disabled; //uniform int _ShellIndex; // index of shell being worked on (0 -> _ShellCount) uniform float _NoiseMin; // minimum strand length uniform float _NoiseMax; // maxmimum strand length uniform float _ShellLength; // amount of distance that the shells cover, 1 means shells will span across 1 world space unit uniform int _ShellCount; // total number of shells (for normalizing the shell index) uniform float _ShellDistanceAttenuation; // exponent how far to push the shell outwards uniform float _Thickness; // how thick a strand shall be uniform float _Attenuation; // AO strength factor uniform float _OcclusionBias; // additive bias for AO uniform vec3 _ShellColor; uniform float _Density; // amout of strands to generate varying flat int _ShellIndex; float hash(uint n) { n = (n << 13U) ^ n; n = n * (n * n * 15731U + 1239221U) + 123376312589U; return float(n & uint(0x7fffffffU)) / float(0x7fffffff); } void vertex() { _ShellIndex = int(INSTANCE_CUSTOM.x); float shell_height = float(_ShellIndex) / float(_ShellCount); shell_height = pow(shell_height, _ShellDistanceAttenuation); VERTEX.xyz += NORMAL.xyz * _ShellLength * shell_height; //NORMAL = normalize(NORMAL); UV = UV; } void fragment() { vec2 newUV = UV * _Density; vec2 localUV = fract(newUV) * 2. - 1.; float localDistanceFromCenter = length(localUV); float h = float(_ShellIndex) / float(_ShellCount); // normalized height uint seed = uint(int(newUV.x) + 100 * int(newUV.y) + 100 * 10); float rand = mix(_NoiseMin, _NoiseMax, hash(seed)); // getting random value for strand if (localDistanceFromCenter > _Thickness * (rand - h) && _ShellIndex > 0) discard; // discarding pixels outside of thickness //float ndotl = dot(NORMAL, WORLD) // TODO do light later? float ambientOcclusion = pow(h, _Attenuation); // fake Ambient Occlusion ambientOcclusion += _OcclusionBias; // Called for every pixel the material is visible on. ALBEDO.rgb = _ShellColor * ambientOcclusion; //ALPHA = 1.0; } void light() { float ndotl = clamp(dot(NORMAL, LIGHT), 0., 1.) * .5 + .5; DIFFUSE_LIGHT += ndotl * ndotl; }