Big refactor to enable preview materials

• add shader variants for decal previewing
• start to add code for part icon
• refactor material properties to be serializable
todo:
• fix decal preview scale (need to call UpdateScale on detached state)
• fix texture preview in part icon
• adjust culling per-object when rendering (turns out cull and ztest values are used by unity at the render time, not by the shader itself, so they can be adjusted in material property blocks!)
This commit is contained in:
2020-06-04 00:12:09 -07:00
parent 6c20675a99
commit e9c8f3dafb
17 changed files with 471 additions and 326 deletions

View File

@ -4,13 +4,17 @@ Shader "ConformalDecals/Feature/Bumped"
{
[Header(Texture Maps)]
_Decal("Decal Texture", 2D) = "gray" {}
_BumpMap("Decal Bump Map", 2D) = "bump" {}
_DecalBumpMap("Decal Bump Map", 2D) = "bump" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Opacity("_Opacity", Range(0,1) ) = 1
_DecalOpacity("Opacity", Range(0,1) ) = 1
_Background("Background Color", Color) = (0.9,0.9,0.9,0.7)
[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 0
[Toggle(DECAL_PREVIEW)] _Preview ("Preview", Float) = 0
[Header(Effects)]
[PerRendererData]_Opacity("_Opacity", Range(0,1) ) = 1
[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
@ -18,9 +22,9 @@ Shader "ConformalDecals/Feature/Bumped"
SubShader
{
Tags { "Queue" = "Geometry+100" }
Cull Off
Zwrite Off
Ztest LEqual
Cull [_Cull]
Ztest LEqual
Pass
{
Name "FORWARD"
@ -32,15 +36,14 @@ Shader "ConformalDecals/Feature/Bumped"
#pragma fragment frag_forward
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap
#pragma multi_compile DECAL_PROJECT DECAL_PREVIEW
sampler2D _Decal;
sampler2D _BumpMap;
sampler2D _DecalBumpMap;
float4 _Decal_ST;
float4 _BumpMap_ST;
float _Cutoff;
float _Opacity;
float4 _DecalBumpMap_ST;
float _RimFalloff;
float4 _RimColor;
@ -55,16 +58,18 @@ Shader "ConformalDecals/Feature/Bumped"
void surf (DecalSurfaceInput IN, inout SurfaceOutput o)
{
float4 color = tex2D(_Decal, IN.uv_decal);
float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_bump));
float3 normal = UnpackNormal(tex2D(_DecalBumpMap, IN.uv_bump));
// clip alpha
clip(color.a - saturate(_Cutoff + 0.01));
#ifdef DECAL_PROJECT
// clip alpha
clip(color.a - _Cutoff + 0.01);
#endif //DECAL_PROJECT
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.Alpha = color.a * _DecalOpacity;
o.Emission = emission;
o.Normal = normal;
}
@ -83,15 +88,14 @@ Shader "ConformalDecals/Feature/Bumped"
#pragma fragment frag_forward
#pragma multi_compile_fwdadd nolightmap nodirlightmap nodynlightmap
#pragma multi_compile DECAL_PROJECT DECAL_PREVIEW
sampler2D _Decal;
sampler2D _BumpMap;
sampler2D _DecalBumpMap;
float4 _Decal_ST;
float4 _BumpMap_ST;
float4 _DecalBumpMap_ST;
float _Cutoff;
float _Opacity;
float _RimFalloff;
float4 _RimColor;
@ -106,16 +110,18 @@ Shader "ConformalDecals/Feature/Bumped"
void surf (DecalSurfaceInput IN, inout SurfaceOutput o)
{
float4 color = tex2D(_Decal, IN.uv_decal);
float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_bump));
float3 normal = UnpackNormal(tex2D(_DecalBumpMap, IN.uv_bump));
// clip alpha
clip(color.a - saturate(_Cutoff + 0.01));
#ifdef DECAL_PROJECT
// clip alpha
clip(color.a - _Cutoff + 0.01);
#endif //DECAL_PROJECT
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.Alpha = color.a * _DecalOpacity;
o.Emission = emission;
o.Normal = normal;
}

View File

@ -6,24 +6,27 @@ Shader "ConformalDecals/Paint/Diffuse"
_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
_EdgeWearStrength("Edge Wear Strength", Range(0,500)) = 100
_EdgeWearOffset("Edge Wear Offset", Range(0,1)) = 0.1
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Opacity("_Opacity", Range(0,1) ) = 1
_DecalOpacity("Opacity", Range(0,1) ) = 1
_Background("Background Color", Color) = (0.9,0.9,0.9,0.7)
[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 0
[Toggle(DECAL_PREVIEW)] _Preview ("Preview", Float) = 0
[Header(Effects)]
[PerRendererData]_Opacity("_Opacity", Range(0,1) ) = 1
[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
Tags { "Queue" = "Geometry+100" }
Cull [_Cull]
Ztest LEqual
Pass
{
@ -36,18 +39,15 @@ Shader "ConformalDecals/Paint/Diffuse"
#pragma fragment frag_forward
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap
#pragma multi_compile __ DECAL_PREVIEW
sampler2D _Decal;
sampler2D _BumpMap;
float4 _Decal_ST;
float4 _BumpMap_ST;
float _EdgeWearStrength;
float _EdgeWearOffset;
float _Cutoff;
float _Opacity;
float _RimFalloff;
float4 _RimColor;
@ -62,11 +62,10 @@ Shader "ConformalDecals/Paint/Diffuse"
void surf (DecalSurfaceInput IN, inout SurfaceOutput o)
{
float4 color = tex2D(_Decal, IN.uv_decal);
float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base));
// clip alpha
clip(color.a - _Cutoff);
decalClipAlpha(color.a);
float3 normal = IN.normal;
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal));
float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a;
@ -76,9 +75,8 @@ Shader "ConformalDecals/Paint/Diffuse"
color.a *= saturate(1 + _EdgeWearOffset - saturate(_EdgeWearStrength * wearFactor));
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
o.Alpha = color.a * _Opacity;
o.Alpha = color.a * _DecalOpacity;
o.Emission = emission;
o.Normal = normal;
}
ENDCG
@ -95,18 +93,15 @@ Shader "ConformalDecals/Paint/Diffuse"
#pragma fragment frag_forward
#pragma multi_compile_fwdadd nolightmap nodirlightmap nodynlightmap
#pragma multi_compile __ DECAL_PREVIEW
sampler2D _Decal;
sampler2D _BumpMap;
float4 _Decal_ST;
float4 _BumpMap_ST;
float _EdgeWearStrength;
float _EdgeWearOffset;
float _Cutoff;
float _Opacity;
float _RimFalloff;
float4 _RimColor;
@ -121,11 +116,10 @@ Shader "ConformalDecals/Paint/Diffuse"
void surf (DecalSurfaceInput IN, inout SurfaceOutput o)
{
float4 color = tex2D(_Decal, IN.uv_decal);
float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base));
// clip alpha
clip(color.a - _Cutoff);
decalClipAlpha(color.a);
float3 normal = IN.normal;
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal));
float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a;
@ -135,9 +129,8 @@ Shader "ConformalDecals/Paint/Diffuse"
color.a *= saturate(1 + _EdgeWearOffset - saturate(_EdgeWearStrength * wearFactor));
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
o.Alpha = color.a * _Opacity;
o.Alpha = color.a * _DecalOpacity;
o.Emission = emission;
o.Normal = normal;
}
ENDCG

