mirror of
https://github.com/drewcassidy/KSP-Conformal-Decals.git
synced 2024-09-01 18:23:54 +00:00
I have a very shiny tortilla
This commit is contained in:
parent
6db2d6b82a
commit
89a1f0d872
@ -1,4 +1,6 @@
|
||||
#ifndef DECALS_COMMON_INCLUDED
|
||||
// Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members screenUV)
|
||||
#pragma exclude_renderers d3d11
|
||||
#define DECALS_COMMON_INCLUDED
|
||||
|
||||
#include "AutoLight.cginc"
|
||||
@ -47,6 +49,12 @@ float4 _Decal_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;
|
||||
@ -104,7 +112,7 @@ struct appdata_decal
|
||||
|
||||
struct v2f
|
||||
{
|
||||
UNITY_POSITION(pos);
|
||||
// UNITY_POSITION(pos);
|
||||
float3 normal : NORMAL;
|
||||
float4 uv_decal : TEXCOORD0;
|
||||
|
||||
@ -124,6 +132,10 @@ struct v2f
|
||||
#ifdef UNITY_PASS_FORWARDADD
|
||||
UNITY_LIGHTING_COORDS(5,6)
|
||||
#endif //UNITY_PASS_FORWARDADD
|
||||
|
||||
#ifdef UNITY_PASS_DEFERRED
|
||||
float4 screenUV : TEXCOORD5;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
#ifndef DECALS_LIGHTING_INCLUDED
|
||||
#define DECALS_LIGHTING_INCLUDED
|
||||
|
||||
#include "UnityPBSLighting.cginc"
|
||||
#include "LegacyToStandard.cginc"
|
||||
|
||||
// modifed version of the KSP BlinnPhong because it does some weird things
|
||||
inline fixed4 LightingBlinnPhongDecal(SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
|
||||
inline fixed4 LightingBlinnPhongDecal(SurfaceOutputStandardSpecular s, fixed3 lightDir, half3 viewDir, fixed atten)
|
||||
{
|
||||
s.Normal = normalize(s.Normal);
|
||||
half3 h = normalize(lightDir + viewDir);
|
||||
@ -10,7 +13,7 @@ inline fixed4 LightingBlinnPhongDecal(SurfaceOutput s, fixed3 lightDir, half3 vi
|
||||
fixed diff = max(0, dot(s.Normal, lightDir));
|
||||
|
||||
float nh = max(0, dot(s.Normal, h));
|
||||
float spec = pow(nh, s.Specular*128.0) * s.Gloss;
|
||||
float spec = pow(nh, s.Smoothness*128.0) * s.Specular; // specular and smoothness inverted from usual KSP lighting function
|
||||
|
||||
fixed4 c = 0;
|
||||
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten);
|
||||
@ -30,4 +33,39 @@ float4 UnderwaterFog(float3 worldPos, float3 color)
|
||||
return float4(lerp(color, _UnderwaterFogColor.rgb, albedoLerpValue), alphaFactor);
|
||||
}
|
||||
|
||||
|
||||
inline half4 KSPLightingStandardSpecular_Deferred (SurfaceOutputStandardSpecular s, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2, out half4 outEmission)
|
||||
{
|
||||
GetStandardSpecularPropertiesFromLegacy(s.Smoothness, s.Specular, _SpecColor, s.Smoothness, s.Specular);
|
||||
|
||||
// energy conservation
|
||||
half oneMinusReflectivity;
|
||||
s.Albedo = EnergyConservationBetweenDiffuseAndSpecular (s.Albedo, s.Specular, oneMinusReflectivity);
|
||||
|
||||
UnityStandardData data;
|
||||
data.diffuseColor = s.Albedo;
|
||||
data.occlusion = s.Occlusion;
|
||||
data.specularColor = s.Specular;
|
||||
data.smoothness = s.Smoothness;
|
||||
data.normalWorld = s.Normal;
|
||||
|
||||
// RT0: diffuse color (rgb), occlusion (a) - sRGB rendertarget
|
||||
outGBuffer0 = half4(data.diffuseColor, data.occlusion);
|
||||
|
||||
// RT1: spec color (rgb), smoothness (a) - sRGB rendertarget
|
||||
outGBuffer1 = half4(data.specularColor, data.smoothness);
|
||||
|
||||
// RT2: normal (rgb), --unused, very low precision-- (a)
|
||||
outGBuffer2 = half4(data.normalWorld * 0.5f + 0.5f, 1.0f);
|
||||
|
||||
outEmission = half4(s.Emission, s.Alpha);
|
||||
|
||||
#ifndef UNITY_HDR_ON
|
||||
outEmission.rgb = exp2(-outEmission.rgb);
|
||||
#endif
|
||||
|
||||
return outEmission;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -6,14 +6,14 @@
|
||||
|
||||
// declare surf function,
|
||||
// this must be defined in any shader using this cginc
|
||||
void surf (DecalSurfaceInput IN, inout SurfaceOutput o);
|
||||
void surf (DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o);
|
||||
|
||||
v2f vert_forward(appdata_decal v)
|
||||
v2f vert(appdata_decal v, out float4 outpos : SV_POSITION)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_INITIALIZE_OUTPUT(v2f,o);
|
||||
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
outpos = UnityObjectToClipPos(v.vertex);
|
||||
o.normal = v.normal;
|
||||
|
||||
#ifdef DECAL_PREVIEW
|
||||
@ -63,6 +63,14 @@ v2f vert_forward(appdata_decal v)
|
||||
unity_4LightAtten0, worldPosition, worldNormal );
|
||||
#endif // VERTEXLIGHT_ON
|
||||
#endif // UNITY_PASS_FORWARDBASE
|
||||
|
||||
#ifdef UNITY_PASS_DEFERRED
|
||||
o.screenUV = v.vertex;
|
||||
|
||||
// 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);
|
||||
@ -70,8 +78,7 @@ v2f vert_forward(appdata_decal v)
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag_forward(v2f IN) : SV_Target
|
||||
{
|
||||
void frag_common(v2f IN, float3 worldPosition, float3 viewDir, out SurfaceOutputStandardSpecular o) {
|
||||
#ifdef DECAL_PREVIEW
|
||||
fixed4 uv_projected = IN.uv_decal;
|
||||
#else
|
||||
@ -84,22 +91,6 @@ fixed4 frag_forward(v2f IN) : SV_Target
|
||||
|
||||
// declare data
|
||||
DecalSurfaceInput i;
|
||||
SurfaceOutput o;
|
||||
|
||||
// setup world-space TBN vectors
|
||||
UNITY_EXTRACT_TBN(IN);
|
||||
|
||||
float3 worldPosition = float3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w);
|
||||
float3 worldTangent = float3(IN.tSpace0.x, IN.tSpace1.x, IN.tSpace2.x);
|
||||
|
||||
// setup world-space light and view direction vectors
|
||||
#ifndef USING_DIRECTIONAL_LIGHT
|
||||
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPosition));
|
||||
#else
|
||||
fixed3 lightDir = _WorldSpaceLightPos0.xyz;
|
||||
#endif
|
||||
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPosition));
|
||||
float3 viewDir = _unity_tbn_0 * worldViewDir.x + _unity_tbn_1 * worldViewDir.y + _unity_tbn_2 * worldViewDir.z;
|
||||
|
||||
// initialize surface input
|
||||
UNITY_INITIALIZE_OUTPUT(DecalSurfaceInput, i)
|
||||
@ -135,7 +126,7 @@ fixed4 frag_forward(v2f IN) : SV_Target
|
||||
o.Emission = 0.0;
|
||||
o.Specular = 0.0;
|
||||
o.Alpha = 0.0;
|
||||
o.Gloss = 0.0;
|
||||
o.Smoothness = 0.0;
|
||||
o.Normal = fixed3(0,0,1);
|
||||
|
||||
// call surface function
|
||||
@ -150,9 +141,30 @@ fixed4 frag_forward(v2f IN) : SV_Target
|
||||
o.Emission = lerp(0, o.Emission, o.Alpha);
|
||||
o.Alpha = _Opacity;
|
||||
#endif //DECAL_PREVIEW
|
||||
}
|
||||
|
||||
fixed4 frag_forward(v2f IN) : SV_Target
|
||||
{
|
||||
// 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);
|
||||
|
||||
// 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;
|
||||
@ -180,4 +192,48 @@ fixed4 frag_forward(v2f IN) : SV_Target
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
#ifdef UNITY_PASS_DEFERRED
|
||||
void frag_deferred (v2f IN,
|
||||
UNITY_VPOS_TYPE uv : VPOS,
|
||||
out half4 outGBuffer0 : SV_Target0,
|
||||
out half4 outGBuffer1 : SV_Target1,
|
||||
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
|
||||
)
|
||||
{
|
||||
|
||||
// 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);
|
||||
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 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;
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
#endif
|
25
Assets/Shaders/LegacyToStandard.cginc
Normal file
25
Assets/Shaders/LegacyToStandard.cginc
Normal file
@ -0,0 +1,25 @@
|
||||
// Taken from https://github.com/LGhassen/Deferred
|
||||
|
||||
//TODO: remove this debug settings
|
||||
float blinnPhongShininessPower;
|
||||
|
||||
// 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
|
||||
// 1) The specularColor can be used as is in the PBR specular flow, just needs to be divided by PI so it sums up to 1 over the hemisphere
|
||||
// 2) Blinn-phong shininess doesn't stop feeling shiny unless at very low values, like below 0.04
|
||||
// while the PBR smoothness feels more linear -> map shininess to smoothness accordingly using a function
|
||||
// that increases very quickly at first then slows down, I went with something like x^(1/4) or x^(1/6) then made the power configurable
|
||||
// I tried various mappings from the literature but nothing really worked as well as this
|
||||
// 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
|
||||
void GetStandardSpecularPropertiesFromLegacy(float legacyShininess, float specularMap, float3 legacySpecularColor,
|
||||
out float smoothness, out float3 specular)
|
||||
{
|
||||
legacySpecularColor = saturate(legacySpecularColor);
|
||||
|
||||
smoothness = pow(legacyShininess, blinnPhongShininessPower) * specularMap;
|
||||
smoothness *= sqrt(length(legacySpecularColor));
|
||||
|
||||
specular = legacySpecularColor * (1 / UNITY_PI);
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
void surf(DecalSurfaceInput IN, inout SurfaceOutput o) {
|
||||
void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
|
||||
float4 color = tex2D(_Decal, IN.uv_decal);
|
||||
o.Albedo = UnderwaterFog(IN.worldPosition, color).rgb;
|
||||
o.Alpha = _DecalOpacity;
|
||||
o.Occlusion = 1;
|
||||
|
||||
#ifdef DECAL_BASE_NORMAL
|
||||
float3 normal = IN.normal;
|
||||
@ -16,8 +17,8 @@ void surf(DecalSurfaceInput IN, inout SurfaceOutput o) {
|
||||
|
||||
#ifdef DECAL_SPECMAP
|
||||
float4 specular = tex2D(_SpecMap, IN.uv_specmap);
|
||||
o.Gloss = specular.r;
|
||||
o.Specular = _Shininess;
|
||||
o.Smoothness = _Shininess;
|
||||
o.Specular = specular
|
||||
#endif
|
||||
|
||||
half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
|
||||
|
@ -55,7 +55,7 @@
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_forward
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag_forward
|
||||
|
||||
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap
|
||||
@ -85,7 +85,7 @@
|
||||
Offset -1, -1
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_forward
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag_forward
|
||||
|
||||
#pragma multi_compile_fwdadd nolightmap nodirlightmap nodynlightmap
|
||||
@ -102,6 +102,37 @@
|
||||
#include "SDF.cginc"
|
||||
#include "StandardDecal.cginc"
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "DEFERRED"
|
||||
Tags { "LightMode" = "Deferred" }
|
||||
ZWrite Off
|
||||
ZTest LEqual
|
||||
Blend SrcAlpha One
|
||||
Offset -1, -1
|
||||
|
||||
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 "StandardDecal.cginc"
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,10 @@ float4 _DecalColor;
|
||||
float4 _OutlineColor;
|
||||
float _OutlineWidth;
|
||||
|
||||
void surf(DecalSurfaceInput IN, inout SurfaceOutput o) {
|
||||
void surf(DecalSurfaceInput IN, inout SurfaceOutputStandardSpecular o) {
|
||||
float4 color = _DecalColor;
|
||||
float dist = _Cutoff - tex2D(_Decal, IN.uv_decal).r; // text distance
|
||||
o.Occlusion = 1;
|
||||
|
||||
#ifdef DECAL_OUTLINE
|
||||
// Outline
|
||||
@ -40,8 +41,8 @@ void surf(DecalSurfaceInput IN, inout SurfaceOutput o) {
|
||||
|
||||
#ifdef DECAL_SPECMAP
|
||||
float4 specular = tex2D(_SpecMap, IN.uv_specmap);
|
||||
o.Gloss = specular.r;
|
||||
o.Specular = _Shininess;
|
||||
o.Smoothness = _Shininess;
|
||||
o.Specular = specular;
|
||||
#endif
|
||||
|
||||
half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
|
||||
|
@ -56,7 +56,7 @@
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_forward
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag_forward
|
||||
|
||||
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap
|
||||
@ -86,7 +86,7 @@
|
||||
Offset -1, -1
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_forward
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag_forward
|
||||
|
||||
#pragma multi_compile_fwdadd nolightmap nodirlightmap nodynlightmap
|
||||
|
Loading…
Reference in New Issue
Block a user