Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Feature/port seteron magic #1396

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Assets/Art/Shaders.meta
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shaders are not art assets by our definition. Move this folder to Content/worldObjects/World/VFX/.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That classification doesn't make much sense to me. Content/Shaders makes more sense to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shaders effect WorldObject, a type of VFX in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not always true, shaders can be used for UI interactions too

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

218 changes: 218 additions & 0 deletions Assets/Art/Shaders/DeferredShadingHalfToon.shader
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "Custom/DeferredShadingHalfToon" {
Properties {
_LightTexture0 ("", any) = "" {}
_LightTextureB0 ("", 2D) = "" {}
_ShadowMapTexture ("", any) = "" {}
_SrcBlend ("", Float) = 1
_DstBlend ("", Float) = 1
}
SubShader {

// Pass 1: Lighting pass
// LDR case - Lighting encoded into a subtractive ARGB8 buffer
// HDR case - Lighting additively blended into floating point buffer
Pass {
ZWrite Off
Blend [_SrcBlend] [_DstBlend]

CGPROGRAM
#pragma target 3.0
#pragma vertex vert_deferred
#pragma fragment frag
#pragma multi_compile_lightpass
#pragma multi_compile ___ UNITY_HDR_ON

#pragma exclude_renderers nomrt

#include "UnityCG.cginc"
#include "UnityDeferredLibrary.cginc"
#include "UnityPBSLighting.cginc"
#include "UnityStandardUtils.cginc"
#include "UnityGBuffer.cginc"
#include "UnityStandardBRDF.cginc"

sampler2D _CameraGBufferTexture0;
sampler2D _CameraGBufferTexture1;
sampler2D _CameraGBufferTexture2;
half4 WrapBRDF (half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
float3 normal, float3 viewDir,
UnityLight light, UnityIndirect gi)
{
float perceptualRoughness = SmoothnessToPerceptualRoughness (smoothness);
float3 halfDir = Unity_SafeNormalize (float3(light.dir) + viewDir);

// NdotV should not be negative for visible pixels, but it can happen due to perspective projection and normal mapping
// In this case normal should be modified to become valid (i.e facing camera) and not cause weird artifacts.
// but this operation adds few ALU and users may not want it. Alternative is to simply take the abs of NdotV (less correct but works too).
// Following define allow to control this. Set it to 0 if ALU is critical on your platform.
// This correction is interesting for GGX with SmithJoint visibility function because artifacts are more visible in this case due to highlight edge of rough surface
// Edit: Disable this code by default for now as it is not compatible with two sided lighting used in SpeedTree.
#define UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV 0

#if UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV
// The amount we shift the normal toward the view vector is defined by the dot product.
half shiftAmount = dot(normal, viewDir);
normal = shiftAmount < 0.0f ? normal + viewDir * (-shiftAmount + 1e-5f) : normal;
// A re-normalization should be applied here but as the shift is small we don't do it to save ALU.
//normal = normalize(normal);

float nv = saturate(dot(normal, viewDir)); // TODO: this saturate should no be necessary here
#else
half nv = abs(dot(normal, viewDir)); // This abs allow to limit artifact
#endif

float nl = saturate(dot(normal, light.dir));
float nh = saturate(dot(normal, halfDir));

half lv = saturate(dot(light.dir, viewDir));
half lh = saturate(dot(light.dir, halfDir));

// Diffuse term
half diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;
diffuseTerm = smoothstep(0, 0.75, diffuseTerm) * 0.7 + 0.3;

// Specular term
// HACK: theoretically we should divide diffuseTerm by Pi and not multiply specularTerm!
// BUT 1) that will make shader look significantly darker than Legacy ones
// and 2) on engine side "Non-important" lights have to be divided by Pi too in cases when they are injected into ambient SH
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
#if UNITY_BRDF_GGX
// GGX with roughtness to 0 would mean no specular at all, using max(roughness, 0.002) here to match HDrenderloop roughtness remapping.
roughness = max(roughness, 0.002);
float V = SmithJointGGXVisibilityTerm (nl, nv, roughness) * 0.5 + 0.5;
float D = GGXTerm (nh, roughness);
#else
// Legacy
half V = SmithBeckmannVisibilityTerm (nl, nv, roughness);
half D = NDFBlinnPhongNormalizedTerm (nh, PerceptualRoughnessToSpecPower(perceptualRoughness));
#endif

float specularTerm = V*D * UNITY_PI; // Torrance-Sparrow model, Fresnel is applied later

# ifdef UNITY_COLORSPACE_GAMMA
specularTerm = sqrt(max(1e-4h, specularTerm));
# endif

// specularTerm * nl can be NaN on Metal in some cases, use max() to make sure it's a sane value
specularTerm = max(0, specularTerm * nl);
#if defined(_SPECULARHIGHLIGHTS_OFF)
specularTerm = 0.0;
#endif

// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(roughness^2+1)
half surfaceReduction;
# ifdef UNITY_COLORSPACE_GAMMA
surfaceReduction = 1.0-0.28*roughness*perceptualRoughness; // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]
# else
surfaceReduction = 1.0 / (roughness*roughness + 1.0); // fade \in [0.5;1]
# endif

// To provide true Lambert lighting, we need to be able to kill specular completely.
specularTerm *= any(specColor) ? 1.0 : 0.0;

half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity));
half3 color = diffColor * (gi.diffuse + light.color * diffuseTerm)
+ specularTerm * light.color * FresnelTerm (specColor, lh)
+ surfaceReduction * gi.specular * FresnelLerp (specColor, grazingTerm, nv);

return half4(color, 1);
}
half4 CalculateLight (unity_v2f_deferred i)
{
float3 wpos;
float2 uv;
float atten, fadeDist;
UnityLight light;
UNITY_INITIALIZE_OUTPUT(UnityLight, light);
UnityDeferredCalculateLightParams (i, wpos, uv, light.dir, atten, fadeDist);

light.color = _LightColor.rgb * atten;

// unpack Gbuffer
half4 gbuffer0 = tex2D (_CameraGBufferTexture0, uv);
half4 gbuffer1 = tex2D (_CameraGBufferTexture1, uv);
half4 gbuffer2 = tex2D (_CameraGBufferTexture2, uv);
UnityStandardData data = UnityStandardDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2);

float3 eyeVec = normalize(wpos-_WorldSpaceCameraPos);
half oneMinusReflectivity = 1 - SpecularStrength(data.specularColor.rgb);

UnityIndirect ind;
UNITY_INITIALIZE_OUTPUT(UnityIndirect, ind);
ind.diffuse = 0;
ind.specular = 0;

half4 res = WrapBRDF (data.diffuseColor, data.specularColor, oneMinusReflectivity, data.smoothness, data.normalWorld, -eyeVec, light, ind);

return res;
}


