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
#include "LightingKSP.cginc"
#pragma surface surf BlinnPhongSmooth vertex:vert
#pragma surface surf BlinnPhong vertex:vert
#pragma target 3.0
sampler2D _MainTex;

View File

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

View File

@ -8,12 +8,12 @@
// this must be defined in any shader using this cginc
void surf (DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o);
v2f vert(appdata_decal v, out float4 outpos : SV_POSITION)
v2f vert(appdata_decal v)
{
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f,o);
outpos = UnityObjectToClipPos(v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = v.normal;
#ifdef DECAL_PREVIEW
@ -64,17 +64,16 @@ v2f vert(appdata_decal v, out float4 outpos : SV_POSITION)
#endif // VERTEXLIGHT_ON
#endif // UNITY_PASS_FORWARDBASE
// pass shadow and, possibly, light cookie coordinates to pixel shader
UNITY_TRANSFER_LIGHTING(o, 0.0);
#ifdef UNITY_PASS_DEFERRED
o.screenUV = v.vertex;
o.screenUV = o.pos.xyw;
// Correct flip when rendering with a flipped projection matrix.
// (I've observed this differing between the Unity scene & game views)
o.screenUV.y *= _ProjectionParams.x;
#endif
// pass shadow and, possibly, light cookie coordinates to pixel shader
UNITY_TRANSFER_LIGHTING(o, 0.0);
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.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.Alpha = _Opacity;
#endif //DECAL_PREVIEW
@ -195,25 +194,22 @@ fixed4 frag_forward(v2f IN) : SV_Target
#ifdef UNITY_PASS_DEFERRED
void frag_deferred (v2f IN,
UNITY_VPOS_TYPE uv : VPOS,
out half4 outGBuffer0 : SV_Target0,
out half4 outGBuffer1 : SV_Target1,
#if defined(DECAL_BUMPMAP) || defined(DECAL_PREVIEW)
out half4 outGBuffer2 : SV_Target2,
out half4 outEmission : SV_Target3
#if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
, out half4 outShadowMask : SV_Target4
#endif
)
out half4 outEmission : SV_Target3)
{
#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
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);
@ -222,6 +218,7 @@ void frag_deferred (v2f IN,
frag_common(IN, worldPosition, viewDir, o);
#if defined(DECAL_BUMPMAP) || defined(DECAL_PREVIEW)
// compute world normal
float3 WorldNormal;
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 = normalize(WorldNormal);
o.Normal = WorldNormal;
#endif
KSPLightingStandardSpecular_Deferred(o, outGBuffer0, outGBuffer1, outGBuffer2, outEmission);
outGBuffer0 = lerp(inGBuffer0, outGBuffer0, o.Alpha);
outGBuffer1 = lerp(inGBuffer1, outGBuffer1, o.Alpha);
outGBuffer2 = lerp(inGBuffer2, outGBuffer2, o.Alpha);
outGBuffer0.a = o.Alpha;
outGBuffer1 *= 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

View File

@ -1,7 +1,7 @@
// Taken from https://github.com/LGhassen/Deferred
//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
// 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);
smoothness = pow(legacyShininess, blinnPhongShininessPower) * specularMap;
smoothness = pow(legacyShininess, 0.215) * specularMap;
smoothness *= sqrt(length(legacySpecularColor));
specular = legacySpecularColor * (1 / UNITY_PI);

View File

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

View File

@ -105,14 +105,48 @@
ENDCG
}
Pass
{
Name "DEFERRED_PREPASS"
Tags { "LightMode" = "Deferred" }
ZWrite [_ZWrite]
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 "StandardDecal.cginc"
ENDCG
}
Pass
{
Name "DEFERRED"
Tags { "LightMode" = "Deferred" }
ZWrite Off
ZWrite [_ZWrite]
ZTest LEqual
Blend SrcAlpha One
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

View File

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

View File

@ -105,5 +105,70 @@
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
}
}
}