Skip to content

Commit

Permalink
Cleaned up deferred support
Browse files Browse the repository at this point in the history
  • Loading branch information
drewcassidy committed Jul 18, 2024
1 parent ded36f4 commit c19a0c2
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 143 deletions.
12 changes: 0 additions & 12 deletions Assets/Shaders/DecalsCommon.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,9 @@ fixed _Shininess;
// KSP EFFECTS
// opacity and color
float _Opacity;
float4 _Color;
float _RimFalloff;
float4 _RimColor;

// fog
float4 _LocalCameraPos;
float4 _LocalCameraDir;
float4 _UnderwaterFogColor;
float _UnderwaterMinAlphaFogDistance;
float _UnderwaterMaxAlbedoFog;
float _UnderwaterMaxAlphaFog;
float _UnderwaterAlbedoDistanceScalar;
float _UnderwaterAlphaDistanceScalar;
float _UnderwaterFogFactor;

// SURFACE INPUT STRUCT
struct DecalSurfaceInput
{
Expand Down
167 changes: 80 additions & 87 deletions Assets/Shaders/DecalsSurface.cginc
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
#define DECALS_SURFACE_INCLUDED

#include "DecalsCommon.cginc"
#include "DecalsLighting.cginc"
#include "LightingKSPDeferred.cginc"

// declare surf function,
// this must be defined in any shader using this cginc
void surf (DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o);
void surf (DecalSurfaceInput IN, inout SurfaceOutput o);

v2f vert(appdata_decal v)
{
Expand Down Expand Up @@ -40,7 +40,7 @@ v2f vert(appdata_decal v)
fixed3 worldBinormal = cross(decalTangent, worldNormal);
fixed3 worldTangent = cross(worldNormal, worldBinormal);
#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);
o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPosition.z);
Expand Down Expand Up @@ -77,7 +77,17 @@ v2f vert(appdata_decal v)
return o;
}

void frag_common(v2f IN, float3 worldPosition, float3 viewDir, out SurfaceOutputStandardSpecular o) {

SurfaceOutput frag_common(v2f IN, out float3 viewDir, out UnityGI gi) {
SurfaceOutput o;

// setup world-space TBN vectors
UNITY_EXTRACT_TBN(IN);

float3 worldPos = float3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w);
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));
viewDir = _unity_tbn_0 * worldViewDir.x + _unity_tbn_1 * worldViewDir.y + _unity_tbn_2 * worldViewDir.z;

#ifdef DECAL_PREVIEW
fixed4 uv_projected = IN.uv_decal;
#else
Expand Down Expand Up @@ -118,19 +128,63 @@ void frag_common(v2f IN, float3 worldPosition, float3 viewDir, out SurfaceOutput

i.vertex_normal = IN.normal;
i.viewDir = viewDir;
i.worldPosition = worldPosition;
i.worldPosition = worldPos;

// initialize surface output
o.Albedo = 0.0;
o.Emission = 0.0;
o.Specular = 0.0;
o.Alpha = 0.0;
o.Smoothness = 0.0;
o.Gloss = 0.0;
o.Normal = fixed3(0,0,1);

// call surface function
surf(i, o);

// compute world normal
float3 worldN;
worldN.x = dot(_unity_tbn_0, o.Normal);
worldN.y = dot(_unity_tbn_1, o.Normal);
worldN.z = dot(_unity_tbn_2, o.Normal);
worldN = normalize(worldN);
o.Normal = worldN;

// compute lighting & shadowing factor
#if UNITY_PASS_DEFERRED
fixed atten = 0;
#else
UNITY_LIGHT_ATTENUATION(atten, IN, worldPos)
#endif

// setup GI
UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
gi.indirect.diffuse = 0;
gi.indirect.specular = 0;
gi.light.color = 0;
gi.light.dir = half3(0,1,0);

// setup light information in forward modes
#ifndef UNITY_PASS_DEFERRED
#ifndef USING_DIRECTIONAL_LIGHT
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
#else
fixed3 lightDir = _WorldSpaceLightPos0.xyz;
#endif
gi.light.color = _LightColor0.rgb;
gi.light.dir = lightDir;
#endif

// Call GI (lightmaps/SH/reflections) lighting function
UnityGIInput giInput;
UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);
giInput.light = gi.light;
giInput.worldPos = worldPos;
giInput.worldViewDir = worldViewDir;
giInput.atten = atten;
giInput.ambient = 0.0;

