Improved support for deferred rendering

This commit is contained in:
Andrew Cassidy 2024-06-26 01:04:00 -07:00
parent 89a1f0d872
commit a3a9ad9674
9 changed files with 158 additions and 43 deletions

View File

@ -29,7 +29,7 @@ Shader "ConformalDecals/Decal Back"
CGPROGRAM CGPROGRAM
#include "LightingKSP.cginc" #include "LightingKSP.cginc"
#pragma surface surf BlinnPhongSmooth vertex:vert #pragma surface surf BlinnPhong vertex:vert
#pragma target 3.0 #pragma target 3.0
sampler2D _MainTex; sampler2D _MainTex;

View File

@ -40,21 +40,17 @@ float4 _Decal_ST;
sampler2D _SpecMap; sampler2D _SpecMap;
float4 _SpecMap_ST; float4 _SpecMap_ST;
// specular color is declared in a unity CGINC for some reason?? // specular color is declared in a unity CGINC for some reason??
fixed _Shininess;
#endif //DECAL_SPECMAP #endif //DECAL_SPECMAP
fixed _Shininess;
#ifdef DECAL_EMISSIVE #ifdef DECAL_EMISSIVE
sampler2D _Emissive; sampler2D _Emissive;
float4 _Emissive_ST; float4 _Emissive_ST;
fixed4 _Emissive_Color; fixed4 _Emissive_Color;
#endif //DECAL_EMISSIVE #endif //DECAL_EMISSIVE
#ifdef UNITY_PASS_DEFERRED
sampler2D _CameraGBufferTexture0;
sampler2D _CameraGBufferTexture1;
sampler2D _CameraGBufferTexture2;
#endif
// KSP EFFECTS // KSP EFFECTS
// opacity and color // opacity and color
float _Opacity; float _Opacity;
@ -112,7 +108,7 @@ struct appdata_decal
struct v2f struct v2f
{ {
// UNITY_POSITION(pos); UNITY_POSITION(pos);
float3 normal : NORMAL; float3 normal : NORMAL;
float4 uv_decal : TEXCOORD0; float4 uv_decal : TEXCOORD0;
@ -134,7 +130,7 @@ struct v2f
#endif //UNITY_PASS_FORWARDADD #endif //UNITY_PASS_FORWARDADD
#ifdef UNITY_PASS_DEFERRED #ifdef UNITY_PASS_DEFERRED
float4 screenUV : TEXCOORD5; float3 screenUV : TEXCOORD5;
#endif #endif
}; };

View File

