You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			62 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Plaintext
		
	
			
		
		
	
	
			62 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Plaintext
		
	
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;
 | 
						|
}
 |