- Mirrors no longer have culling enabled, since it caused too much flickering.
- Added a fake sub-surface scattering shader that might be used later. - Apparently the arcade games were altered somehow? Don't remember that.
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: SSS Demo
|
||||
m_Shader: {fileID: 4800000, guid: dd867f0212ded544396217ac461f949c, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _METALLICGLOSSMAP
|
||||
m_InvalidKeywords:
|
||||
- _
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BRDFTex:
|
||||
m_Texture: {fileID: 2800000, guid: 438762e23bc56bf4188ce947bf60e0e3, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailBumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OverlayMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ThicknessMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _texcoord:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _texcoord2:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _CullMode: 2
|
||||
- _Cutoff: 0.5
|
||||
- _Cutout: 0.5
|
||||
- _DetailBumpMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _OcclusionUVSource: 0
|
||||
- _Parallax: 0.02
|
||||
- _SSSAmbient: 0
|
||||
- _SSSDist: 1
|
||||
- _SSSIntensity: 1
|
||||
- _SSSPow: 1
|
||||
- _SSSShadow: 1
|
||||
- _ScatteringByAlbedo: 1
|
||||
- _SecondUVSource: 0
|
||||
- _SmoothnessFromAlbedo: 0
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _ThicknessMapInvert: 1
|
||||
- _ThicknessMapPower: 1
|
||||
- _ThicknessUVSource: 0
|
||||
- _UVSec: 0
|
||||
- _UseAlphaToMask: 0
|
||||
- _UseCutout: 0
|
||||
- _UseSkinScattering: 1
|
||||
- _WrappingFactor: 0.01
|
||||
- _WrappingPowerFactor: 1
|
||||
- _ZWrite: 1
|
||||
- __dirty: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 0.8283805, b: 0.7216981, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _OverlayColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _SSSCol: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 511ba8c25b0549c4ba9a8dbd34424156
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,108 @@
|
||||
// Put together with Amplify's help.
|
||||
Shader "Silent/Subsurface Scattering (Specular)"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Standard)]
|
||||
_Color ("Color", Color) = (1,1,1,1)
|
||||
_MainTex("Albedo", 2D) = "white" {}
|
||||
[NoScaleOffset][Normal]_BumpMap("Normal Map", 2D) = "bump" {}
|
||||
_BumpScale ("Normal Scale", Float) = 1
|
||||
[NoScaleOffset]_MetallicGlossMap("Specular", 2D) = "black" {}
|
||||
_SpecularColor("Specular Tint", Color) = (1,1,1)
|
||||
_GlossMapScale("Smoothness", Range(0, 1)) = 1.0
|
||||
[ToggleUI]_SmoothnessFromAlbedo("Smoothness stored in Albedo alpha", Float) = 0.0
|
||||
[NoScaleOffset]_OcclusionMap("Occlusion", 2D) = "white" {}
|
||||
_OcclusionStrength("Occlusion Strength", Range(0, 1)) = 1.0
|
||||
[Enum(UV1, 0, UV2, 1)] _OcclusionUVSource("Occlusion UV Source", Float) = 0
|
||||
_EmissionMap("Emission", 2D) = "black" {}
|
||||
[HDR]_EmissionColor ("Emission Color", Color) = (1,1,1,1)
|
||||
|
||||
[Header(Detail)]
|
||||
[NoScaleOffset]_OverlayMap("Overlay", 2D) = "black" {}
|
||||
_OverlayColor ("Overlay Color", Color) = (1,1,1,1)
|
||||
[NoScaleOffset]_DetailMask("Detail Mask", 2D) = "white" {}
|
||||
[Normal]_DetailBumpMap("Detail Normal Map", 2D) = "bump" {}
|
||||
_DetailMetallicGlossMap("Detail Metallic", 2D) = "white" {}
|
||||
_DetailBumpMapScale ("Detail Scale", Float) = 1
|
||||
[Enum(UV1, 0, UV2, 1)] _SecondUVSource("Secondary UV Source", Float) = 0
|
||||
|
||||
[Header(Transmission)]
|
||||
[NoScaleOffset]_ThicknessMap("Thickness Map", 2D) = "black" {}
|
||||
[ToggleUI]_ThicknessMapInvert("Invert Thickness", Float) = 0.0
|
||||
_ThicknessMapPower ("Thickness Map Power", Range(0.01, 10)) = 1
|
||||
[Enum(UV1, 0, UV2, 1)] _ThicknessUVSource("Thickness UV Source", Float) = 0
|
||||
[ToggleUI]_ScatteringByAlbedo("Tint Scattering with Albedo", Float) = 0.0
|
||||
_SSSCol ("Scattering Color", Color) = (1,1,1,1)
|
||||
_SSSIntensity ("Scattering Intensity", Range(0, 10)) = 1
|
||||
_SSSPow ("Scattering Power", Range(0.01, 10)) = 1
|
||||
_SSSDist ("Scattering Distance", Range(0, 10)) = 1
|
||||
_SSSAmbient ("Scattering Ambient Intensity", Range(0, 0.5)) = 0
|
||||
_SSSShadow ("Scattering Shadow Power", Range(0, 1)) = 1
|
||||
|
||||
[Header(Skin)]
|
||||
[Toggle(_METALLICGLOSSMAP)]_UseSkinScattering("Use Skin Scattering", Float) = 0.0
|
||||
[NoScaleOffset]_BRDFTex("Skin BRDF LUT", 2D) = "white" {}
|
||||
|
||||
[Header(Wrapped Diffuse)]
|
||||
_WrappingFactor("Wrapping Factor", Range(0.001, 1)) = 0.01
|
||||
[Gamma]_WrappingPowerFactor("Wrapping Power Factor", Float) = 1
|
||||
|
||||
[Header(System)]
|
||||
[Enum(UnityEngine.Rendering.CullMode)] _CullMode("Cull Mode", Float) = 2
|
||||
[Toggle(_ALPHATEST_ON)] _UseCutout("Alpha Test Cutout", Float) = 0
|
||||
[Toggle(_ALPHABLEND_ON)] _UseAlphaToMask("Alpha To Coverage Transparency", Float) = 0
|
||||
_Cutout("Cutout", Range(0, 1)) = 0.5
|
||||
[ToggleOff(_SPECULARHIGHLIGHTS_OFF)]_SpecularHighlights ("Specular Highlights", Float) = 1.0
|
||||
[ToggleOff(_GLOSSYREFLECTIONS_OFF)]_GlossyReflections ("Glossy Reflections", Float) = 1.0
|
||||
[HideInInspector] _texcoord( "", 2D ) = "white" {}
|
||||
[HideInInspector] _texcoord2( "", 2D ) = "white" {}
|
||||
[HideInInspector] __dirty( "", Int ) = 1
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags{ "RenderType" = "TransparentCutout" "Queue" = "AlphaTest+0" }
|
||||
Cull[_CullMode]
|
||||
AlphaToMask [_UseAlphaToMask]
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#pragma shader_feature _SPECULARHIGHLIGHTS_OFF
|
||||
#pragma shader_feature _GLOSSYREFLECTIONS_OFF
|
||||
#pragma shader_feature _ALPHATEST_ON
|
||||
|
||||
// Reuse Standard keywords for features to avoid reaching limit
|
||||
// This one is for scattering.
|
||||
#pragma shader_feature _METALLICGLOSSMAP
|
||||
|
||||
#define SSS_SPECULAR
|
||||
#include "SSS_Standard.cginc"
|
||||
|
||||
ENDCG
|
||||
CGPROGRAM
|
||||
#pragma surface surf StandardCustomLighting keepalpha fullforwardshadows
|
||||
|
||||
ENDCG
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags{ "LightMode" = "ShadowCaster" }
|
||||
ZWrite On
|
||||
AlphaToMask Off
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
#pragma multi_compile_shadowcaster
|
||||
#pragma multi_compile UNITY_PASS_SHADOWCASTER
|
||||
#pragma shader_feature _ _ALPHATEST_ON
|
||||
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
|
||||
|
||||
#include "SSS_Shadow.cginc"
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
Fallback "Standard"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3286a5d3dc0c3dd4e8dfc9dcd833291c
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures:
|
||||
- _MainTex: {instanceID: 0}
|
||||
- _BumpMap: {instanceID: 0}
|
||||
- _MetallicGlossMap: {instanceID: 0}
|
||||
- _OcclusionMap: {instanceID: 0}
|
||||
- _OverlayMap: {instanceID: 0}
|
||||
- _DetailMask: {instanceID: 0}
|
||||
- _DetailBumpMap: {instanceID: 0}
|
||||
- _DetailMetallicGlossMap: {instanceID: 0}
|
||||
- _ThicknessMap: {instanceID: 0}
|
||||
- _BRDFTex: {fileID: 2800000, guid: 438762e23bc56bf4188ce947bf60e0e3, type: 3}
|
||||
- _texcoord: {instanceID: 0}
|
||||
- _texcoord2: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,107 @@
|
||||
// Put together with Amplify's help.
|
||||
Shader "Silent/Subsurface Scattering"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[Header(Standard)]
|
||||
_Color ("Color", Color) = (1,1,1,1)
|
||||
_MainTex("Albedo", 2D) = "white" {}
|
||||
[NoScaleOffset][Normal]_BumpMap("Normal Map", 2D) = "bump" {}
|
||||
_BumpScale ("Normal Scale", Float) = 1
|
||||
[NoScaleOffset]_MetallicGlossMap("Metallic", 2D) = "black" {}
|
||||
_GlossMapScale("Smoothness", Range(0, 1)) = 1.0
|
||||
[ToggleUI]_SmoothnessFromAlbedo("Smoothness stored in Albedo alpha", Float) = 0.0
|
||||
[NoScaleOffset]_OcclusionMap("Occlusion", 2D) = "white" {}
|
||||
_OcclusionStrength("Occlusion Strength", Range(0, 1)) = 1.0
|
||||
[Enum(UV1, 0, UV2, 1)] _OcclusionUVSource("Occlusion UV Source", Float) = 0
|
||||
_EmissionMap("Emission", 2D) = "black" {}
|
||||
[HDR]_EmissionColor ("Emission Color", Color) = (1,1,1,1)
|
||||
|
||||
[Header(Detail)]
|
||||
[NoScaleOffset]_OverlayMap("Overlay", 2D) = "black" {}
|
||||
_OverlayColor ("Overlay Color", Color) = (1,1,1,1)
|
||||
[NoScaleOffset]_DetailMask("Detail Mask", 2D) = "white" {}
|
||||
[Normal]_DetailBumpMap("Detail Normal Map", 2D) = "bump" {}
|
||||
_DetailMetallicGlossMap("Detail Metallic", 2D) = "white" {}
|
||||
_DetailBumpMapScale ("Detail Scale", Float) = 1
|
||||
[Enum(UV1, 0, UV2, 1)] _SecondUVSource("Secondary UV Source", Float) = 0
|
||||
|
||||
[Header(Transmission)]
|
||||
[NoScaleOffset]_ThicknessMap("Thickness Map", 2D) = "black" {}
|
||||
[ToggleUI]_ThicknessMapInvert("Invert Thickness", Float) = 0.0
|
||||
_ThicknessMapPower ("Thickness Map Power", Range(0.01, 10)) = 1
|
||||
[Enum(UV1, 0, UV2, 1)] _ThicknessUVSource("Thickness UV Source", Float) = 0
|
||||
[ToggleUI]_ScatteringByAlbedo("Tint Scattering with Albedo", Float) = 0.0
|
||||
_SSSCol ("Scattering Color", Color) = (1,1,1,1)
|
||||
_SSSIntensity ("Scattering Intensity", Range(0, 10)) = 1
|
||||
_SSSPow ("Scattering Power", Range(0.01, 10)) = 1
|
||||
_SSSDist ("Scattering Distance", Range(0, 10)) = 1
|
||||
_SSSAmbient ("Scattering Ambient Intensity", Range(0, 0.5)) = 0
|
||||
_SSSShadow ("Scattering Shadow Power", Range(0, 1)) = 1
|
||||
|
||||
[Header(Skin)]
|
||||
[Toggle(_METALLICGLOSSMAP)]_UseSkinScattering("Use Skin Scattering", Float) = 0.0
|
||||
[NoScaleOffset]_BRDFTex("Skin BRDF LUT", 2D) = "white" {}
|
||||
|
||||
[Header(Wrapped Diffuse)]
|
||||
_WrappingFactor("Wrapping Factor", Range(0.001, 1)) = 0.01
|
||||
[Gamma]_WrappingPowerFactor("Wrapping Power Factor", Float) = 1
|
||||
|
||||
[Header(System)]
|
||||
[Enum(UnityEngine.Rendering.CullMode)] _CullMode("Cull Mode", Float) = 2
|
||||
[Toggle(_ALPHATEST_ON)] _UseCutout("Alpha Test Cutout", Float) = 0
|
||||
[Toggle(_ALPHABLEND_ON)] _UseAlphaToMask("Alpha To Coverage Transparency", Float) = 0
|
||||
_Cutout("Cutout", Range(0, 1)) = 0.5
|
||||
[ToggleOff(_SPECULARHIGHLIGHTS_OFF)]_SpecularHighlights ("Specular Highlights", Float) = 1.0
|
||||
[ToggleOff(_GLOSSYREFLECTIONS_OFF)]_GlossyReflections ("Glossy Reflections", Float) = 1.0
|
||||
[HideInInspector] _texcoord( "", 2D ) = "white" {}
|
||||
[HideInInspector] _texcoord2( "", 2D ) = "white" {}
|
||||
[HideInInspector] __dirty( "", Int ) = 1
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags{ "RenderType" = "TransparentCutout" "Queue" = "AlphaTest+0" }
|
||||
Cull[_CullMode]
|
||||
AlphaToMask [_UseAlphaToMask]
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#pragma shader_feature _SPECULARHIGHLIGHTS_OFF
|
||||
#pragma shader_feature _GLOSSYREFLECTIONS_OFF
|
||||
#pragma shader_feature _ALPHATEST_ON
|
||||
|
||||
// Reuse Standard keywords for features to avoid reaching limit
|
||||
// This one is for scattering.
|
||||
#pragma shader_feature _METALLICGLOSSMAP
|
||||
|
||||
#define SSS_METALLIC
|
||||
#include "SSS_Standard.cginc"
|
||||
|
||||
ENDCG
|
||||
CGPROGRAM
|
||||
#pragma surface surf StandardCustomLighting keepalpha fullforwardshadows
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
Pass
|
||||
{
|
||||
Name "ShadowCaster"
|
||||
Tags{ "LightMode" = "ShadowCaster" }
|
||||
ZWrite On
|
||||
AlphaToMask Off
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile_shadowcaster
|
||||
#pragma multi_compile UNITY_PASS_SHADOWCASTER
|
||||
#pragma shader_feature _ _ALPHATEST_ON
|
||||
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
|
||||
|
||||
#include "SSS_Shadow.cginc"
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
Fallback "Standard"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd867f0212ded544396217ac461f949c
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures:
|
||||
- _MainTex: {instanceID: 0}
|
||||
- _BumpMap: {instanceID: 0}
|
||||
- _MetallicGlossMap: {instanceID: 0}
|
||||
- _OcclusionMap: {instanceID: 0}
|
||||
- _OverlayMap: {instanceID: 0}
|
||||
- _DetailMask: {instanceID: 0}
|
||||
- _DetailBumpMap: {instanceID: 0}
|
||||
- _DetailMetallicGlossMap: {instanceID: 0}
|
||||
- _ThicknessMap: {instanceID: 0}
|
||||
- _BRDFTex: {fileID: 2800000, guid: 438762e23bc56bf4188ce947bf60e0e3, type: 3}
|
||||
- _texcoord: {instanceID: 0}
|
||||
- _texcoord2: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,330 @@
|
||||
#ifndef SSS_CORE_INCLUDED
|
||||
#define SSS_CORE_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
// BRDF functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// See UnityStandardBRDF for more info
|
||||
|
||||
UNITY_DECLARE_TEX2D(_BRDFTex);
|
||||
|
||||
half4 UNITY_BRDF_PBS_SSSS (half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness, half thickness,
|
||||
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
|
||||
half3 diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;
|
||||
|
||||
#if defined(_METALLICGLOSSMAP) // Scattering
|
||||
// Skin Lighting
|
||||
float2 brdfUV;
|
||||
// Half-Lambert lighting value based on blurred normals.
|
||||
brdfUV.x = nl * 0.5 + 0.5;
|
||||
// Curvature amount. Multiplied by light's luminosity so brighter light = more scattering.
|
||||
// Pleae note: gi.light.color already contains light attenuation
|
||||
brdfUV.y = thickness * dot(light.color, fixed3(0.22, 0.707, 0.071));
|
||||
half3 brdf = UNITY_SAMPLE_TEX2D ( _BRDFTex, brdfUV ).rgb;
|
||||
#else
|
||||
float wrappedDiffuse = pow(saturate((diffuseTerm + _WrappingFactor) /
|
||||
(1.0f + _WrappingFactor)), _WrappingPowerFactor) * (_WrappingPowerFactor + 1) / (2 * (1 + _WrappingFactor));
|
||||
half3 brdf = wrappedDiffuse;
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
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
|
||||
|
||||
const float epsilon = 1.192092896e-07; // Smallest positive number, such that 1.0 + epsilon != 1.0
|
||||
|
||||
// SH brdf term
|
||||
#if defined(_METALLICGLOSSMAP) // Scattering
|
||||
float3 shLength = GetSHLength();
|
||||
float3 giBase = saturate(gi.diffuse / shLength);
|
||||
float giBaseL = dot(giBase, 1.0/3.0) + epsilon;
|
||||
giBase /= giBaseL;
|
||||
|
||||
brdfUV.x = giBaseL * 0.5 + 0.5;
|
||||
brdfUV.y = thickness * dot(shLength, fixed3(0.22, 0.707, 0.071));
|
||||
half3 brdfSH = UNITY_SAMPLE_TEX2D ( _BRDFTex, brdfUV ).rgb;
|
||||
gi.diffuse = max(0, shLength * giBase * lerp(giBaseL, brdfSH, thickness));
|
||||
#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 * lerp(diffuseTerm, brdf, thickness))
|
||||
+ specularTerm * light.color * FresnelTerm (specColor, lh)
|
||||
+ surfaceReduction * gi.specular * FresnelLerp (specColor, grazingTerm, nv);
|
||||
|
||||
return half4(color, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Surface functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct SurfaceOutputStandardSSSS
|
||||
{
|
||||
fixed3 Albedo; // base (diffuse or specular) color
|
||||
float3 Normal; // tangent space normal, if written
|
||||
half3 Emission;
|
||||
half Metallic; // 0=non-metal, 1=metal
|
||||
// Smoothness is the user facing name, it should be perceptual smoothness but user should not have to deal with it.
|
||||
// Everywhere in the code you meet smoothness it is perceptual smoothness
|
||||
half Smoothness; // 0=rough, 1=smooth
|
||||
half Occlusion; // occlusion (default 1)
|
||||
fixed Alpha; // alpha for transparencies
|
||||
fixed Thickness;
|
||||
};
|
||||
|
||||
|
||||
struct SurfaceOutputStandardSpecularSSSS
|
||||
{
|
||||
fixed3 Albedo; // diffuse color
|
||||
fixed3 Specular; // specular color
|
||||
float3 Normal; // tangent space normal, if written
|
||||
half3 Emission;
|
||||
half Smoothness; // 0=rough, 1=smooth
|
||||
half Occlusion; // occlusion (default 1)
|
||||
fixed Alpha; // alpha for transparencies
|
||||
fixed Thickness;
|
||||
};
|
||||
|
||||
inline half4 LightingStandardSSSS (SurfaceOutputStandardSSSS s, UnityGIInput data, UnityGI gi)
|
||||
{
|
||||
s.Normal = normalize(s.Normal);
|
||||
|
||||
half oneMinusReflectivity;
|
||||
half3 specColor;
|
||||
s.Albedo = DiffuseAndSpecularFromMetallic (s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
|
||||
|
||||
// shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
|
||||
// this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
|
||||
half outputAlpha;
|
||||
s.Albedo = PreMultiplyAlpha (s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
|
||||
|
||||
half4 c = UNITY_BRDF_PBS_SSSS (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Thickness, s.Normal, data.worldViewDir, gi.light, gi.indirect);
|
||||
|
||||
|
||||
#if defined(UNITY_PASS_FORWARDBASE) && defined(VERTEXLIGHT_ON)
|
||||
// energy conservation
|
||||
UnityLight light = gi.light;
|
||||
UnityIndirect nullGi = gi.indirect;
|
||||
|
||||
nullGi.diffuse = 0;
|
||||
nullGi.specular = 0;
|
||||
|
||||
for(int num = 0; num < 4 && any(unity_LightColor[num].rgb > 0); num++)
|
||||
{
|
||||
UnityLight light;
|
||||
float3 lightPos = float3(unity_4LightPosX0[num], unity_4LightPosY0[num], unity_4LightPosZ0[num]);
|
||||
light.dir = lightPos - data.worldPos;
|
||||
|
||||
float lengthSq = dot(light.dir, light.dir);
|
||||
float atten2 = saturate(1 - (lengthSq * unity_4LightAtten0[num] / 25));
|
||||
|
||||
if (atten2 > 0)
|
||||
{
|
||||
light.dir *= min(1e30, rsqrt(lengthSq));
|
||||
float atten = 1.0 / (1.0 + (lengthSq * unity_4LightAtten0[num]));
|
||||
//atten = unityPointAttenuation(lengthSq, unity_4LightAtten0[num]);
|
||||
atten = min(atten, atten2 * atten2);
|
||||
|
||||
light.color = unity_LightColor[num].rgb * atten;
|
||||
|
||||
c += UNITY_BRDF_PBS_SSSS (s.Albedo, specColor,
|
||||
oneMinusReflectivity, s.Smoothness,
|
||||
s.Thickness, s.Normal,
|
||||
data.worldViewDir, light, nullGi);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
c.a = outputAlpha;
|
||||
return c;
|
||||
}
|
||||
|
||||
inline half4 LightingStandardSSSS_Deferred (SurfaceOutputStandardSSSS s, float3 viewDir, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2)
|
||||
{
|
||||
half oneMinusReflectivity;
|
||||
half3 specColor;
|
||||
s.Albedo = DiffuseAndSpecularFromMetallic (s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
|
||||
|
||||
half4 c = UNITY_BRDF_PBS_SSSS (s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Thickness, s.Normal, viewDir, gi.light, gi.indirect);
|
||||
|
||||
UnityStandardData data;
|
||||
data.diffuseColor = s.Albedo;
|
||||
data.occlusion = s.Occlusion;
|
||||
data.specularColor = specColor;
|
||||
data.smoothness = s.Smoothness;
|
||||
data.normalWorld = s.Normal;
|
||||
|
||||
UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
|
||||
|
||||
half4 emission = half4(s.Emission + c.rgb, 1);
|
||||
return emission;
|
||||
}
|
||||
|
||||
inline void LightingStandardSSSS_GI (
|
||||
SurfaceOutputStandardSSSS s,
|
||||
UnityGIInput data,
|
||||
inout UnityGI gi)
|
||||
{
|
||||
#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
|
||||
gi = UnityGlobalIllumination_Geom(data, s.Occlusion, s.Normal);
|
||||
#else
|
||||
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo, s.Metallic));
|
||||
gi = UnityGlobalIllumination_Geom(data, s.Occlusion, s.Normal, g);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline half4 LightingStandardSSSSSpecular (SurfaceOutputStandardSpecularSSSS s, UnityGIInput data, UnityGI gi)
|
||||
{
|
||||
s.Normal = normalize(s.Normal);
|
||||
|
||||
// energy conservation
|
||||
half oneMinusReflectivity;
|
||||
s.Albedo = EnergyConservationBetweenDiffuseAndSpecular (s.Albedo, s.Specular, /*out*/ oneMinusReflectivity);
|
||||
|
||||
// shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
|
||||
// this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
|
||||
half outputAlpha;
|
||||
s.Albedo = PreMultiplyAlpha (s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
|
||||
|
||||
half4 c = UNITY_BRDF_PBS_SSSS (s.Albedo, s.Specular, oneMinusReflectivity, s.Smoothness, s.Thickness, s.Normal, data.worldViewDir, gi.light, gi.indirect);
|
||||
|
||||
#if defined(UNITY_PASS_FORWARDBASE) && defined(VERTEXLIGHT_ON)
|
||||
// energy conservation
|
||||
UnityLight light = gi.light;
|
||||
UnityIndirect nullGi = gi.indirect;
|
||||
|
||||
nullGi.diffuse = 0;
|
||||
nullGi.specular = 0;
|
||||
|
||||
for(int num = 0; num < 4 && any(unity_LightColor[num].rgb > 0); num++)
|
||||
{
|
||||
UnityLight light;
|
||||
float3 lightPos = float3(unity_4LightPosX0[num], unity_4LightPosY0[num], unity_4LightPosZ0[num]);
|
||||
light.dir = lightPos - data.worldPos;
|
||||
|
||||
float lengthSq = dot(light.dir, light.dir);
|
||||
float atten2 = saturate(1 - (lengthSq * unity_4LightAtten0[num] / 25));
|
||||
|
||||
if (atten2 > 0)
|
||||
{
|
||||
light.dir *= min(1e30, rsqrt(lengthSq));
|
||||
float atten = 1.0 / (1.0 + (lengthSq * unity_4LightAtten0[num]));
|
||||
//atten = unityPointAttenuation(lengthSq, unity_4LightAtten0[num]);
|
||||
atten = min(atten, atten2 * atten2);
|
||||
|
||||
light.color = unity_LightColor[num].rgb * atten;
|
||||
|
||||
c += UNITY_BRDF_PBS_SSSS (s.Albedo, s.Specular,
|
||||
oneMinusReflectivity, s.Smoothness,
|
||||
s.Thickness, s.Normal,
|
||||
data.worldViewDir, light, nullGi);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
c.a = outputAlpha;
|
||||
return c;
|
||||
}
|
||||
|
||||
inline half4 LightingStandardSSSSSpecular_Deferred (SurfaceOutputStandardSpecularSSSS s, float3 viewDir, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2)
|
||||
{
|
||||
// energy conservation
|
||||
half oneMinusReflectivity;
|
||||
s.Albedo = EnergyConservationBetweenDiffuseAndSpecular (s.Albedo, s.Specular, /*out*/ oneMinusReflectivity);
|
||||
|
||||
half4 c = UNITY_BRDF_PBS_SSSS (s.Albedo, s.Specular, oneMinusReflectivity, s.Smoothness, s.Thickness, s.Normal, viewDir, gi.light, gi.indirect);
|
||||
|
||||
UnityStandardData data;
|
||||
data.diffuseColor = s.Albedo;
|
||||
data.occlusion = s.Occlusion;
|
||||
data.specularColor = s.Specular;
|
||||
data.smoothness = s.Smoothness;
|
||||
data.normalWorld = s.Normal;
|
||||
|
||||
UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2);
|
||||
|
||||
half4 emission = half4(s.Emission + c.rgb, 1);
|
||||
return emission;
|
||||
}
|
||||
|
||||
inline void LightingStandardSSSSSpecular_GI (
|
||||
SurfaceOutputStandardSpecularSSSS s,
|
||||
UnityGIInput data,
|
||||
inout UnityGI gi)
|
||||
{
|
||||
#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
|
||||
gi = UnityGlobalIllumination_Geom(data, s.Occlusion, s.Normal);
|
||||
#else
|
||||
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, s.Specular);
|
||||
gi = UnityGlobalIllumination_Geom(data, s.Occlusion, s.Normal, g);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // SSS_CORE_INCLUDED
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b397c9c20b437d6459940d848fd7bb20
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
#ifndef SSS_SHADOW_INCLUDED
|
||||
#define SSS_SHADOW_INCLUDED
|
||||
|
||||
#include "HLSLSupport.cginc"
|
||||
#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN )
|
||||
#define CAN_SKIP_VPOS
|
||||
#endif
|
||||
#include "UnityCG.cginc"
|
||||
#include "Lighting.cginc"
|
||||
#include "UnityPBSLighting.cginc"
|
||||
struct v2f
|
||||
{
|
||||
V2F_SHADOW_CASTER;
|
||||
float4 customPack1 : TEXCOORD1;
|
||||
float4 tSpace0 : TEXCOORD2;
|
||||
float4 tSpace1 : TEXCOORD3;
|
||||
float4 tSpace2 : TEXCOORD4;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
v2f vert( appdata_full v )
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID( v );
|
||||
UNITY_INITIALIZE_OUTPUT( v2f, o );
|
||||
UNITY_TRANSFER_INSTANCE_ID( v, o );
|
||||
Input customInputData;
|
||||
float3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;
|
||||
half3 worldNormal = UnityObjectToWorldNormal( v.normal );
|
||||
half3 worldTangent = UnityObjectToWorldDir( v.tangent.xyz );
|
||||
half tangentSign = v.tangent.w * unity_WorldTransformParams.w;
|
||||
half3 worldBinormal = cross( worldNormal, worldTangent ) * tangentSign;
|
||||
o.tSpace0 = float4( worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x );
|
||||
o.tSpace1 = float4( worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y );
|
||||
o.tSpace2 = float4( worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z );
|
||||
o.customPack1.xy = customInputData.uv_texcoord;
|
||||
o.customPack1.xy = v.texcoord;
|
||||
o.customPack1.zw = v.texcoord1;
|
||||
|
||||
TRANSFER_SHADOW_CASTER_NORMALOFFSET( o )
|
||||
return o;
|
||||
}
|
||||
half4 frag( v2f IN
|
||||
#if !defined( CAN_SKIP_VPOS )
|
||||
, UNITY_VPOS_TYPE vpos : VPOS
|
||||
#endif
|
||||
) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID( IN );
|
||||
Input surfIN;
|
||||
UNITY_INITIALIZE_OUTPUT( Input, surfIN );
|
||||
surfIN.uv_texcoord = IN.customPack1.xy;
|
||||
surfIN.uv2_texcoord2 = IN.customPack1.zw;
|
||||
float3 worldPos = float3( IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w );
|
||||
half3 worldViewDir = normalize( UnityWorldSpaceViewDir( worldPos ) );
|
||||
surfIN.worldNormal = float3( IN.tSpace0.z, IN.tSpace1.z, IN.tSpace2.z );
|
||||
surfIN.internalSurfaceTtoW0 = IN.tSpace0.xyz;
|
||||
surfIN.internalSurfaceTtoW1 = IN.tSpace1.xyz;
|
||||
surfIN.internalSurfaceTtoW2 = IN.tSpace2.xyz;
|
||||
SurfaceOutputCustomLightingCustom o;
|
||||
UNITY_INITIALIZE_OUTPUT( SurfaceOutputCustomLightingCustom, o );
|
||||
|
||||
#if !defined(SSS_CUSTOM_SHADOW)
|
||||
float2 scaledUV = TRANSFORM_TEX(surfIN.uv_texcoord, _MainTex);
|
||||
|
||||
float4 _MainTex_var = tex2D( _MainTex, scaledUV );
|
||||
#if !(defined(_ALPHATEST_ON) || defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON))
|
||||
o.Alpha = 1.0;
|
||||
#else
|
||||
o.Alpha = (_SmoothnessFromAlbedo? 1.0 : _MainTex_var.a) * _Color.a ;
|
||||
o.Alpha = ((o.Alpha - _Cutout) / 0.0001 + 0.5);
|
||||
clip(o.Alpha - 1.0/255.0 );
|
||||
#endif
|
||||
#else
|
||||
customShadow( surfIN, o );
|
||||
#endif
|
||||
|
||||
#if defined( CAN_SKIP_VPOS )
|
||||
float2 vpos = IN.pos;
|
||||
#endif
|
||||
SHADOW_CASTER_FRAGMENT( IN )
|
||||
}
|
||||
|
||||
#endif // SSS_SHADOW_INCLUDED
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9670dae62ebdb8e4dbebe1dd39e0ba49
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,227 @@
|
||||
#ifndef SSS_INPUT_INCLUDED
|
||||
#define SSS_INPUT_INCLUDED
|
||||
|
||||
#include "UnityPBSLighting.cginc"
|
||||
#include "Lighting.cginc"
|
||||
|
||||
#ifdef UNITY_PASS_SHADOWCASTER
|
||||
#undef INTERNAL_DATA
|
||||
#undef WorldReflectionVector
|
||||
#undef WorldNormalVector
|
||||
#define INTERNAL_DATA half3 internalSurfaceTtoW0; half3 internalSurfaceTtoW1; half3 internalSurfaceTtoW2;
|
||||
#define WorldReflectionVector(data,normal) reflect (data.worldRefl, half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal)))
|
||||
#define WorldNormalVector(data,normal) half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal))
|
||||
#endif
|
||||
|
||||
struct Input
|
||||
{
|
||||
float3 worldNormal;
|
||||
float4 screenPos;
|
||||
INTERNAL_DATA
|
||||
float2 uv_texcoord;
|
||||
float2 uv2_texcoord2;
|
||||
half facing : VFACE;
|
||||
};
|
||||
|
||||
struct SurfaceOutputCustomLightingCustom
|
||||
{
|
||||
half3 Albedo;
|
||||
half3 Normal;
|
||||
half3 Emission;
|
||||
half3 Specular;
|
||||
half Smoothness;
|
||||
half Occlusion;
|
||||
half Alpha;
|
||||
half Thickness;
|
||||
half3 SubsurfaceColour;
|
||||
Input SurfInput;
|
||||
UnityGIInput GIData;
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
|
||||
uniform sampler2D _BumpMap;
|
||||
uniform sampler2D _MetallicGlossMap;
|
||||
uniform sampler2D _OcclusionMap;
|
||||
uniform sampler2D _ThicknessMap;
|
||||
uniform sampler2D _OverlayMap;
|
||||
uniform sampler2D _EmissionMap;
|
||||
uniform sampler2D _DetailMask;
|
||||
uniform sampler2D _DetailBumpMap; uniform float4 _DetailBumpMap_ST;
|
||||
uniform sampler2D _DetailMetallicGlossMap; uniform float4 _DetailMetallicGlossMap_ST;
|
||||
|
||||
uniform float _ThicknessMapPower;
|
||||
uniform float _ThicknessMapInvert;
|
||||
uniform float3 _SSSCol;
|
||||
uniform float _SSSAmbient;
|
||||
uniform float _SSSIntensity;
|
||||
uniform float _SSSPow;
|
||||
uniform float _SSSDist;
|
||||
uniform float _SSSShadow;
|
||||
uniform float4 _Color;
|
||||
uniform float3 _OverlayColor;
|
||||
uniform float3 _EmissionColor;
|
||||
uniform float3 _SpecularColor;
|
||||
|
||||
uniform float _DetailBumpMapScale;
|
||||
uniform float _ScatteringByAlbedo;
|
||||
uniform float _SmoothnessFromAlbedo;
|
||||
uniform float _BumpScale;
|
||||
uniform float _OcclusionStrength;
|
||||
uniform float _GlossMapScale;
|
||||
uniform float _Cutout;
|
||||
|
||||
uniform float _WrappingFactor;
|
||||
uniform float _WrappingPowerFactor;
|
||||
|
||||
uniform float _SecondUVSource;
|
||||
uniform float _OcclusionUVSource;
|
||||
uniform float _ThicknessUVSource;
|
||||
|
||||
#include "SSS_Utils.cginc"
|
||||
#include "SSS_Core.cginc"
|
||||
|
||||
inline void LightingStandardCustomLighting_GI( inout SurfaceOutputCustomLightingCustom s, UnityGIInput data, inout UnityGI gi )
|
||||
{
|
||||
s.GIData = data;
|
||||
}
|
||||
|
||||
void surf( Input i , inout SurfaceOutputCustomLightingCustom s1 )
|
||||
{
|
||||
s1.SurfInput = i;
|
||||
|
||||
float2 scaledUV = TRANSFORM_TEX(i.uv_texcoord, _MainTex);
|
||||
|
||||
float4 _MainTex_var = tex2D( _MainTex, scaledUV );
|
||||
float2 texcoord2 = _SecondUVSource? i.uv2_texcoord2 : scaledUV;
|
||||
float detailMask = tex2D( _DetailMask, scaledUV ).a;
|
||||
float3 overlayMask = tex2D(_OverlayMap,texcoord2).rgb*detailMask;
|
||||
|
||||
#if defined(USE_DETAIL_AS_ALPHA)
|
||||
_Color.a = lerp( _Color.a, tex2D( _OverlayMap, texcoord2 ).rgb,
|
||||
detailMask);
|
||||
#endif
|
||||
|
||||
#if !(defined(_ALPHATEST_ON) || defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON))
|
||||
s1.Alpha = 1.0;
|
||||
#else
|
||||
s1.Alpha = (_SmoothnessFromAlbedo? 1.0 : _MainTex_var.a) * _Color.a;
|
||||
s1.Alpha = ((s1.Alpha - _Cutout) / max(fwidth(s1.Alpha), 0.0001) + 0.5);
|
||||
clip(s1.Alpha - 1.0/255.0 );
|
||||
#endif
|
||||
|
||||
#if defined(USE_DETAIL_AS_ALPHA)
|
||||
s1.Albedo = _MainTex_var.rgb * _Color;
|
||||
#else
|
||||
s1.Albedo = lerp(_MainTex_var.rgb * _Color, _OverlayColor, overlayMask);
|
||||
#endif
|
||||
|
||||
s1.Normal = NormalInTangentSpace(scaledUV, texcoord2, detailMask);
|
||||
|
||||
s1.Emission = tex2D( _EmissionMap, scaledUV ).rgb * _EmissionColor.rgb;
|
||||
float4 _MetallicGlossMap_var = tex2D( _MetallicGlossMap, scaledUV );
|
||||
float4 detailMetallicGlossMap_var = tex2D (_DetailMetallicGlossMap, TRANSFORM_TEX(texcoord2, _DetailMetallicGlossMap));
|
||||
_MetallicGlossMap_var *= lerp(1.0, detailMetallicGlossMap_var, detailMask);
|
||||
|
||||
#if defined(SSS_METALLIC)
|
||||
s1.Specular = _MetallicGlossMap_var.r;
|
||||
#else
|
||||
s1.Specular = _MetallicGlossMap_var.rgb;
|
||||
#endif
|
||||
|
||||
s1.Specular *= _SpecularColor;
|
||||
|
||||
s1.Smoothness = _SmoothnessFromAlbedo? _MainTex_var.a : _MetallicGlossMap_var.a;
|
||||
s1.Smoothness *= _GlossMapScale;
|
||||
|
||||
float2 occlusionUV = _OcclusionUVSource? i.uv2_texcoord2 : scaledUV;
|
||||
s1.Occlusion = LerpOneTo(tex2D( _OcclusionMap, occlusionUV ).g, _OcclusionStrength);
|
||||
|
||||
float2 thicknessUV = _ThicknessUVSource? i.uv2_texcoord2 : scaledUV;
|
||||
float3 thicknessMap_var = tex2D( _ThicknessMap, thicknessUV ).rgb;
|
||||
s1.Thickness = pow(abs(_ThicknessMapInvert-thicknessMap_var), _ThicknessMapPower);
|
||||
s1.SubsurfaceColour = _ScatteringByAlbedo? _SSSCol*s1.Albedo : _SSSCol;
|
||||
}
|
||||
|
||||
inline half4 LightingStandardCustomLighting( inout SurfaceOutputCustomLightingCustom s, half3 viewDir, UnityGI gi )
|
||||
{
|
||||
UnityGIInput data = s.GIData;
|
||||
Input i = s.SurfInput;
|
||||
half4 c = 0;
|
||||
|
||||
#if defined(SSS_METALLIC)
|
||||
SurfaceOutputStandardSSSS s1 = (SurfaceOutputStandardSSSS ) 0;
|
||||
#else
|
||||
SurfaceOutputStandardSpecularSSSS s1 = (SurfaceOutputStandardSpecularSSSS ) 0;
|
||||
#endif
|
||||
|
||||
s1.Albedo = s.Albedo;
|
||||
s1.Normal = s.Normal;
|
||||
s1.Emission = s.Emission;
|
||||
#if defined(SSS_METALLIC)
|
||||
s1.Metallic = s.Specular.r;
|
||||
#else
|
||||
s1.Specular = s.Specular;
|
||||
#endif
|
||||
s1.Smoothness = s.Smoothness;
|
||||
s1.Occlusion = s.Occlusion;
|
||||
s1.Alpha = s.Alpha;
|
||||
s1.Thickness = s.Thickness;
|
||||
|
||||
s1.Smoothness = GeometricNormalFiltering(s1.Smoothness, i.worldNormal, 0.25, 0.5);
|
||||
|
||||
data.light = gi.light;
|
||||
|
||||
UnityGI gi1 = gi;
|
||||
#ifdef UNITY_PASS_FORWARDBASE
|
||||
Unity_GlossyEnvironmentData g1 =
|
||||
UnityGlossyEnvironmentSetup( s.Smoothness, data.worldViewDir, s1.Normal, float3(0,0,0));
|
||||
gi1 = UnityGlobalIllumination_Geom( data, 1.0, s1.Normal, g1, s1.Thickness);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
float NdotV = saturate(abs(dot(s1.Normal, viewDir)));
|
||||
float occlusion = ComputeMicroShadowing(s1.Occlusion * 0.8 + 0.3, NdotV, 1.0);
|
||||
float3 occlusionCol = GTAOMultiBounce( saturate(occlusion * 1.2), s1.Albedo);
|
||||
gi1.indirect.diffuse *= occlusionCol;
|
||||
gi1.indirect.specular *= occlusion;
|
||||
|
||||
float NdotL = saturate(abs(dot(s1.Normal, gi.light.dir)));
|
||||
occlusion = ComputeMicroShadowing(s1.Occlusion * 0.8 + 0.3, NdotL, 1.0);
|
||||
occlusionCol = GTAOMultiBounce( saturate(occlusion * 1.2), s1.Albedo);
|
||||
gi.light.color *= occlusionCol;
|
||||
#endif
|
||||
|
||||
#ifdef UNITY_PASS_FORWARDBASE
|
||||
float ase_lightAtten = data.atten;
|
||||
if( _LightColor0.a == 0)
|
||||
ase_lightAtten = 0;
|
||||
#else
|
||||
float3 ase_lightAttenRGB = gi.light.color / ( ( _LightColor0.rgb ) + 0.000001 );
|
||||
float ase_lightAtten = max( max( ase_lightAttenRGB.r, ase_lightAttenRGB.g ), ase_lightAttenRGB.b );
|
||||
#endif
|
||||
|
||||
#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
|
||||
half bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);
|
||||
float zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);
|
||||
float fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);
|
||||
ase_lightAtten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));
|
||||
#endif
|
||||
|
||||
#if defined(SSS_METALLIC)
|
||||
float3 finalResult = LightingStandardSSSS ( s1, data, gi1 ).rgb;
|
||||
#else
|
||||
float3 finalResult = LightingStandardSSSSSpecular ( s1, data, gi1 ).rgb;
|
||||
#endif
|
||||
|
||||
finalResult += getSubsurfaceScatteringLight(gi.light.color, gi.light.dir, s1.Normal, data.worldViewDir,
|
||||
LerpOneTo(ase_lightAtten, _SSSShadow), s1.Thickness, gi1.indirect.diffuse, s.SubsurfaceColour );
|
||||
|
||||
finalResult += s1.Emission;
|
||||
|
||||
c.rgb = finalResult;
|
||||
c.a = s1.Alpha;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif // SSS_INPUT_INCLUDED
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e88fd0cd8e9dd446a184fd9e762d9a5
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,415 @@
|
||||
#ifndef SSS_UTILS_INCLUDED
|
||||
#define SSS_UTILS_INCLUDED
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
float RoughnessToPerceptualRoughness_local(float roughness)
|
||||
{
|
||||
return sqrt(roughness);
|
||||
}
|
||||
|
||||
float RoughnessToPerceptualSmoothness_local(float roughness)
|
||||
{
|
||||
return 1.0 - sqrt(roughness);
|
||||
}
|
||||
|
||||
float PerceptualSmoothnessToRoughness_local(float perceptualSmoothness)
|
||||
{
|
||||
return (1.0 - perceptualSmoothness) * (1.0 - perceptualSmoothness);
|
||||
}
|
||||
|
||||
float PerceptualSmoothnessToPerceptualRoughness_local(float perceptualSmoothness)
|
||||
{
|
||||
return (1.0 - perceptualSmoothness);
|
||||
}
|
||||
|
||||
float PerceptualRoughnessToPerceptualSmoothness_local(float perceptualRoughness)
|
||||
{
|
||||
return (1.0 - perceptualRoughness);
|
||||
}
|
||||
|
||||
// Return modified perceptualSmoothness based on provided variance (get from GeometricNormalVariance + TextureNormalVariance)
|
||||
float NormalFiltering(float perceptualSmoothness, float variance, float threshold)
|
||||
{
|
||||
float roughness = PerceptualSmoothnessToRoughness_local(perceptualSmoothness);
|
||||
// Ref: Geometry into Shading - http://graphics.pixar.com/library/BumpRoughness/paper.pdf - equation (3)
|
||||
float squaredRoughness = saturate(roughness * roughness + min(2.0 * variance, threshold * threshold)); // threshold can be floatly low, square the value for easier control
|
||||
|
||||
return RoughnessToPerceptualSmoothness_local(sqrt(squaredRoughness));
|
||||
}
|
||||
|
||||
// Reference: Error Reduction and Simplification for Shading Anti-Aliasing
|
||||
// Specular antialiasing for geometry-induced normal (and NDF) variations: Tokuyoshi / Kaplanyan et al.'s method.
|
||||
// This is the deferred approximation, which works reasonably well so we keep it for forward too for now.
|
||||
// screenSpaceVariance should be at most 0.5^2 = 0.25, as that corresponds to considering
|
||||
// a gaussian pixel reconstruction kernel with a standard deviation of 0.5 of a pixel, thus 2 sigma covering the whole pixel.
|
||||
float GeometricNormalVariance(float3 geometricNormalWS, float screenSpaceVariance)
|
||||
{
|
||||
float3 deltaU = ddx(geometricNormalWS);
|
||||
float3 deltaV = ddy(geometricNormalWS);
|
||||
|
||||
return screenSpaceVariance * (dot(deltaU, deltaU) + dot(deltaV, deltaV));
|
||||
}
|
||||
|
||||
// Return modified perceptualSmoothness
|
||||
float GeometricNormalFiltering(float perceptualSmoothness, float3 geometricNormalWS, float screenSpaceVariance, float threshold)
|
||||
{
|
||||
float variance = GeometricNormalVariance(geometricNormalWS, screenSpaceVariance);
|
||||
return NormalFiltering(perceptualSmoothness, variance, threshold);
|
||||
}
|
||||
|
||||
//SSS method from GDC 2011 conference by Colin Barre-Bresebois & Marc Bouchard and modified by Xiexe
|
||||
float3 getSubsurfaceScatteringLight (float3 lightColor, float3 lightDirection, float3 normalDirection, float3 viewDirection,
|
||||
float attenuation, float3 thickness, float3 indirectLight, float3 subsurfaceColour)
|
||||
{
|
||||
float3 vLTLight = lightDirection + normalDirection * _SSSDist; // Distortion
|
||||
float3 fLTDot = pow(saturate(dot(viewDirection, -vLTLight)), _SSSPow)
|
||||
* _SSSIntensity * 1.0/UNITY_PI;
|
||||
|
||||
return lerp(1, attenuation, float(any(_WorldSpaceLightPos0.xyz)))
|
||||
* (fLTDot + _SSSAmbient) * thickness
|
||||
* (lightColor + indirectLight) * subsurfaceColour;
|
||||
|
||||
}
|
||||
|
||||
inline float3 BlendNormalsPD(float3 n1, float3 n2) {
|
||||
return normalize(float3(n1.xy*n2.z + n2.xy*n1.z, n1.z*n2.z));
|
||||
}
|
||||
|
||||
// Based on NormalInTangentSpace from UnityStandardInput
|
||||
inline float3 NormalInTangentSpace(float2 texcoords, float2 texcoords2, half mask)
|
||||
{
|
||||
//float3 normalTangent = UnpackNormal(tex2D(_BumpMap,TRANSFORM_TEX(texcoords.xy, _MainTex)));
|
||||
//float3 normalTangent = UnpackNormal(tex2D(_BumpMap,texcoords.xy));
|
||||
half3 normalTangent = UnpackScaleNormal(tex2D (_BumpMap, texcoords.xy), _BumpScale);
|
||||
|
||||
half3 detailNormalTangent = UnpackScaleNormal(tex2D (_DetailBumpMap, TRANSFORM_TEX(texcoords2.xy, _DetailBumpMap)), _DetailBumpMapScale);
|
||||
#if _DETAIL_LERP
|
||||
normalTangent = lerp(
|
||||
normalTangent,
|
||||
detailNormalTangent,
|
||||
mask);
|
||||
#else
|
||||
normalTangent = lerp(
|
||||
normalTangent,
|
||||
BlendNormalsPD(normalTangent, detailNormalTangent),
|
||||
mask);
|
||||
#endif
|
||||
|
||||
return normalTangent;
|
||||
}
|
||||
|
||||
// "R2" dithering
|
||||
|
||||
// Triangle Wave
|
||||
float T(float z) {
|
||||
return z >= 0.5 ? 2.-2.*z : 2.*z;
|
||||
}
|
||||
|
||||
// R dither mask
|
||||
float intensity(float2 pixel) {
|
||||
const float a1 = 0.75487766624669276;
|
||||
const float a2 = 0.569840290998;
|
||||
return frac(a1 * float(pixel.x) + a2 * float(pixel.y));
|
||||
}
|
||||
|
||||
// Get the maximum SH contribution
|
||||
// synqark's Arktoon shader's shading method
|
||||
half3 GetSHLength ()
|
||||
{
|
||||
half3 x, x1;
|
||||
x.r = length(unity_SHAr);
|
||||
x.g = length(unity_SHAg);
|
||||
x.b = length(unity_SHAb);
|
||||
x1.r = length(unity_SHBr);
|
||||
x1.g = length(unity_SHBg);
|
||||
x1.b = length(unity_SHBb);
|
||||
return x + x1;
|
||||
}
|
||||
|
||||
half3 min3(float a, float b, float c) {
|
||||
return min(min(a, b), c);
|
||||
}
|
||||
|
||||
half3 min3(float3 a) {
|
||||
return min(min(a.x, a.y), a.z);
|
||||
}
|
||||
|
||||
half3 max3(float a, float b, float c) {
|
||||
return max(max(a, b), c);
|
||||
}
|
||||
|
||||
half3 max3(float3 a) {
|
||||
return max(max(a.x, a.y), a.z);
|
||||
}
|
||||
|
||||
half3 GetSHAvg ()
|
||||
{
|
||||
return float3(unity_SHAr.w,unity_SHAg.w,unity_SHAb.w);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Better GI functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/* http://www.geomerics.com/wp-content/uploads/2015/08/CEDEC_Geomerics_ReconstructingDiffuseLighting1.pdf */
|
||||
float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
|
||||
{
|
||||
// average energy
|
||||
float R0 = L0;
|
||||
|
||||
// avg direction of incoming light
|
||||
float3 R1 = 0.5f * L1;
|
||||
|
||||
// directional brightness
|
||||
float lenR1 = length(R1);
|
||||
|
||||
// linear angle between normal and direction 0-1
|
||||
//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
|
||||
//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
|
||||
float q = dot(normalize(R1), n) * 0.5 + 0.5;
|
||||
q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
|
||||
|
||||
// power for q
|
||||
// lerps from 1 (linear) to 3 (cubic) based on directionality
|
||||
float p = 1.0f + 2.0f * lenR1 / R0;
|
||||
|
||||
// dynamic range constant
|
||||
// should vary between 4 (highly directional) and 0 (ambient)
|
||||
float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
|
||||
|
||||
return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
|
||||
}
|
||||
|
||||
// From https://github.com/lukis101/VRCUnityStuffs/tree/master/SH
|
||||
// SH Convolution Functions
|
||||
// Code adapted from https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
|
||||
///////////////////////////
|
||||
|
||||
float3 GeneralWrapSH(float fA) // original unoptimized
|
||||
{
|
||||
// Normalization factor for our model.
|
||||
float norm = 0.5 * (2 + fA) / (1 + fA);
|
||||
float4 t = float4(2 * (fA + 1), fA + 2, fA + 3, fA + 4);
|
||||
return norm * float3(t.x / t.y, 2 * t.x / (t.y * t.z),
|
||||
t.x * (fA * fA - t.x + 5) / (t.y * t.z * t.w));
|
||||
}
|
||||
float3 GeneralWrapSHOpt(float fA)
|
||||
{
|
||||
const float4 t0 = float4(-0.047771, -0.129310, 0.214438, 0.279310);
|
||||
const float4 t1 = float4( 1.000000, 0.666667, 0.250000, 0.000000);
|
||||
|
||||
float3 r;
|
||||
r.xyz = saturate(t0.xxy * fA + t0.yzw);
|
||||
r.xyz = -r * fA + t1.xyz;
|
||||
return r;
|
||||
}
|
||||
|
||||
float3 GreenWrapSHOpt(float fW)
|
||||
{
|
||||
const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
|
||||
const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
|
||||
|
||||
float3 r;
|
||||
r.xyz = t0.xxy * fW + t0.xzw;
|
||||
r.xyz = r.xyz * fW + t1.xyz;
|
||||
return r;
|
||||
}
|
||||
|
||||
float3 ShadeSH9_wrapped(float3 normal, float3 conv)
|
||||
{
|
||||
float3 x0, x1, x2;
|
||||
conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution
|
||||
//conv *= _Bands.xyz; // debugging
|
||||
|
||||
// Constant (L0)
|
||||
// Band 0 has constant part from 6th kernel (band 1) pre-applied, but ignore for performance
|
||||
x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
|
||||
|
||||
// Linear (L1) polynomial terms
|
||||
x1.r = (dot(unity_SHAr.xyz, normal));
|
||||
x1.g = (dot(unity_SHAg.xyz, normal));
|
||||
x1.b = (dot(unity_SHAb.xyz, normal));
|
||||
|
||||
// 4 of the quadratic (L2) polynomials
|
||||
float4 vB = normal.xyzz * normal.yzzx;
|
||||
x2.r = dot(unity_SHBr, vB);
|
||||
x2.g = dot(unity_SHBg, vB);
|
||||
x2.b = dot(unity_SHBb, vB);
|
||||
|
||||
// Final (5th) quadratic (L2) polynomial
|
||||
float vC = normal.x * normal.x - normal.y * normal.y;
|
||||
x2 += unity_SHC.rgb * vC;
|
||||
|
||||
return x0 * conv.x + x1 * conv.y + x2 * conv.z;
|
||||
}
|
||||
|
||||
float3 ShadeSH9_wrappedCorrect(float3 normal, float3 conv)
|
||||
{
|
||||
const float3 cosconv_inv = float3(1, 1.5, 4); // Inverse of the pre-applied cosine convolution
|
||||
float3 x0, x1, x2;
|
||||
conv *= cosconv_inv; // Undo pre-applied cosine convolution
|
||||
//conv *= _Bands.xyz; // debugging
|
||||
|
||||
// Constant (L0)
|
||||
x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
|
||||
// Remove the constant part from L2 and add it back with correct convolution
|
||||
float3 otherband = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
|
||||
x0 = (x0 + otherband) * conv.x - otherband * conv.z;
|
||||
|
||||
// Linear (L1) polynomial terms
|
||||
x1.r = (dot(unity_SHAr.xyz, normal));
|
||||
x1.g = (dot(unity_SHAg.xyz, normal));
|
||||
x1.b = (dot(unity_SHAb.xyz, normal));
|
||||
|
||||
// 4 of the quadratic (L2) polynomials
|
||||
float4 vB = normal.xyzz * normal.yzzx;
|
||||
x2.r = dot(unity_SHBr, vB);
|
||||
x2.g = dot(unity_SHBg, vB);
|
||||
x2.b = dot(unity_SHBb, vB);
|
||||
|
||||
// Final (5th) quadratic (L2) polynomial
|
||||
float vC = normal.x * normal.x - normal.y * normal.y;
|
||||
x2 += unity_SHC.rgb * vC;
|
||||
|
||||
return x0 + x1 * conv.y + x2 * conv.z;
|
||||
}
|
||||
|
||||
float PositivePow(float base, float power)
|
||||
{
|
||||
return pow(abs(base), power);
|
||||
}
|
||||
|
||||
bool isReflectionProbeActive()
|
||||
{
|
||||
#ifndef SHADER_TARGET_SURFACE_ANALYSIS // Required to use GetDimensions
|
||||
float height, width;
|
||||
unity_SpecCube0.GetDimensions(width, height);
|
||||
return !(height * width < 32);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Ref: Moving Frostbite to PBR - Gotanda siggraph 2011
|
||||
// Return specular occlusion based on ambient occlusion (usually get from SSAO) and view/roughness info
|
||||
float GetSpecularOcclusionFromAmbientOcclusion(float NdotV, float ambientOcclusion, float roughness)
|
||||
{
|
||||
return saturate(PositivePow(NdotV + ambientOcclusion, exp2(-16.0 * roughness - 1.0)) - 1.0 + ambientOcclusion);
|
||||
}
|
||||
|
||||
inline UnityGI UnityGlobalIllumination_Geom (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn,
|
||||
half thickness = 0.5)
|
||||
{
|
||||
UnityGI o_gi = UnityGI_Base(data, occlusion, normalWorld);
|
||||
#if UNITY_SHOULD_SAMPLE_SH
|
||||
#if 0
|
||||
o_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
|
||||
float3 nonLinearSH = float3(0,0,0);
|
||||
nonLinearSH.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normalWorld);
|
||||
nonLinearSH.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normalWorld);
|
||||
nonLinearSH.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normalWorld);
|
||||
nonLinearSH = max(nonLinearSH, 0);
|
||||
nonLinearSH += SHEvalLinearL2(half4(normal, 1.0));
|
||||
o_gi.indirect.diffuse += nonLinearSH * occlusion;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
float shWrap = thickness;
|
||||
float3 sh_conv = GeneralWrapSH(shWrap);
|
||||
o_gi.indirect.diffuse = ShadeSH9_wrappedCorrect(normalWorld, sh_conv);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
half NdotV = abs(dot(normalWorld, data.worldViewDir));
|
||||
float specOcclusion = GetSpecularOcclusionFromAmbientOcclusion(NdotV, occlusion, glossIn.roughness);
|
||||
#else
|
||||
float specOcclusion = occlusion;
|
||||
#endif
|
||||
|
||||
|
||||
if (isReflectionProbeActive())
|
||||
{
|
||||
o_gi.indirect.specular = UnityGI_IndirectSpecular(data, specOcclusion, glossIn);
|
||||
} else
|
||||
{
|
||||
// Use light probes for the indirect specular lighting.
|
||||
o_gi.indirect.specular = o_gi.indirect.diffuse;
|
||||
}
|
||||
return o_gi;
|
||||
}
|
||||
|
||||
half3 BetterSH9 (half4 normal) {
|
||||
float3 indirect;
|
||||
float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
|
||||
indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal);
|
||||
indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal);
|
||||
indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal);
|
||||
indirect = max(0, indirect);
|
||||
return indirect;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Ref: Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
|
||||
float GetHorizonOcclusion(float3 V, float3 normalWS, float3 vertexNormal, float horizonFade)
|
||||
{
|
||||
float3 R = reflect(-V, normalWS);
|
||||
float specularOcclusion = saturate(1.0 + horizonFade * dot(R, vertexNormal));
|
||||
// smooth it
|
||||
return specularOcclusion * specularOcclusion;
|
||||
}
|
||||
|
||||
// ref: Practical floattime Strategies for Accurate Indirect Occlusion
|
||||
// Update ambient occlusion to colored ambient occlusion based on statitics of how light is bouncing in an object and with the albedo of the object
|
||||
float3 GTAOMultiBounce(float visibility, float3 albedo)
|
||||
{
|
||||
float3 a = 2.0404 * albedo - 0.3324;
|
||||
float3 b = -4.7951 * albedo + 0.6417;
|
||||
float3 c = 2.7552 * albedo + 0.6903;
|
||||
|
||||
float x = visibility;
|
||||
return max(x, ((x * a + b) * x + c) * x);
|
||||
}
|
||||
|
||||
// Ref: The Technical Art of Uncharted 4 - Brinck and Maximov 2016
|
||||
float ComputeMicroShadowing(float AO, float NdotL, float opacity)
|
||||
{
|
||||
float aperture = 2.0 * AO * AO;
|
||||
float microshadow = saturate(NdotL + aperture - 1.0);
|
||||
return lerp(1.0, microshadow, opacity);
|
||||
}
|
||||
|
||||
// Invoke with finalcolor:ApplyDitherAlpha
|
||||
// Must be defined after surf in file.
|
||||
void ApplyDitherAlpha(Input IN, SurfaceOutputCustomLightingCustom o, inout fixed4 color) {
|
||||
float2 pos = (IN.screenPos.xy*_ScreenParams)/IN.screenPos.w;
|
||||
pos += _SinTime.x%4;
|
||||
float alpha = o.Alpha;
|
||||
|
||||
#if !(defined(_ALPHATEST_ON) || defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON))
|
||||
alpha = 1.0;
|
||||
#else
|
||||
alpha = ((alpha - _Cutout) / max(fwidth(alpha), 0.0001) + 0.5);
|
||||
clip(alpha - 1.0/255.0 );
|
||||
#endif
|
||||
|
||||
//float mask = (T(intensity(pos)));
|
||||
//alpha = saturate(alpha + alpha * mask);
|
||||
|
||||
color.a = alpha;
|
||||
}
|
||||
|
||||
float unityPointAttenuation(float lengthSq, float range)
|
||||
{
|
||||
// Based on https://geom.io/bakery/wiki/index.php?title=Point_Light_Attenuation
|
||||
return 1/(pow((lengthSq/range)*5, 2.0)+1);
|
||||
|
||||
}
|
||||
|
||||
#endif // SSS_UTILS_INCLUDED
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c0344c0f457988478df793fa62f9cdd
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
@@ -0,0 +1,96 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 438762e23bc56bf4188ce947bf60e0e3
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user