@ -8,12 +8,12 @@
// this must be defined in any shader using this cginc // this must be defined in any shader using this cginc
void surf (DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o); void surf (DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o);
v2f vert(appdata_decal v, out float4 outpos : SV_POSITION) v2f vert(appdata_decal v)
{ {
v2f o; v2f o;
UNITY_INITIALIZE_OUTPUT(v2f,o); UNITY_INITIALIZE_OUTPUT(v2f,o);
outpos = UnityObjectToClipPos(v.vertex); o.pos = UnityObjectToClipPos(v.vertex);
o.normal = v.normal; o.normal = v.normal;
#ifdef DECAL_PREVIEW #ifdef DECAL_PREVIEW
@ -64,17 +64,16 @@ v2f vert(appdata_decal v, out float4 outpos : SV_POSITION)
#endif // VERTEXLIGHT_ON #endif // VERTEXLIGHT_ON
#endif // UNITY_PASS_FORWARDBASE #endif // UNITY_PASS_FORWARDBASE
// pass shadow and, possibly, light cookie coordinates to pixel shader
UNITY_TRANSFER_LIGHTING(o, 0.0);
#ifdef UNITY_PASS_DEFERRED #ifdef UNITY_PASS_DEFERRED
o.screenUV = v.vertex; o.screenUV = o.pos.xyw;
// Correct flip when rendering with a flipped projection matrix. // Correct flip when rendering with a flipped projection matrix.
// (I've observed this differing between the Unity scene & game views) // (I've observed this differing between the Unity scene & game views)
o.screenUV.y *= _ProjectionParams.x; o.screenUV.y *= _ProjectionParams.x;
#endif #endif
// pass shadow and, possibly, light cookie coordinates to pixel shader
UNITY_TRANSFER_LIGHTING(o, 0.0);
return o; return o;
} }
@ -137,7 +136,7 @@ void frag_common(v2f IN, float3 worldPosition, float3 viewDir, out SurfaceOutput
o.Albedo = lerp(_Background.rgb, o.Albedo, o.Alpha) * _Color.rgb; o.Albedo = lerp(_Background.rgb, o.Albedo, o.Alpha) * _Color.rgb;
o.Normal = lerp(float3(0,0,1), o.Normal, o.Alpha); o.Normal = lerp(float3(0,0,1), o.Normal, o.Alpha);
o.Gloss = lerp(_Background.a, o.Gloss, o.Alpha); o.Specular = lerp(_Background.a, o.Specular, o.Alpha);
o.Emission = lerp(0, o.Emission, o.Alpha); o.Emission = lerp(0, o.Emission, o.Alpha);
o.Alpha = _Opacity; o.Alpha = _Opacity;
#endif //DECAL_PREVIEW #endif //DECAL_PREVIEW
@ -195,25 +194,22 @@ fixed4 frag_forward(v2f IN) : SV_Target
#ifdef UNITY_PASS_DEFERRED #ifdef UNITY_PASS_DEFERRED
void frag_deferred (v2f IN, void frag_deferred (v2f IN,
UNITY_VPOS_TYPE uv : VPOS,
out half4 outGBuffer0 : SV_Target0, out half4 outGBuffer0 : SV_Target0,
out half4 outGBuffer1 : SV_Target1, out half4 outGBuffer1 : SV_Target1,
out half4 outGBuffer2 : SV_Target2, #if defined(DECAL_BUMPMAP) || defined(DECAL_PREVIEW)
out half4 outEmission : SV_Target3 out half4 outGBuffer2 : SV_Target2,
#if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4) #endif
, out half4 outShadowMask : SV_Target4 out half4 outEmission : SV_Target3)
#endif
)
{ {
#if !(defined(DECAL_BUMPMAP) || defined(DECAL_PREVIEW))
half4 outGBuffer2 = 0; // define dummy normal buffer when we're not writing to it
#endif
// float2 uv = (IN.screenUV.xy / IN.screenUV.w) * 0.5f + 0.5f;
half4 inGBuffer0 = tex2D (_CameraGBufferTexture0, uv); // Diffuse RGB, Occlusion A
half4 inGBuffer1 = tex2D (_CameraGBufferTexture1, uv); // Specular RGB, Smoothness A
half4 inGBuffer2 = tex2D (_CameraGBufferTexture2, uv); // Normal RGB
// setup world-space TBN vectors // setup world-space TBN vectors
UNITY_EXTRACT_TBN(IN); UNITY_EXTRACT_TBN(IN);
SurfaceOutputStandardSpecular o; SurfaceOutputStandardSpecular o;
float3 worldPosition = float3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w); float3 worldPosition = float3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w);
float3 worldTangent = float3(IN.tSpace0.x, IN.tSpace1.x, IN.tSpace2.x); float3 worldTangent = float3(IN.tSpace0.x, IN.tSpace1.x, IN.tSpace2.x);
@ -222,6 +218,7 @@ void frag_deferred (v2f IN,
frag_common(IN, worldPosition, viewDir, o); frag_common(IN, worldPosition, viewDir, o);
#if defined(DECAL_BUMPMAP) || defined(DECAL_PREVIEW)
// compute world normal // compute world normal
float3 WorldNormal; float3 WorldNormal;
WorldNormal.x = dot(_unity_tbn_0, o.Normal); WorldNormal.x = dot(_unity_tbn_0, o.Normal);
@ -229,11 +226,30 @@ void frag_deferred (v2f IN,
WorldNormal.z = dot(_unity_tbn_2, o.Normal); WorldNormal.z = dot(_unity_tbn_2, o.Normal);
WorldNormal = normalize(WorldNormal); WorldNormal = normalize(WorldNormal);
o.Normal = WorldNormal; o.Normal = WorldNormal;
#endif
KSPLightingStandardSpecular_Deferred(o, outGBuffer0, outGBuffer1, outGBuffer2, outEmission); KSPLightingStandardSpecular_Deferred(o, outGBuffer0, outGBuffer1, outGBuffer2, outEmission);
outGBuffer0 = lerp(inGBuffer0, outGBuffer0, o.Alpha); outGBuffer0.a = o.Alpha;
outGBuffer1 = lerp(inGBuffer1, outGBuffer1, o.Alpha); outGBuffer1 *= o.Alpha;
outGBuffer2 = lerp(inGBuffer2, outGBuffer2, o.Alpha); outGBuffer2.a = o.Alpha;
outEmission.a = o.Alpha;
} }
void frag_deferred_prepass(v2f IN, out half4 outGBuffer1: SV_Target1) {
// setup world-space TBN vectors
UNITY_EXTRACT_TBN(IN);
SurfaceOutputStandardSpecular o;
float3 worldPosition = float3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w);
float3 worldTangent = float3(IN.tSpace0.x, IN.tSpace1.x, IN.tSpace2.x);
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPosition));
float3 viewDir = _unity_tbn_0 * worldViewDir.x + _unity_tbn_1 * worldViewDir.y + _unity_tbn_2 * worldViewDir.z;
frag_common(IN, worldPosition, viewDir, o);
outGBuffer1 = o.Alpha;
}
#endif #endif
#endif #endif

View File

@ -1,7 +1,7 @@
// Taken from https://github.com/LGhassen/Deferred // Taken from https://github.com/LGhassen/Deferred
//TODO: remove this debug settings //TODO: remove this debug settings
float blinnPhongShininessPower; float blinnPhongShininessPower = 0.215f;
// An exact conversion from blinn-phong to PBR is impossible, but the look can be approximated perceptually // An exact conversion from blinn-phong to PBR is impossible, but the look can be approximated perceptually
// and by observing how blinn-phong looks and feels at various settings, although it can never be perfect // and by observing how blinn-phong looks and feels at various settings, although it can never be perfect
@ -18,7 +18,7 @@ void GetStandardSpecularPropertiesFromLegacy(float legacyShininess, float specul
{ {
legacySpecularColor = saturate(legacySpecularColor); legacySpecularColor = saturate(legacySpecularColor);
smoothness = pow(legacyShininess, blinnPhongShininessPower) * specularMap; smoothness = pow(legacyShininess, 0.215) * specularMap;
smoothness *= sqrt(length(legacySpecularColor)); smoothness *= sqrt(length(legacySpecularColor));
specular = legacySpecularColor * (1 / UNITY_PI); specular = legacySpecularColor * (1 / UNITY_PI);

View File

@ -1,5 +1,6 @@
void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) { void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
float4 color = tex2D(_Decal, IN.uv_decal); float4 color = tex2D(_Decal, IN.uv_decal);
o.Specular = 0.4;
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb; o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
o.Alpha = _DecalOpacity; o.Alpha = _DecalOpacity;
o.Occlusion = 1; o.Occlusion = 1;
@ -12,15 +13,16 @@ void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
#endif #endif
#ifdef DECAL_BUMPMAP #ifdef DECAL_BUMPMAP
o.Normal = tex2D(_BumpMap, IN.uv_bumpmap); o.Normal = UnpackNormalDXT5nm(tex2D(_BumpMap, IN.uv_bumpmap));
#endif #endif
#ifdef DECAL_SPECMAP #ifdef DECAL_SPECMAP
float4 specular = tex2D(_SpecMap, IN.uv_specmap); float4 specular = tex2D(_SpecMap, IN.uv_specmap);
o.Smoothness = _Shininess;
o.Specular = specular o.Specular = specular
#endif #endif
o.Smoothness = _Shininess;
half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal)); half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
o.Emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; o.Emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a;

View File

@ -105,18 +105,52 @@
ENDCG ENDCG
} }
Pass Pass
{ {
Name "DEFERRED" Name "DEFERRED_PREPASS"
Tags { "LightMode" = "Deferred" } Tags { "LightMode" = "Deferred" }
ZWrite Off ZWrite [_ZWrite]
ZTest LEqual ZTest LEqual
Blend SrcAlpha One
Offset -1, -1 Offset -1, -1
Blend 1 Zero OneMinusSrcColor, Zero OneMinusSrcAlpha
CGPROGRAM CGPROGRAM
#pragma vertex vert #pragma vertex vert
#pragma fragment frag_deferred #pragma fragment frag_deferred_prepass
#pragma target 3.0
#pragma multi_compile_deferred nolightmap nodirlightmap nodynlightmap
#pragma skip_variants SHADOWS_DEPTH SHADOWS_CUBE SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING POINT_COOKIE
#pragma multi_compile_local __ DECAL_PREVIEW
// #pragma multi_compile_local __ DECAL_BASE_NORMAL DECAL_BUMPMAP
#pragma multi_compile_local __ DECAL_SPECMAP
// #pragma multi_compile_local __ DECAL_EMISSIVE
#pragma multi_compile_local __ DECAL_SDF_ALPHA
#include "UnityCG.cginc"
#include "DecalsCommon.cginc"
#include "DecalsSurface.cginc"
#include "SDF.cginc"
#include "StandardDecal.cginc"
ENDCG
}
Pass
{
Name "DEFERRED"
Tags { "LightMode" = "Deferred" }
ZWrite [_ZWrite]
ZTest LEqual
Offset -1, -1
Blend 0 SrcAlpha OneMinusSrcAlpha, Zero One
Blend 1 One One
Blend 2 SrcAlpha OneMinusSrcAlpha, Zero One
Blend 3 SrcAlpha OneMinusSrcAlpha, Zero One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_deferred
#pragma target 3.0 #pragma target 3.0
#pragma multi_compile_deferred nolightmap nodirlightmap nodynlightmap #pragma multi_compile_deferred nolightmap nodirlightmap nodynlightmap

View File

@ -6,6 +6,7 @@ float _OutlineWidth;
void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) { void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
float4 color = _DecalColor; float4 color = _DecalColor;
float dist = _Cutoff - tex2D(_Decal, IN.uv_decal).r; // text distance float dist = _Cutoff - tex2D(_Decal, IN.uv_decal).r; // text distance
o.Specular = 0.4;
o.Occlusion = 1; o.Occlusion = 1;
#ifdef DECAL_OUTLINE #ifdef DECAL_OUTLINE
@ -41,10 +42,11 @@ void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
#ifdef DECAL_SPECMAP #ifdef DECAL_SPECMAP
float4 specular = tex2D(_SpecMap, IN.uv_specmap); float4 specular = tex2D(_SpecMap, IN.uv_specmap);
o.Smoothness = _Shininess;
o.Specular = specular; o.Specular = specular;
#endif #endif
o.Smoothness = _Shininess;
half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal)); half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
o.Emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a; o.Emission = (_RimColor.rgb * pow(rim, _RimFalloff)) * _RimColor.a;
} }