View File

@ -7,16 +7,19 @@ Shader "ConformalDecals/Paint/Specular"
_BumpMap("Bump Map", 2D) = "bump" {}
_SpecMap("Specular Map", 2D) = "black" {}
_EdgeWearStrength("Edge Wear Strength", Range(0,100)) = 0
_EdgeWearOffset("Edge Wear Offset", Range(0,1)) = 0
_EdgeWearStrength("Edge Wear Strength", Range(0,500)) = 100
_EdgeWearOffset("Edge Wear Offset", Range(0,1)) = 0.1
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Opacity("_Opacity", Range(0,1) ) = 1
_DecalOpacity("Opacity", Range(0,1) ) = 1
_Background("Background Color", Color) = (0.9,0.9,0.9,0.7)
[Header(Specularity)]
_SpecColor ("_SpecColor", Color) = (0.5, 0.5, 0.5, 1)
_Shininess ("Shininess", Range (0.03, 10)) = 0.4
_SpecColor ("_SpecColor", Color) = (0.25, 0.25, 0.25, 1)
_Shininess ("Shininess", Range (0.03, 10)) = 0.3
[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 0
[Toggle(DECAL_PREVIEW)] _Preview ("Preview", Float) = 0
[Header(Effects)]
[PerRendererData]_Opacity("_Opacity", Range(0,1) ) = 1
@ -26,10 +29,9 @@ Shader "ConformalDecals/Paint/Specular"
}
SubShader
{
Tags { "Queue" = "Geometry+400" }
ZWrite Off
ZTest LEqual
Offset -1, -1
Tags { "Queue" = "Geometry+100" }
Cull [_Cull]
Ztest LEqual
Pass
{
@ -42,22 +44,19 @@ Shader "ConformalDecals/Paint/Specular"
#pragma fragment frag_forward
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap
#pragma multi_compile __ DECAL_PREVIEW
sampler2D _Decal;
sampler2D _BumpMap;
sampler2D _SpecMap;
float4 _Decal_ST;
float4 _BumpMap_ST;
float4 _SpecMap_ST;
float _EdgeWearStrength;
float _EdgeWearOffset;
half _Shininess;
float _Cutoff;
float _Opacity;
float _RimFalloff;
float4 _RimColor;
@ -73,11 +72,13 @@ Shader "ConformalDecals/Paint/Specular"
void surf (DecalSurfaceInput IN, inout SurfaceOutput o)
{
float4 color = tex2D(_Decal, IN.uv_decal);
float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base));
float3 specular = tex2D(_SpecMap, IN.uv_spec);
// clip alpha
clip(color.a - _Cutoff);
float3 normal = IN.normal;
#ifdef DECAL_PROJECT
// clip alpha
clip(color.a - _Cutoff + 0.01);
#endif //DECAL_PROJECT
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal));
float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a;
@ -86,12 +87,11 @@ Shader "ConformalDecals/Paint/Specular"
float wearFactorAlpha = saturate(_EdgeWearStrength * wearFactor);
color.a *= saturate(1 + _EdgeWearOffset - saturate(_EdgeWearStrength * wearFactor));
color.a *= _Opacity;
color.a *= _DecalOpacity;
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
o.Alpha = color.a;
o.Emission = emission;
o.Normal = normal;
o.Specular = _Shininess;
o.Gloss = specular.r * color.a;
}
@ -110,22 +110,19 @@ Shader "ConformalDecals/Paint/Specular"
#pragma fragment frag_forward
#pragma multi_compile_fwdadd nolightmap nodirlightmap nodynlightmap
#pragma multi_compile __ DECAL_PREVIEW
sampler2D _Decal;
sampler2D _BumpMap;
sampler2D _SpecMap;
float4 _Decal_ST;
float4 _BumpMap_ST;
float4 _SpecMap_ST;
float _EdgeWearStrength;
float _EdgeWearOffset;
half _Shininess;
float _Cutoff;
float _Opacity;
float _RimFalloff;
float4 _RimColor;
@ -141,11 +138,13 @@ Shader "ConformalDecals/Paint/Specular"
void surf (DecalSurfaceInput IN, inout SurfaceOutput o)
{
float4 color = tex2D(_Decal, IN.uv_decal);
float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base));
float3 specular = tex2D(_SpecMap, IN.uv_spec);
float3 normal = IN.normal;
// clip alpha
clip(color.a - _Cutoff);
#ifdef DECAL_PROJECT
// clip alpha
clip(color.a - _Cutoff + 0.01);
#endif //DECAL_PROJECT
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), normal));
float3 emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a;
@ -156,9 +155,8 @@ Shader "ConformalDecals/Paint/Specular"
color.a *= saturate(1 + _EdgeWearOffset - saturate(_EdgeWearStrength * wearFactor));
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
o.Alpha = color.a * _Opacity;
o.Alpha = color.a * _DecalOpacity;
o.Emission = emission;
o.Normal = normal;
o.Specular = _Shininess;
o.Gloss = specular.r;
}

