206 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			HLSL
		
	
	
	
		
		
			
		
	
	
			206 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			HLSL
		
	
	
	
| 
								 | 
							
								// Curved World <http://u3d.as/1W8h>
							 | 
						||
| 
								 | 
							
								// Copyright (c) Amazing Assets <https://amazingassets.world>
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef UNITY_BUILTIN_3X_TREE_LIBRARY_INCLUDED
							 | 
						||
| 
								 | 
							
								#define UNITY_BUILTIN_3X_TREE_LIBRARY_INCLUDED
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Shared tree shader functionality for Unity 3.x Tree Creator shaders
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "UnityCG.cginc"
							 | 
						||
| 
								 | 
							
								#include "Lighting.cginc"
							 | 
						||
| 
								 | 
							
								#include "TerrainEngine.cginc"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "../../Core/CurvedWorldTransform.cginc" 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fixed4 _Color;
							 | 
						||
| 
								 | 
							
								fixed3 _TranslucencyColor;
							 | 
						||
| 
								 | 
							
								fixed _TranslucencyViewDependency;
							 | 
						||
| 
								 | 
							
								half _ShadowStrength;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct LeafSurfaceOutput {
							 | 
						||
| 
								 | 
							
								    fixed3 Albedo;
							 | 
						||
| 
								 | 
							
								    fixed3 Normal;
							 | 
						||
| 
								 | 
							
								    fixed3 Emission;
							 | 
						||
| 
								 | 
							
								    fixed Translucency;
							 | 
						||
| 
								 | 
							
								    half Specular;
							 | 
						||
| 
								 | 
							
								    fixed Gloss;
							 | 
						||
| 
								 | 
							
								    fixed Alpha;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline half4 LightingTreeLeaf (LeafSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    half3 h = normalize (lightDir + viewDir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    half nl = dot (s.Normal, lightDir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    half nh = max (0, dot (s.Normal, h));
							 | 
						||
| 
								 | 
							
								    half spec = pow (nh, s.Specular * 128.0) * s.Gloss;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // view dependent back contribution for translucency
							 | 
						||
| 
								 | 
							
								    fixed backContrib = saturate(dot(viewDir, -lightDir));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // normally translucency is more like -nl, but looks better when it's view dependent
							 | 
						||
| 
								 | 
							
								    backContrib = lerp(saturate(-nl), backContrib, _TranslucencyViewDependency);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    fixed3 translucencyColor = backContrib * s.Translucency * _TranslucencyColor;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // wrap-around diffuse
							 | 
						||
| 
								 | 
							
								    nl = max(0, nl * 0.6 + 0.4);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    fixed4 c;
							 | 
						||
| 
								 | 
							
								    /////@TODO: what is is this multiply 2x here???
							 | 
						||
| 
								 | 
							
								    c.rgb = s.Albedo * (translucencyColor * 2 + nl);
							 | 
						||
| 
								 | 
							
								    c.rgb = c.rgb * _LightColor0.rgb + spec;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // For directional lights, apply less shadow attenuation
							 | 
						||
| 
								 | 
							
								    // based on shadow strength parameter.
							 | 
						||
| 
								 | 
							
								    #if defined(DIRECTIONAL) || defined(DIRECTIONAL_COOKIE)
							 | 
						||
| 
								 | 
							
								    c.rgb *= lerp(1, atten, _ShadowStrength);
							 | 
						||
| 
								 | 
							
								    #else
							 | 
						||
| 
								 | 
							
								    c.rgb *= atten;
							 | 
						||
| 
								 | 
							
								    #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    c.a = s.Alpha;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return c;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// -------- Per-vertex lighting functions for "Tree Creator Leaves Fast" shaders
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fixed3 ShadeTranslucentMainLight (float4 vertex, float3 normal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    float3 viewDir = normalize(WorldSpaceViewDir(vertex));
							 | 
						||
| 
								 | 
							
								    float3 lightDir = normalize(WorldSpaceLightDir(vertex));
							 | 
						||
| 
								 | 
							
								    fixed3 lightColor = _LightColor0.rgb;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    float nl = dot (normal, lightDir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // view dependent back contribution for translucency
							 | 
						||
| 
								 | 
							
								    fixed backContrib = saturate(dot(viewDir, -lightDir));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // normally translucency is more like -nl, but looks better when it's view dependent
							 | 
						||
| 
								 | 
							
								    backContrib = lerp(saturate(-nl), backContrib, _TranslucencyViewDependency);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // wrap-around diffuse
							 | 
						||
| 
								 | 
							
								    fixed diffuse = max(0, nl * 0.6 + 0.4);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return lightColor.rgb * (diffuse + backContrib * _TranslucencyColor);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fixed3 ShadeTranslucentLights (float4 vertex, float3 normal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    float3 viewDir = normalize(WorldSpaceViewDir(vertex));
							 | 
						||
| 
								 | 
							
								    float3 mainLightDir = normalize(WorldSpaceLightDir(vertex));
							 | 
						||
| 
								 | 
							
								    float3 frontlight = ShadeSH9 (float4(normal,1.0));
							 | 
						||
| 
								 | 
							
								    float3 backlight = ShadeSH9 (float4(-normal,1.0));
							 | 
						||
| 
								 | 
							
								    #ifdef VERTEXLIGHT_ON
							 | 
						||
| 
								 | 
							
								    float3 worldPos = mul(unity_ObjectToWorld, vertex).xyz;
							 | 
						||
| 
								 | 
							
								    frontlight += Shade4PointLights (
							 | 
						||
| 
								 | 
							
								        unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
							 | 
						||
| 
								 | 
							
								        unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
							 | 
						||
| 
								 | 
							
								        unity_4LightAtten0, worldPos, normal);
							 | 
						||
| 
								 | 
							
								    backlight += Shade4PointLights (
							 | 
						||
| 
								 | 
							
								        unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
							 | 
						||
| 
								 | 
							
								        unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
							 | 
						||
| 
								 | 
							
								        unity_4LightAtten0, worldPos, -normal);
							 | 
						||
| 
								 | 
							
								    #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // view dependent back contribution for translucency using main light as a cue
							 | 
						||
| 
								 | 
							
								    fixed backContrib = saturate(dot(viewDir, -mainLightDir));
							 | 
						||
| 
								 | 
							
								    backlight = lerp(backlight, backlight * backContrib, _TranslucencyViewDependency);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // as we integrate over whole sphere instead of normal hemi-sphere
							 | 
						||
| 
								 | 
							
								    // lighting gets too washed out, so let's half it down
							 | 
						||
| 
								 | 
							
								    return 0.5 * (frontlight + backlight * _TranslucencyColor);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TreeVertBark (inout appdata_full v)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    v.vertex.xyz *= _TreeInstanceScale.xyz;
							 | 
						||
| 
								 | 
							
								    v.vertex = AnimateVertex(v.vertex, v.normal, float4(v.color.xy, v.texcoord1.xy));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    v.vertex = Squash(v.vertex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//Curved World
							 | 
						||
| 
								 | 
							
								    #if defined(CURVEDWORLD_IS_INSTALLED) && !defined(CURVEDWORLD_DISABLED_ON)
							 | 
						||
| 
								 | 
							
								        #ifdef CURVEDWORLD_NORMAL_TRANSFORMATION_ON
							 | 
						||
| 
								 | 
							
								            CURVEDWORLD_TRANSFORM_VERTEX_AND_NORMAL(v.vertex, v.normal, v.tangent)
							 | 
						||
| 
								 | 
							
								        #else
							 | 
						||
| 
								 | 
							
								            CURVEDWORLD_TRANSFORM_VERTEX(v.vertex)
							 | 
						||
| 
								 | 
							
								        #endif
							 | 
						||
| 
								 | 
							
								    #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    v.color.rgb = _TreeInstanceColor.rgb * _Color.rgb;
							 | 
						||
| 
								 | 
							
								    v.normal = normalize(v.normal);
							 | 
						||
| 
								 | 
							
								    v.tangent.xyz = normalize(v.tangent.xyz);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TreeVertLeaf (inout appdata_full v)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ExpandBillboard (UNITY_MATRIX_IT_MV, v.vertex, v.normal, v.tangent);
							 | 
						||
| 
								 | 
							
								    v.vertex.xyz *= _TreeInstanceScale.xyz;
							 | 
						||
| 
								 | 
							
								    v.vertex = AnimateVertex (v.vertex,v.normal, float4(v.color.xy, v.texcoord1.xy));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    v.vertex = Squash(v.vertex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//Curved World
							 | 
						||
| 
								 | 
							
								    #if defined(CURVEDWORLD_IS_INSTALLED) && !defined(CURVEDWORLD_DISABLED_ON)
							 | 
						||
| 
								 | 
							
								        #ifdef CURVEDWORLD_NORMAL_TRANSFORMATION_ON
							 | 
						||
| 
								 | 
							
								            CURVEDWORLD_TRANSFORM_VERTEX_AND_NORMAL(v.vertex, v.normal, v.tangent)
							 | 
						||
| 
								 | 
							
								        #else
							 | 
						||
| 
								 | 
							
								            CURVEDWORLD_TRANSFORM_VERTEX(v.vertex)
							 | 
						||
| 
								 | 
							
								        #endif
							 | 
						||
| 
								 | 
							
								    #endif
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    v.color.rgb = _TreeInstanceColor.rgb * _Color.rgb;
							 | 
						||
| 
								 | 
							
								    v.normal = normalize(v.normal);
							 | 
						||
| 
								 | 
							
								    v.tangent.xyz = normalize(v.tangent.xyz);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								float ScreenDitherToAlpha(float x, float y, float c0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if (SHADER_TARGET > 30) || defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3)
							 | 
						||
| 
								 | 
							
								    //dither matrix reference: https://en.wikipedia.org/wiki/Ordered_dithering
							 | 
						||
| 
								 | 
							
								    const float dither[64] = {
							 | 
						||
| 
								 | 
							
								        0, 32, 8, 40, 2, 34, 10, 42,
							 | 
						||
| 
								 | 
							
								        48, 16, 56, 24, 50, 18, 58, 26 ,
							 | 
						||
| 
								 | 
							
								        12, 44, 4, 36, 14, 46, 6, 38 ,
							 | 
						||
| 
								 | 
							
								        60, 28, 52, 20, 62, 30, 54, 22,
							 | 
						||
| 
								 | 
							
								        3, 35, 11, 43, 1, 33, 9, 41,
							 | 
						||
| 
								 | 
							
								        51, 19, 59, 27, 49, 17, 57, 25,
							 | 
						||
| 
								 | 
							
								        15, 47, 7, 39, 13, 45, 5, 37,
							 | 
						||
| 
								 | 
							
								        63, 31, 55, 23, 61, 29, 53, 21 };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int xMat = int(x) & 7;
							 | 
						||
| 
								 | 
							
								    int yMat = int(y) & 7;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    float limit = (dither[yMat * 8 + xMat] + 11.0) / 64.0;
							 | 
						||
| 
								 | 
							
								    //could also use saturate(step(0.995, c0) + limit*(c0));
							 | 
						||
| 
								 | 
							
								    //original step(limit, c0 + 0.01);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return lerp(limit*c0, 1.0, c0);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    return 1.0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								float ComputeAlphaCoverage(float4 screenPos, float fadeAmount)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if (SHADER_TARGET > 30) || defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3)
							 | 
						||
| 
								 | 
							
								    float2 pixelPosition = screenPos.xy / (screenPos.w + 0.00001);
							 | 
						||
| 
								 | 
							
								    pixelPosition *= _ScreenParams;
							 | 
						||
| 
								 | 
							
								    float coverage = ScreenDitherToAlpha(pixelPosition.x, pixelPosition.y, fadeAmount);
							 | 
						||
| 
								 | 
							
								    return coverage;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    return 1.0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // UNITY_BUILTIN_3X_TREE_LIBRARY_INCLUDED
							 |