View File

@ -105,5 +105,70 @@
ENDCG ENDCG
} }
Pass
{
Name "DEFERRED_PREPASS"
Tags { "LightMode" = "Deferred" }
ZWrite Off
ZTest LEqual
Offset -1, -1
Blend 1 Zero OneMinusSrcColor, Zero OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_deferred_prepass
#pragma target 3.0
#pragma multi_compile_deferred nolightmap nodirlightmap nodynlightmap
#pragma skip_variants SHADOWS_DEPTH SHADOWS_CUBE SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING POINT_COOKIE
#pragma multi_compile_local __ DECAL_PREVIEW
// #pragma multi_compile_local __ DECAL_BASE_NORMAL DECAL_BUMPMAP
#pragma multi_compile_local __ DECAL_SPECMAP
// #pragma multi_compile_local __ DECAL_EMISSIVE
#pragma multi_compile_local __ DECAL_SDF_ALPHA
#include "UnityCG.cginc"
#include "DecalsCommon.cginc"
#include "DecalsSurface.cginc"
#include "SDF.cginc"
#include "TextDecal.cginc"
ENDCG
}
Pass
{
Name "DEFERRED"
Tags { "LightMode" = "Deferred" }
ZWrite Off
ZTest LEqual
Offset -1, -1
Blend 0 SrcAlpha OneMinusSrcAlpha, Zero One
Blend 1 One One
Blend 2 SrcAlpha OneMinusSrcAlpha, Zero One
Blend 3 SrcAlpha OneMinusSrcAlpha, Zero One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_deferred
#pragma target 3.0
#pragma multi_compile_deferred nolightmap nodirlightmap nodynlightmap
#pragma skip_variants SHADOWS_DEPTH SHADOWS_CUBE SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING POINT_COOKIE
#pragma multi_compile_local __ DECAL_PREVIEW
#pragma multi_compile_local __ DECAL_BASE_NORMAL DECAL_BUMPMAP
#pragma multi_compile_local __ DECAL_SPECMAP
#pragma multi_compile_local __ DECAL_EMISSIVE
#pragma multi_compile_local __ DECAL_SDF_ALPHA
#include "UnityCG.cginc"
#include "DecalsCommon.cginc"
#include "DecalsSurface.cginc"
#include "SDF.cginc"
#include "TextDecal.cginc"
ENDCG
}
} }
} }