LightingBlinnPhongSmooth_GI(o, giInput, gi);

#ifdef DECAL_PREVIEW
if (any(IN.uv_decal > 1) || any(IN.uv_decal < 0)) o.Alpha = 0;

Expand All @@ -139,60 +193,22 @@ void frag_common(v2f IN, float3 worldPosition, float3 viewDir, out SurfaceOutput
o.Specular = lerp(_Background.a, o.Specular, o.Alpha);
o.Emission = lerp(0, o.Emission, o.Alpha);
o.Alpha = _Opacity;
#endif //DECAL_PREVIEW
#endif //DECAL_PREVIEW

return o;
}

fixed4 frag_forward(v2f IN) : SV_Target
{
// setup world-space TBN vectors
UNITY_EXTRACT_TBN(IN);
fixed3 viewDir = 0;
UnityGI gi;

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);

// compute lighting & shadowing factor
UNITY_LIGHT_ATTENUATION(atten, IN, worldPosition)

// setup world-space light and view direction vectors
#ifndef USING_DIRECTIONAL_LIGHT
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPosition));
#else
fixed3 lightDir = _WorldSpaceLightPos0.xyz;
#endif

// 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;
SurfaceOutput o = frag_common(IN, viewDir, gi);

//call modified KSP lighting function
float4 c = LightingBlinnPhongDecal(o, lightDir, worldViewDir, atten);

// Forward base emission and ambient/vertex lighting
#ifdef UNITY_PASS_FORWARDBASE
c.rgb += o.Emission;
c.rgb += o.Albedo * IN.vlight;
c.a = o.Alpha;
#endif //UNITY_PASS_FORWARDBASE

// Forward add multiply by alpha
#ifdef UNITY_PASS_FORWARDADD
c.rgb *= o.Alpha;
#endif

return c;
return LightingBlinnPhongSmooth(o, viewDir, gi);
}


