diff --git a/Assets/Shaders/DecalFeatureBumped.shader b/Assets/Shaders/DecalFeatureBumped.shader index c52a40d..6feb818 100644 --- a/Assets/Shaders/DecalFeatureBumped.shader +++ b/Assets/Shaders/DecalFeatureBumped.shader @@ -42,6 +42,9 @@ Shader "ConformalDecals/Feature/Bumped" sampler2D _Decal; sampler2D _DecalBumpMap; + + float4 _Decal_ST; + float4 _DecalBumpMap_ST; float _Cutoff; float _Opacity; @@ -50,27 +53,29 @@ Shader "ConformalDecals/Feature/Bumped" void surf (DecalSurfaceInput IN, inout SurfaceOutput o) { - fixed4 projUV = UNITY_PROJ_COORD(IN.uv_decal); + fixed4 uv_projected = UNITY_PROJ_COORD(IN.uv_decal); // since I cant easily affect the clamping mode in KSP, do it here - clip(projUV.xyz); - clip(1-projUV.xyz); + clip(uv_projected.xyz); + clip(1-uv_projected.xyz); // clip backsides clip(dot(_DecalNormal, IN.normal)); - - float4 color = tex2D(_Decal, projUV); - float3 normal = UnpackNormal(tex2D(_DecalBumpMap, projUV)); - half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal)); - float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; - + + float2 uv_decal = TRANSFORM_TEX(uv_projected, _Decal); + float4 color = tex2D(_Decal, uv_decal); + float3 normal = UnpackNormal(tex2D(_DecalBumpMap, uv_decal)); + // clip alpha clip(color.a - _Cutoff); + half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal)); + float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; + o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb; o.Alpha = color.a * _Opacity; o.Emission = emission; - o.Normal = DECAL_ORIENT_NORMAL(normal, IN); + o.Normal = normal; } ENDCG @@ -97,6 +102,9 @@ Shader "ConformalDecals/Feature/Bumped" sampler2D _Decal; sampler2D _DecalBumpMap; + float4 _Decal_ST; + float4 _DecalBumpMap_ST; + float _Cutoff; float _Opacity; float _RimFalloff; @@ -104,27 +112,29 @@ Shader "ConformalDecals/Feature/Bumped" void surf (DecalSurfaceInput IN, inout SurfaceOutput o) { - fixed4 projUV = UNITY_PROJ_COORD(IN.uv_decal); + fixed4 uv_projected = UNITY_PROJ_COORD(IN.uv_decal); // since I cant easily affect the clamping mode in KSP, do it here - clip(projUV.xyz); - clip(1-projUV.xyz); + clip(uv_projected.xyz); + clip(1-uv_projected.xyz); // clip backsides clip(dot(_DecalNormal, IN.normal)); - - float4 color = tex2D(_Decal, projUV); - float3 normal = UnpackNormal(tex2D(_DecalBumpMap, projUV)); - half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal)); - float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; - + + float2 uv_decal = TRANSFORM_TEX(uv_projected, _Decal); + float4 color = tex2D(_Decal, uv_decal); + float3 normal = UnpackNormal(tex2D(_DecalBumpMap, uv_decal)); + // clip alpha clip(color.a - _Cutoff); + half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal)); + float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; + o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb; o.Alpha = color.a * _Opacity; o.Emission = emission; - o.Normal = DECAL_ORIENT_NORMAL(normal, IN); + o.Normal = normal; } ENDCG diff --git a/Assets/Shaders/DecalPaint.shader b/Assets/Shaders/DecalPaint.shader index 9fac776..dd1c66b 100644 --- a/Assets/Shaders/DecalPaint.shader +++ b/Assets/Shaders/DecalPaint.shader @@ -1,80 +1,169 @@ Shader "ConformalDecals/Paint/Diffuse" { - Properties - { - _Decal ("Cookie", 2D) = "gray" {} - _BumpMap("_BumpMap", 2D) = "bump" {} + Properties + { + [Header(Texture Maps)] + _Decal("Decal Texture", 2D) = "gray" {} + _BumpMap("Bump Map", 2D) = "bump" {} + _EdgeWearStrength("Edge Wear Strength", Range(0,100)) = 0 + _EdgeWearOffset("Edge Wear Offset", Range(0,1)) = 0 + _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5 _Opacity("_Opacity", Range(0,1) ) = 1 - _NormalWear("_NormalWear", Range(0,100)) = 50 - } - - SubShader - { - Tags { "Queue" = "Geometry" } - - ZWrite On - ZTest LEqual - Blend SrcAlpha OneMinusSrcAlpha - - CGPROGRAM - - #pragma surface surf Lambert alpha vertex:vert - #pragma target 4.0 - - float4x4 _ProjectionMatrix; - float3 _DecalNormal; - float3 _DecalBiNormal; - sampler2D _Decal; - sampler2D _DecalBumpMap; - sampler2D _BumpMap; - - float _Cutoff; - float _Opacity; - float _NormalWear; + [Header(Effects)] + [PerRendererData]_Opacity("_Opacity", Range(0,1) ) = 1 + [PerRendererData]_RimFalloff("_RimFalloff", Range(0.01,5) ) = 0.1 + [PerRendererData]_RimColor("_RimColor", Color) = (0,0,0,0) + [PerRendererData]_UnderwaterFogFactor ("Underwater Fog Factor", Range(0,1)) = 0 + } + SubShader + { + Tags { "Queue" = "Geometry+400" } + ZWrite Off + ZTest LEqual + Offset -1, -1 + + Pass + { + Name "FORWARD" + Tags { "LightMode" = "ForwardBase" } + Blend SrcAlpha OneMinusSrcAlpha - struct Input - { - float4 decal : TEXCOORD0; - float2 uv_BumpMap : TEXCOORD1; - float4 position : SV_POSITION; - float3 normal : NORMAL; - }; + CGPROGRAM + #pragma vertex vert_forward + #pragma fragment frag_forward - void vert (inout appdata_full v, out Input o) { - o.decal = mul (_ProjectionMatrix, v.vertex); - o.uv_BumpMap = v.texcoord.xy; - o.position = UnityObjectToClipPos(v.vertex); - o.normal = v.normal; - } + #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap + + sampler2D _Decal; + sampler2D _BumpMap; + + float4 _Decal_ST; + float4 _BumpMap_ST; + + float _EdgeWearStrength; + float _EdgeWearOffset; + + float _Cutoff; + float _Opacity; + float _RimFalloff; + float4 _RimColor; + + #define DECAL_BASE_NORMAL + + #include "UnityCG.cginc" + #include "Lighting.cginc" + #include "AutoLight.cginc" + #include "LightingKSP.cginc" + #include "DecalsCommon.cginc" - void surf (Input IN, inout SurfaceOutput o) - { - fixed4 projUV = UNITY_PROJ_COORD(IN.decal); + void surf (DecalSurfaceInput IN, inout SurfaceOutput o) + { + fixed4 uv_projected = UNITY_PROJ_COORD(IN.uv_decal); - // since I cant easily affect the clamping mode in KSP, do it here - clip(projUV.xyz); - clip(1-projUV.xyz); - - // clip backsides - clip(dot(_DecalNormal, IN.normal)); + // since I cant easily affect the clamping mode in KSP, do it here + clip(uv_projected.xyz); + clip(1-uv_projected.xyz); + + // clip backsides + clip(dot(_DecalNormal, IN.normal)); + + float2 uv_decal = TRANSFORM_TEX(uv_projected, _Decal); + float4 color = tex2D(_Decal, uv_decal); + + // clip alpha + clip(color.a - _Cutoff); - float4 color = tex2D(_Decal, projUV); - float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); - - color.a *= (1 - (_NormalWear * (1 - dot(normal, fixed3(0,0,1))))); - clip (color.a - _Cutoff); - - fixed2 normalGradient = fixed2(ddx(normal.z), ddy(normal.z)); + float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base)); + half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal)); + float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; + + float wearFactor = 1 - normal.z; + float wearFactorAlpha = saturate(_EdgeWearStrength * wearFactor); - o.Albedo = color.rgb; - //o.Albedo = projUV; - o.Normal = normal; - o.Alpha = color.a * _Opacity; - } + color.a *= saturate(1 + _EdgeWearOffset - saturate(_EdgeWearStrength * wearFactor)); + + o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb; + o.Alpha = color.a * _Opacity; + o.Emission = emission; + o.Normal = normal; + } - ENDCG - } -} \ No newline at end of file + ENDCG + } + + Pass + { + Name "FORWARD" + Tags { "LightMode" = "ForwardAdd" } + Blend One One + + CGPROGRAM + #pragma vertex vert_forward + #pragma fragment frag_forward + + #pragma multi_compile_fwdadd nolightmap nodirlightmap nodynlightmap + + sampler2D _Decal; + sampler2D _BumpMap; + + float4 _Decal_ST; + float4 _BumpMap_ST; + + float _EdgeWearStrength; + float _EdgeWearOffset; + + float _Cutoff; + float _Opacity; + float _RimFalloff; + float4 _RimColor; + + #define DECAL_BASE_NORMAL + + #include "UnityCG.cginc" + #include "Lighting.cginc" + #include "AutoLight.cginc" + #include "LightingKSP.cginc" + #include "DecalsCommon.cginc" + + void surf (DecalSurfaceInput IN, inout SurfaceOutput o) + { + fixed4 uv_projected = UNITY_PROJ_COORD(IN.uv_decal); + + // since I cant easily affect the clamping mode in KSP, do it here + clip(uv_projected.xyz); + clip(1-uv_projected.xyz); + + // clip backsides + clip(dot(_DecalNormal, IN.normal)); + + float2 uv_decal = TRANSFORM_TEX(uv_projected, _Decal); + float4 color = tex2D(_Decal, uv_decal); + + // clip alpha + clip(color.a - _Cutoff); + + float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base)); + half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal)); + float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; + + float wearFactor = 1 - normal.z; + float wearFactorAlpha = saturate(_EdgeWearStrength * wearFactor); + + color.a *= saturate(1 + _EdgeWearOffset - saturate(_EdgeWearStrength * wearFactor)); + + o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb; + o.Alpha = color.a * _Opacity; + o.Emission = emission; + o.Normal = normal; + } + + ENDCG + } + + // shadow casting support + UsePass "Legacy Shaders/VertexLit/SHADOWCASTER" + } +} \ No newline at end of file diff --git a/Assets/Shaders/DecalsCommon.cginc b/Assets/Shaders/DecalsCommon.cginc index 9e90663..524be8b 100644 --- a/Assets/Shaders/DecalsCommon.cginc +++ b/Assets/Shaders/DecalsCommon.cginc @@ -1,17 +1,6 @@ #ifndef DECALS_COMMON_INCLUDED #define DECALS_COMMON_INCLUDED -inline fixed3 OrientNormal(float3 normal, float4 tSpace0, float4 tSpace1, float4 tSpace2) { - float3 WorldNormal; - WorldNormal.x = dot(tSpace0.xyz, normal); - WorldNormal.y = dot(tSpace1.xyz, normal); - WorldNormal.z = dot(tSpace2.xyz, normal); - WorldNormal = normalize(WorldNormal); - return WorldNormal; -} - -#define DECAL_ORIENT_NORMAL(normal, IN) OrientNormal(normal, IN.tSpace0, IN.tSpace1, IN.tSpace2) - struct DecalSurfaceInput { float4 uv_decal; @@ -21,10 +10,6 @@ struct DecalSurfaceInput float3 normal; float3 viewDir; float3 worldPosition; - - float4 tSpace0; - float4 tSpace1; - float4 tSpace2; }; struct appdata_decal @@ -33,6 +18,7 @@ struct appdata_decal float3 normal : NORMAL; #ifdef DECAL_BASE_NORMAL float4 texcoord : TEXCOORD0; + float4 tangent : TANGENT; #endif //DECAL_BASE_NORMAL }; @@ -157,9 +143,6 @@ fixed4 frag_forward(v2f IN) : SV_Target i.normal = IN.normal; i.viewDir = viewDir; i.worldPosition = worldPosition; - i.tSpace0 = IN.tSpace0; - i.tSpace1 = IN.tSpace1; - i.tSpace2 = IN.tSpace2; // initialize surface output o.Albedo = 0.0; @@ -175,6 +158,15 @@ fixed4 frag_forward(v2f IN) : SV_Target // compute lighting & shadowing factor UNITY_LIGHT_ATTENUATION(atten, IN, worldPosition) + // compute world normal + float3 WorldNormal; + WorldNormal.x = dot(_unity_tbn_0, o.Normal); + WorldNormal.y = dot(_unity_tbn_1, o.Normal); + WorldNormal.z = dot(_unity_tbn_2, o.Normal); + WorldNormal = normalize(WorldNormal); + o.Normal = WorldNormal; + + //KSP lighting function c += LightingBlinnPhongSmooth(o, lightDir, viewDir, atten);