View File

@ -18,10 +18,9 @@ struct DecalSurfaceInput
#endif //DECAL_EMISSIVE
#ifdef DECAL_BASE_NORMAL
float2 uv_base;
#endif //DECAL_BASE_NORMAL
float3 normal;
#endif
float3 normal;
float3 viewDir;
float3 worldPosition;
};
@ -30,10 +29,10 @@ struct appdata_decal
{
float4 vertex : POSITION;
float3 normal : NORMAL;
#ifdef DECAL_BASE_NORMAL
#if defined(DECAL_BASE_NORMAL) || defined(DECAL_PREVIEW)
float4 texcoord : TEXCOORD0;
float4 tangent : TANGENT;
#endif //DECAL_BASE_NORMAL
#endif
};
struct v2f
@ -65,6 +64,23 @@ float4x4 _ProjectionMatrix;
float3 _DecalNormal;
float3 _DecalTangent;
#ifdef DECAL_BASE_NORMAL
sampler2D _BumpMap;
float4 _BumpMap_ST;
#endif //DECAL_BASE_NORMAL
float _Cutoff;
float _DecalOpacity;
float _Opacity;
float4 _Background;
inline void decalClipAlpha(float alpha) {
#ifndef DECAL_PREVIEW
clip(alpha - _Cutoff + 0.01);
#endif
}
// declare surf function,
// this must be defined in any shader using this cginc
void surf (DecalSurfaceInput IN, inout SurfaceOutput o);
@ -76,7 +92,12 @@ v2f vert_forward(appdata_decal v)
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = v.normal;
o.uv_decal = mul (_ProjectionMatrix, v.vertex);
#ifdef DECAL_PREVIEW
o.uv_decal = v.texcoord;
#else
o.uv_decal = mul (_ProjectionMatrix, v.vertex);
#endif //DECAL_PREVIEW
#ifdef DECAL_BASE_NORMAL
o.uv_base = TRANSFORM_TEX(v.texcoord, _BumpMap);
@ -85,7 +106,7 @@ v2f vert_forward(appdata_decal v)
float3 worldPosition = mul(unity_ObjectToWorld, v.vertex).xyz;
float3 worldNormal = UnityObjectToWorldNormal(v.normal);
#ifdef DECAL_BASE_NORMAL
#if defined(DECAL_BASE_NORMAL) || defined(DECAL_PREVIEW)
// use tangent of base geometry
fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
@ -95,7 +116,7 @@ v2f vert_forward(appdata_decal v)
fixed3 decalTangent = UnityObjectToWorldDir(_DecalTangent);
fixed3 worldBinormal = cross(decalTangent, worldNormal);
fixed3 worldTangent = cross(worldNormal, worldBinormal);
#endif //DECAL_BASE_NORMAL
#endif //defined(DECAL_BASE_NORMAL) || defined(DECAL_PREVIEW)
o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPosition.x);
o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPosition.y);
@ -148,22 +169,26 @@ fixed4 frag_forward(v2f IN) : SV_Target
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPosition));
float3 viewDir = _unity_tbn_0 * worldViewDir.x + _unity_tbn_1 * worldViewDir.y + _unity_tbn_2 * worldViewDir.z;
// perform decal projection
fixed4 uv_projected = UNITY_PROJ_COORD(IN.uv_decal);
#ifdef DECAL_PREVIEW
fixed4 uv_projected = IN.uv_decal;
#else
// perform decal projection
fixed4 uv_projected = UNITY_PROJ_COORD(IN.uv_decal);
// clip texture outside of xyz bounds
clip(uv_projected.xyz);
clip(1-uv_projected.xyz);
// clip backsides
clip(dot(_DecalNormal, IN.normal));
// clip texture outside of xyz bounds
clip(uv_projected.xyz);
clip(1-uv_projected.xyz);
// clip backsides
clip(dot(_DecalNormal, IN.normal));
#endif //DECAL_PREVIEW
// initialize surface input
UNITY_INITIALIZE_OUTPUT(DecalSurfaceInput, i)
i.uv_decal = TRANSFORM_TEX(uv_projected, _Decal);
#ifdef DECAL_NORMAL
i.uv_bump = TRANSFORM_TEX(uv_projected, _BumpMap);
i.uv_bump = TRANSFORM_TEX(uv_projected, _DecalBumpMap);
#endif //DECAL_NORMAL
#ifdef DECAL_SPECULAR
@ -173,12 +198,16 @@ fixed4 frag_forward(v2f IN) : SV_Target
#ifdef DECAL_EMISSIVE
i.uv_glow = TRANSFORM_TEX(uv_projected, _GlowMap);
#endif //DECAL_EMISSIVE
#ifdef DECAL_BASE_NORMAL
i.uv_base = IN.uv_base;
#endif //DECAL_BASE_NORMAL
i.normal = IN.normal;
#ifdef DECAL_BASE_NORMAL
#ifdef DECAL_PREVIEW
i.normal = fixed3(0,0,1);
#else
i.normal = UnpackNormal(tex2D(_BumpMap, IN.uv_base));
#endif //DECAL_PREVIEW
#endif //DECAL_BASE_NORMAL
//i.normal = IN.normal;
i.viewDir = viewDir;
i.worldPosition = worldPosition;
@ -192,6 +221,14 @@ fixed4 frag_forward(v2f IN) : SV_Target
// call surface function
surf(i, o);
#ifdef DECAL_PREVIEW
o.Albedo = lerp(_Background.rgb,o.Albedo, o.Alpha);
o.Normal = lerp(float3(0,0,1), o.Normal, o.Alpha);
o.Gloss = lerp(_Background.a, o.Gloss, o.Alpha);
o.Emission = lerp(0, o.Emission, o.Alpha);
o.Alpha = _Opacity;
#endif //DECAL_PREVIEW
// compute lighting & shadowing factor
UNITY_LIGHT_ATTENUATION(atten, IN, worldPosition)
@ -203,7 +240,6 @@ fixed4 frag_forward(v2f IN) : SV_Target
WorldNormal.z = dot(_unity_tbn_2, o.Normal);
WorldNormal = normalize(WorldNormal);
o.Normal = WorldNormal;
//KSP lighting function
c += LightingBlinnPhongSmooth(o, lightDir, worldViewDir, atten);