#ifdef UNITY_PASS_DEFERRED
void frag_deferred (v2f IN,
out half4 outGBuffer0 : SV_Target0,
out half4 outGBuffer1 : SV_Target1,
Expand All @@ -205,34 +221,19 @@ void frag_deferred (v2f IN,
half4 outGBuffer2 = 0; // define dummy normal buffer when we're not writing to it
#endif


// 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);

#if defined(DECAL_BUMPMAP) || defined(DECAL_PREVIEW)
// 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;
#endif
float3 viewDir;
UnityGI gi;
SurfaceOutput o = frag_common(IN, viewDir, gi);

#ifdef DECAL_PREVIEW
o.Alpha = 1;
#endif

KSPLightingStandardSpecular_Deferred(o, outGBuffer0, outGBuffer1, outGBuffer2, outEmission);
outEmission = LightingBlinnPhongSmooth_Deferred(o, viewDir, gi, outGBuffer0, outGBuffer1, outGBuffer2);

#ifndef UNITY_HDR_ON
outEmission.rgb = exp2(-outEmission.rgb);
#endif

outGBuffer0.a = o.Alpha;
outGBuffer1 *= o.Alpha;
Expand All @@ -241,20 +242,12 @@ void frag_deferred (v2f IN,
}

void frag_deferred_prepass(v2f IN, out half4 outGBuffer1: SV_Target1) {
// setup world-space TBN vectors
UNITY_EXTRACT_TBN(IN);

float3 viewDir;
UnityGI gi;

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);
SurfaceOutput o = frag_common(IN, viewDir, gi);

outGBuffer1 = o.Alpha;
}

#endif
#endif
40 changes: 18 additions & 22 deletions Assets/Shaders/LightingKSPDeferred.cginc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef LIGHTING_KSP_INCLUDED
#define LIGHTING_KSP_INCLUDED

#include "UnityPBSLighting.cginc"


#define blinnPhongShininessPower 0.215

Expand All @@ -14,46 +16,40 @@
// 3) Finally I noticed that some parts still looked very shiny like the AV-R8 winglet while in stock they looked rough thanks a low
// specularColor but high shininess and specularMap, so I multiplied the smoothness by the sqrt of the specularColor and that caps
// the smoothness when specularColor is low
float4 GetStandardSpecularPropertiesFromLegacy(float legacyShininess, float specularMap)
void GetStandardSpecularPropertiesFromLegacy(float legacyShininess, float specularMap, out float3 specular, out float smoothness)
{
float3 legacySpecularColor = saturate(_SpecColor);

float smoothness = pow(legacyShininess, blinnPhongShininessPower) * specularMap;
smoothness = pow(legacyShininess, blinnPhongShininessPower) * specularMap;
smoothness *= sqrt(length(legacySpecularColor));

float3 specular = legacySpecularColor * UNITY_INV_PI;
return float4(specular, smoothness);
specular = legacySpecularColor * UNITY_INV_PI;
}

float4 _Color;

fixed4 LightingBlinnPhongSmooth(SurfaceOutput s, half3 viewDir, UnityGI gi)
{
fixed4 c;
c = UnityBlinnPhongLight(s, viewDir, gi.light);

#ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
c.rgb += s.Albedo * gi.indirect.diffuse;
#endif

fixed4 c = LightingBlinnPhong(s, viewDir, gi);
// #ifdef UNITY_PASS_FORWARDADD
// c.rgb *= c.a;
// #endif
return c;
}

half4 LightingBlinnPhongSmooth_Deferred(SurfaceOutput s, half3 viewDir, UnityGI gi,
out half4 outDiffuseOcclusion, out half4 outSpecSmoothness,
out half4 outNormal)
{
outDiffuseOcclusion = half4(s.Albedo, 1.0);
outSpecSmoothness = GetStandardSpecularPropertiesFromLegacy(s.Specular, s.Gloss);
outNormal = half4(s.Normal, 1.0);

half4 emission = half4(s.Emission, 1);

#ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
emission.rgb += s.Albedo * gi.indirect.diffuse;
#endif

return emission;
SurfaceOutputStandardSpecular ss;
ss.Albedo = s.Albedo;
ss.Normal = s.Normal;
ss.Emission = s.Emission;
ss.Occlusion = 1;
ss.Alpha = saturate(s.Alpha);
GetStandardSpecularPropertiesFromLegacy(s.Specular, s.Gloss, ss.Specular, ss.Smoothness);

return LightingStandardSpecular_Deferred(ss, viewDir, gi, outDiffuseOcclusion, outSpecSmoothness, outNormal);
}


Expand Down
9 changes: 5 additions & 4 deletions Assets/Shaders/StandardDecal.cginc
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
#include "SDF.cginc"

void surf(DecalSurfaceInput IN, inout SurfaceOutput o) {
float4 color = tex2D(_Decal, IN.uv_decal);
o.Specular = 0.4;
o.Gloss = _Shininess;
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
o.Alpha = _DecalOpacity;
o.Occlusion = 1;

#ifdef DECAL_BASE_NORMAL
float3 normal = IN.normal;
Expand All @@ -21,7 +23,6 @@ void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
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;
Expand All @@ -37,5 +38,5 @@ void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
#else
o.Alpha *= SDFAA(dist);
o.Alpha *= color.a;
#endif
#endif
}
Loading

0 comments on commit c19a0c2

Please sign in to comment.