#ifdef UNITY_HDR_ON
half4
#else
fixed4
#endif
frag (unity_v2f_deferred i) : SV_Target
{
half4 c = CalculateLight(i);
#ifdef UNITY_HDR_ON
return c;
#else
return exp2(-c);
#endif
}

ENDCG
}


// Pass 2: Final decode pass.
// Used only with HDR off, to decode the logarithmic buffer into the main RT
Pass {
ZTest Always Cull Off ZWrite Off
Stencil {
ref [_StencilNonBackground]
readmask [_StencilNonBackground]
// Normally just comp would be sufficient, but there's a bug and only front face stencil state is set (case 583207)
compback equal
compfront equal
}

CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma exclude_renderers nomrt

#include "UnityCG.cginc"

sampler2D _LightBuffer;
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};

v2f vert (float4 vertex : POSITION, float2 texcoord : TEXCOORD0)
{
v2f o;
o.vertex = UnityObjectToClipPos(vertex);
o.texcoord = texcoord.xy;
#ifdef UNITY_SINGLE_PASS_STEREO
o.texcoord = TransformStereoScreenSpaceTex(o.texcoord, 1.0f);
#endif
return o;
}

fixed4 frag (v2f i) : SV_Target
{
return -log2(tex2D(_LightBuffer, i.texcoord));
}
ENDCG
}

}
Fallback Off
}
9 changes: 9 additions & 0 deletions Assets/Art/Shaders/DeferredShadingHalfToon.shader.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading