Created
March 16, 2022 17:49
-
-
Save shivaduke28/7d2aa7fd9651d06be96f1dee9441e20a to your computer and use it in GitHub Desktop.
a copy of Standard shader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copyright(c) 2016 Unity Technologies | |
Permission is hereby granted, free of charge, to any person obtaining a copy of | |
this software and associated documentation files(the "Software"), to deal in | |
the Software without restriction, including without limitation the rights to | |
use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies | |
of the Software, and to permit persons to whom the Software is furnished to do | |
so, subject to the following conditions : | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR | |
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
#ifndef TKMNY_STANDARD_VARIANT_INCLUDED | |
#define TKMNY_STANDARD_VARIANT_INCLUDED | |
#include <UnityCG.cginc> | |
#include <UnityLightingCommon.cginc> | |
#include <AutoLight.cginc> | |
//--------------------------------------- | |
// define | |
//--------------------------------------- | |
#if (_NORMALMAP || DIRLIGHTMAP_COMBINED || _PARALLAXMAP) | |
#define _TANGENT_TO_WORLD 1 | |
#endif | |
#if (_DETAIL_MULX2 || _DETAIL_MUL || _DETAIL_ADD || _DETAIL_LERP) | |
#define _DETAIL 1 | |
#endif | |
#ifdef _PARALLAXMAP | |
#define IN_VIEWDIR4PARALLAX(i) half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w) | |
#define IN_VIEWDIR4PARALLAX_FWDADD(i) normalize(i.viewDirForParallax.xyz) | |
#else | |
#define IN_VIEWDIR4PARALLAX(i) half3(0,0,0) | |
#define IN_VIEWDIR4PARALLAX_FWDADD(i) half3(0,0,0) | |
#endif | |
#if UNITY_REQUIRE_FRAG_WORLDPOS | |
#if UNITY_PACK_WORLDPOS_WITH_TANGENT | |
#define IN_WORLDPOS(i) half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w) | |
#else | |
#define IN_WORLDPOS(i) i.posWorld | |
#endif | |
#define IN_WORLDPOS_FWDADD(i) i.posWorld | |
#else | |
#define IN_WORLDPOS(i) half3(0,0,0) | |
#define IN_WORLDPOS_FWDADD(i) half3(0,0,0) | |
#endif | |
#define UNITY_SPECCUBE_LOD_STEPS (6) | |
#define IN_LIGHTDIR_FWDADD(i) half3(i.tangentToWorldAndLightDir[0].w, i.tangentToWorldAndLightDir[1].w, i.tangentToWorldAndLightDir[2].w) | |
//--------------------------------------- | |
// uniform | |
//--------------------------------------- | |
half4 _Color; | |
half _Cutoff; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
sampler2D _DetailAlbedoMap; | |
float4 _DetailAlbedoMap_ST; | |
sampler2D _BumpMap; | |
half _BumpScale; | |
sampler2D _DetailMask; | |
sampler2D _DetailNormalMap; | |
half _DetailNormalMapScale; | |
sampler2D _SpecGlossMap; | |
sampler2D _MetallicGlossMap; | |
half _Metallic; | |
float _Glossiness; | |
float _GlossMapScale; | |
sampler2D _OcclusionMap; | |
half _OcclusionStrength; | |
sampler2D _ParallaxMap; | |
half _Parallax; | |
half _UVSec; | |
half4 _EmissionColor; | |
sampler2D _EmissionMap; | |
//--------------------------------------- | |
// struct | |
//--------------------------------------- | |
struct VertexInput | |
{ | |
float4 vertex : POSITION; | |
half3 normal : NORMAL; | |
float2 uv0 : TEXCOORD0; | |
float2 uv1 : TEXCOORD1; | |
#if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META) | |
float2 uv2 : TEXCOORD2; | |
#endif | |
#ifdef _TANGENT_TO_WORLD | |
half4 tangent : TANGENT; | |
#endif | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
}; | |
struct VertexOutputForwardBase | |
{ | |
UNITY_POSITION(pos); | |
float4 tex : TEXCOORD0; | |
float4 eyeVec : TEXCOORD1; // eyeVec.xyz | fogCoord | |
float4 tangentToWorldAndPackedData[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax or worldPos] | |
half4 ambientOrLightmapUV : TEXCOORD5; // SH or Lightmap UV | |
UNITY_LIGHTING_COORDS(6, 7) | |
// next ones would not fit into SM2.0 limits, but they are always for SM3.0+ | |
#if UNITY_REQUIRE_FRAG_WORLDPOS && !UNITY_PACK_WORLDPOS_WITH_TANGENT | |
float3 posWorld : TEXCOORD8; | |
#endif | |
UNITY_VERTEX_INPUT_INSTANCE_ID | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
//---------------------------------------- | |
// functions | |
inline float3 Unity_SafeNormalize(float3 inVec) | |
{ | |
float dp3 = max(0.001f, dot(inVec, inVec)); | |
return inVec * rsqrt(dp3); | |
} | |
float SmoothnessToPerceptualRoughness(float smoothness) | |
{ | |
return (1 - smoothness); | |
} | |
float PerceptualRoughnessToRoughness(float perceptualRoughness) | |
{ | |
return perceptualRoughness * perceptualRoughness; | |
} | |
inline half OneMinusReflectivityFromMetallic(half metallic) | |
{ | |
// We'll need oneMinusReflectivity, so | |
// 1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic) | |
// store (1-dielectricSpec) in unity_ColorSpaceDielectricSpec.a, then | |
// 1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) = | |
// = alpha - metallic * alpha | |
half oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.a; | |
return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec; | |
} | |
inline half3 DiffuseAndSpecularFromMetallic(half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity) | |
{ | |
specColor = lerp(unity_ColorSpaceDielectricSpec.rgb, albedo, metallic); | |
oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic); | |
return albedo * oneMinusReflectivity; | |
} | |
inline half Pow5(half x) | |
{ | |
return x * x * x * x * x; | |
} | |
half2 ParallaxOffset1Step(half h, half height, half3 viewDir) | |
{ | |
h = h * height - height / 2.0; | |
half3 v = normalize(viewDir); | |
v.z += 0.42; | |
return h * (v.xy / v.z); | |
} | |
half LerpOneTo(half b, half t) | |
{ | |
half oneMinusT = 1 - t; | |
return oneMinusT + b * t; | |
} | |
half3 LerpWhiteTo(half3 b, half t) | |
{ | |
half oneMinusT = 1 - t; | |
return half3(oneMinusT, oneMinusT, oneMinusT) + b * t; | |
} | |
half3 UnpackScaleNormalRGorAG(half4 packednormal, half bumpScale) | |
{ | |
#if defined(UNITY_NO_DXT5nm) | |
half3 normal = packednormal.xyz * 2 - 1; | |
#if (SHADER_TARGET >= 30) | |
// SM2.0: instruction count limitation | |
// SM2.0: normal scaler is not supported | |
normal.xy *= bumpScale; | |
#endif | |
return normal; | |
#else | |
// This do the trick | |
packednormal.x *= packednormal.w; | |
half3 normal; | |
normal.xy = (packednormal.xy * 2 - 1); | |
#if (SHADER_TARGET >= 30) | |
// SM2.0: instruction count limitation | |
// SM2.0: normal scaler is not supported | |
normal.xy *= bumpScale; | |
#endif | |
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy))); | |
return normal; | |
#endif | |
} | |
half3 UnpackScaleNormal(half4 packednormal, half bumpScale) | |
{ | |
return UnpackScaleNormalRGorAG(packednormal, bumpScale); | |
} | |
half3 BlendNormals(half3 n1, half3 n2) | |
{ | |
return normalize(half3(n1.xy + n2.xy, n1.z * n2.z)); | |
} | |
half3x3 CreateTangentToWorldPerVertex(half3 normal, half3 tangent, half tangentSign) | |
{ | |
// For odd-negative scale transforms we need to flip the sign | |
half sign = tangentSign * unity_WorldTransformParams.w; | |
half3 binormal = cross(normal, tangent) * sign; | |
return half3x3(tangent, binormal, normal); | |
} | |
float4 TexCoords(VertexInput v) | |
{ | |
float4 texcoord; | |
texcoord.xy = TRANSFORM_TEX(v.uv0, _MainTex); // Always source from uv0 | |
texcoord.zw = TRANSFORM_TEX(((_UVSec == 0) ? v.uv0 : v.uv1), _DetailAlbedoMap); | |
return texcoord; | |
} | |
half DetailMask(float2 uv) | |
{ | |
return tex2D(_DetailMask, uv).a; | |
} | |
half3 Albedo(float4 texcoords) | |
{ | |
half3 albedo = _Color.rgb * tex2D(_MainTex, texcoords.xy).rgb; | |
#if _DETAIL | |
half mask = DetailMask(texcoords.xy); | |
half3 detailAlbedo = tex2D (_DetailAlbedoMap, texcoords.zw).rgb; | |
#if _DETAIL_MULX2 | |
albedo *= LerpWhiteTo (detailAlbedo * unity_ColorSpaceDouble.rgb, mask); | |
#elif _DETAIL_MUL | |
albedo *= LerpWhiteTo (detailAlbedo, mask); | |
#elif _DETAIL_ADD | |
albedo += detailAlbedo * mask; | |
#elif _DETAIL_LERP | |
albedo = lerp (albedo, detailAlbedo, mask); | |
#endif | |
#endif | |
return albedo; | |
} | |
half Alpha(float2 uv) | |
{ | |
#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) | |
return _Color.a; | |
#else | |
return tex2D(_MainTex, uv).a * _Color.a; | |
#endif | |
} | |
half Occlusion(float2 uv) | |
{ | |
half occ = tex2D(_OcclusionMap, uv).g; | |
return LerpOneTo(occ, _OcclusionStrength); | |
} | |
half2 MetallicGloss(float2 uv) | |
{ | |
half2 mg; | |
#ifdef _METALLICGLOSSMAP | |
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
mg.r = tex2D(_MetallicGlossMap, uv).r; | |
mg.g = tex2D(_MainTex, uv).a; | |
#else | |
mg = tex2D(_MetallicGlossMap, uv).ra; | |
#endif | |
mg.g *= _GlossMapScale; | |
#else | |
mg.r = _Metallic; | |
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
mg.g = tex2D(_MainTex, uv).a * _GlossMapScale; | |
#else | |
mg.g = _Glossiness; | |
#endif | |
#endif | |
return mg; | |
} | |
half3 Emission(float2 uv) | |
{ | |
#ifndef _EMISSION | |
return 0; | |
#else | |
return tex2D(_EmissionMap, uv).rgb * _EmissionColor.rgb; | |
#endif | |
} | |
#ifdef _NORMALMAP | |
half3 NormalInTangentSpace(float4 texcoords) | |
{ | |
half3 normalTangent = UnpackScaleNormal(tex2D (_BumpMap, texcoords.xy), _BumpScale); | |
#if _DETAIL && defined(UNITY_ENABLE_DETAIL_NORMALMAP) | |
half mask = DetailMask(texcoords.xy); | |
half3 detailNormalTangent = UnpackScaleNormal(tex2D (_DetailNormalMap, texcoords.zw), _DetailNormalMapScale); | |
#if _DETAIL_LERP | |
normalTangent = lerp( | |
normalTangent, | |
detailNormalTangent, | |
mask); | |
#else | |
normalTangent = lerp( | |
normalTangent, | |
BlendNormals(normalTangent, detailNormalTangent), | |
mask); | |
#endif | |
#endif | |
return normalTangent; | |
} | |
#endif | |
float4 Parallax(float4 texcoords, half3 viewDir) | |
{ | |
#if !defined(_PARALLAXMAP) | |
// Disable parallax on pre-SM3.0 shader target models | |
return texcoords; | |
#else | |
half h = tex2D (_ParallaxMap, texcoords.xy).g; | |
float2 offset = ParallaxOffset1Step (h, _Parallax, viewDir); | |
return float4(texcoords.xy + offset, texcoords.zw + offset); | |
#endif | |
} | |
float3 PerPixelWorldNormal(float4 i_tex, float4 tangentToWorld[3]) | |
{ | |
#ifdef _NORMALMAP | |
half3 tangent = tangentToWorld[0].xyz; | |
half3 binormal = tangentToWorld[1].xyz; | |
half3 normal = tangentToWorld[2].xyz; | |
#if UNITY_TANGENT_ORTHONORMALIZE | |
// ortho-normalize Tangent | |
tangent = normalize (tangent - normal * dot(tangent, normal)); | |
// recalculate Binormal | |
half3 newB = cross(normal, tangent); | |
binormal = newB * sign (dot (newB, binormal)); | |
#endif | |
half3 normalTangent = NormalInTangentSpace(i_tex); | |
float3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z); | |
#else | |
float3 normalWorld = normalize(tangentToWorld[2].xyz); | |
#endif | |
return normalWorld; | |
} | |
inline half3 PreMultiplyAlpha(half3 diffColor, half alpha, half oneMinusReflectivity, out half outModifiedAlpha) | |
{ | |
#if defined(_ALPHAPREMULTIPLY_ON) | |
// NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha) | |
// Transparency 'removes' from Diffuse component | |
diffColor *= alpha; | |
// Reflectivity 'removes' from the rest of components, including Transparency | |
// outAlpha = 1-(1-alpha)*(1-reflectivity) = 1-(oneMinusReflectivity - alpha*oneMinusReflectivity) = | |
// = 1-oneMinusReflectivity + alpha*oneMinusReflectivity | |
outModifiedAlpha = 1-oneMinusReflectivity + alpha*oneMinusReflectivity; | |
#else | |
outModifiedAlpha = alpha; | |
#endif | |
return diffColor; | |
} | |
//-------------------------------- | |
// PBR functions | |
//-------------------------------- | |
// Note: Disney diffuse must be multiply by diffuseAlbedo / PI. This is done outside of this function. | |
half DisneyDiffuse(half NdotV, half NdotL, half LdotH, half perceptualRoughness) | |
{ | |
half fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness; | |
// Two schlick fresnel term | |
half lightScatter = (1 + (fd90 - 1) * Pow5(1 - NdotL)); | |
half viewScatter = (1 + (fd90 - 1) * Pow5(1 - NdotV)); | |
return lightScatter * viewScatter; | |
} | |
// NDF | |
inline float GGXTerm(float NdotH, float roughness) | |
{ | |
float a2 = roughness * roughness; | |
float d = (NdotH * a2 - NdotH) * NdotH + 1.0f; // 2 mad | |
return UNITY_INV_PI * a2 / (d * d + 1e-7f); // This function is not intended to be running on Mobile, | |
// therefore epsilon is smaller than what can be represented by half | |
} | |
// Visibility | |
inline float SmithJointGGXVisibilityTerm(float NdotL, float NdotV, float roughness) | |
{ | |
float a = roughness; | |
float lambdaV = NdotL * (NdotV * (1 - a) + a); | |
float lambdaL = NdotV * (NdotL * (1 - a) + a); | |
return 0.5f / (lambdaV + lambdaL + 1e-5f); | |
} | |
inline half3 FresnelTerm(half3 F0, half cosA) | |
{ | |
half t = Pow5(1 - cosA); // ala Schlick interpoliation | |
return F0 + (1 - F0) * t; | |
} | |
inline half3 FresnelLerp(half3 F0, half3 F90, half cosA) | |
{ | |
half t = Pow5(1 - cosA); // ala Schlick interpoliation | |
return lerp(F0, F90, t); | |
} | |
half4 BRDF(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness, | |
float3 normal, float3 viewDir, | |
UnityLight light) | |
{ | |
float perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness); | |
float3 halfDir = Unity_SafeNormalize(float3(light.dir) + viewDir); | |
half nv = abs(dot(normal, viewDir)); // This abs allow to limit artifact | |
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; | |
// 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); | |
// 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); | |
float specularTerm = V * D * UNITY_PI; // Torrance-Sparrow model, Fresnel is applied later | |
// 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 | |
// 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 * (light.color * diffuseTerm) + specularTerm * light.color * FresnelTerm(specColor, lh); | |
return half4(color, 1); | |
} | |
//------------------------------ | |
// GI diffuse | |
//----------------------------- | |
half3 ShadeSHPerVertex(half3 normal, half3 ambient) | |
{ | |
#if UNITY_SAMPLE_FULL_SH_PER_PIXEL | |
// Completely per-pixel | |
// nothing to do here | |
#elif (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE | |
// Completely per-vertex | |
ambient += max(half3(0, 0, 0), ShadeSH9(half4(normal, 1.0))); | |
#else | |
// L2 per-vertex, L0..L1 & gamma-correction per-pixel | |
// NOTE: SH data is always in Linear AND calculation is split between vertex & pixel | |
// Convert ambient to Linear and do final gamma-correction at the end (per-pixel) | |
#ifdef UNITY_COLORSPACE_GAMMA | |
ambient = GammaToLinearSpace (ambient); | |
#endif | |
ambient += SHEvalLinearL2 (half4(normal, 1.0)); // no max since this is only L2 contribution | |
#endif | |
return ambient; | |
} | |
half3 ShadeSHPerPixel(half3 normal, half3 ambient, float3 worldPos) | |
{ | |
half3 ambient_contrib = 0.0; | |
#if UNITY_SAMPLE_FULL_SH_PER_PIXEL | |
// Completely per-pixel | |
#if UNITY_LIGHT_PROBE_PROXY_VOLUME | |
if (unity_ProbeVolumeParams.x == 1.0) | |
ambient_contrib = SHEvalLinearL0L1_SampleProbeVolume(half4(normal, 1.0), worldPos); | |
else | |
ambient_contrib = SHEvalLinearL0L1(half4(normal, 1.0)); | |
#else | |
ambient_contrib = SHEvalLinearL0L1(half4(normal, 1.0)); | |
#endif | |
ambient_contrib += SHEvalLinearL2(half4(normal, 1.0)); | |
ambient += max(half3(0, 0, 0), ambient_contrib); | |
#else | |
// L2 per-vertex, L0..L1 & gamma-correction per-pixel | |
// Ambient in this case is expected to be always Linear, see ShadeSHPerVertex() | |
#if UNITY_LIGHT_PROBE_PROXY_VOLUME | |
if (unity_ProbeVolumeParams.x == 1.0) | |
ambient_contrib = SHEvalLinearL0L1_SampleProbeVolume (half4(normal, 1.0), worldPos); | |
else | |
ambient_contrib = SHEvalLinearL0L1 (half4(normal, 1.0)); | |
#else | |
ambient_contrib = SHEvalLinearL0L1(half4(normal, 1.0)); | |
#endif | |
ambient = max(half3(0, 0, 0), ambient + ambient_contrib); // include L2 contribution in vertex shader before clamp. | |
#endif | |
return ambient; | |
} | |
//-------------------- | |
half3 GI_diffuse(half3 diffColor, float3 worldPos, half3 normal, half4 ambientOrLightmapUV, half atten, half occlusion) | |
{ | |
half3 diffuse; | |
// SH | |
#if UNITY_SHOULD_SAMPLE_SH | |
diffuse = ShadeSHPerPixel(normal, ambientOrLightmapUV.rgb, worldPos); | |
#endif | |
// Baked lightmaps | |
#if defined(LIGHTMAP_ON) | |
float2 lightmapUV = ambientOrLightmapUV.xy; | |
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, lightmapUV); | |
half3 bakedColor = DecodeLightmap(bakedColorTex); | |
// directional mode | |
#ifdef DIRLIGHTMAP_COMBINED | |
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, lightmapUV); | |
diffuse += DecodeDirectionalLightmap (bakedColor, bakedDirTex, normal); | |
#else // not directional lightmap | |
diffuse += bakedColor; | |
#endif | |
#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) | |
diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap (diffuse, atten, bakedColorTex, normal); | |
#endif | |
#endif // LIGHTMAP_ON | |
// Dynamic lightmaps | |
#ifdef DYNAMICLIGHTMAP_ON | |
float2 dynamicLightmapUV = lightmapUV.zw; | |
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, dynamicLightmapUV); | |
half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex); | |
#ifdef DIRLIGHTMAP_COMBINED | |
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, dynamicLightmapUV); | |
diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normal); | |
#else | |
diffuse += realtimeColor; | |
#endif | |
#endif // DYNAMICLIGHTMAP_ON | |
diffuse *= occlusion; | |
return diffuse * diffColor; | |
} | |
//---------------------------- | |
// GI Specular | |
//---------------------------- | |
half3 Unity_GlossyEnvironment(UNITY_ARGS_TEXCUBE(tex), half4 hdr, half perceptualRoughness, half3 reflUVW) | |
{ | |
perceptualRoughness = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness); | |
// perceptual roughness to mipmap level | |
half mip = perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS; | |
half3 R = reflUVW; | |
half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, R, mip); | |
return DecodeHDR(rgbm, hdr); | |
} | |
inline float3 BoxProjectedCubemapDirection(float3 worldRefl, float3 worldPos, float4 cubemapCenter, float4 boxMin, float4 boxMax) | |
{ | |
// Do we have a valid reflection probe? | |
UNITY_BRANCH | |
if (cubemapCenter.w > 0.0) | |
{ | |
float3 nrdir = normalize(worldRefl); | |
#if 1 | |
float3 rbmax = (boxMax.xyz - worldPos) / nrdir; | |
float3 rbmin = (boxMin.xyz - worldPos) / nrdir; | |
float3 rbminmax = (nrdir > 0.0f) ? rbmax : rbmin; | |
#else // Optimized version | |
float3 rbmax = (boxMax.xyz - worldPos); | |
float3 rbmin = (boxMin.xyz - worldPos); | |
float3 select = step (float3(0,0,0), nrdir); | |
float3 rbminmax = lerp (rbmax, rbmin, select); | |
rbminmax /= nrdir; | |
#endif | |
float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); | |
worldPos -= cubemapCenter.xyz; | |
worldRefl = worldPos + nrdir * fa; | |
} | |
return worldRefl; | |
} | |
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, half perceptualRoughness, half3 reflUVW) | |
{ | |
half3 specular; | |
#ifdef UNITY_SPECCUBE_BOX_PROJECTION | |
// we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice for probe0 and probe1), so keep original to pass into BoxProjectedCubemapDirection | |
half3 originalReflUVW = reflUVW; | |
reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]); | |
#endif | |
#ifdef _GLOSSYREFLECTIONS_OFF | |
specular = unity_IndirectSpecColor.rgb; | |
#else | |
half peceptualRoughness = perceptualRoughness; | |
half3 env0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], peceptualRoughness, reflUVW); | |
#ifdef UNITY_SPECCUBE_BLENDING | |
const float kBlendFactor = 0.99999; | |
float blendLerp = data.boxMin[0].w; | |
UNITY_BRANCH | |
if (blendLerp < kBlendFactor) | |
{ | |
#ifdef UNITY_SPECCUBE_BOX_PROJECTION | |
reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[1], data.boxMin[1], data.boxMax[1]); | |
#endif | |
half3 env1 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0), data.probeHDR[1], peceptualRoughness, reflUVW); | |
specular = lerp(env1, env0, blendLerp); | |
} | |
else | |
{ | |
specular = env0; | |
} | |
#else | |
specular = env0; | |
#endif | |
#endif | |
return specular * occlusion; | |
} | |
half3 GI_specular(half3 specColor, half smoothness, half percepstualRoughness, half roughness, half3 normal, half3 view, half nv, half occlusion, half oneMinusReflectivity) | |
{ | |
half3 specular; | |
half3 reflUVW = reflect(-view, normal); | |
UnityGIInput d; | |
d.probeHDR[0] = unity_SpecCube0_HDR; | |
d.probeHDR[1] = unity_SpecCube1_HDR; | |
#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) | |
d.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending | |
#endif | |
#ifdef UNITY_SPECCUBE_BOX_PROJECTION | |
d.boxMax[0] = unity_SpecCube0_BoxMax; | |
d.probePosition[0] = unity_SpecCube0_ProbePosition; | |
d.boxMax[1] = unity_SpecCube1_BoxMax; | |
d.boxMin[1] = unity_SpecCube1_BoxMin; | |
d.probePosition[1] = unity_SpecCube1_ProbePosition; | |
#endif | |
// reflection probes and ambient reflection | |
half3 gi_specular = UnityGI_IndirectSpecular(d, occlusion, percepstualRoughness, reflUVW); | |
half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity)); | |
half surfaceReduction = 1.0 / (roughness * roughness + 1.0); // fade \in [0.5;1] | |
return surfaceReduction * gi_specular * FresnelLerp(specColor, grazingTerm, nv); | |
} | |
//-------------------------------------------- | |
// vertex function | |
//-------------------------------------------- | |
VertexOutputForwardBase vertBase(VertexInput v) | |
{ | |
UNITY_SETUP_INSTANCE_ID(v); | |
VertexOutputForwardBase o; | |
UNITY_INITIALIZE_OUTPUT(VertexOutputForwardBase, o); | |
UNITY_TRANSFER_INSTANCE_ID(v, o); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); | |
float3 posWorld = mul(unity_ObjectToWorld, v.vertex); | |
// world position | |
#if UNITY_REQUIRE_FRAG_WORLDPOS | |
#if UNITY_PACK_WORLDPOS_WITH_TANGENT | |
o.tangentToWorldAndPackedData[0].w = posWorld.x; | |
o.tangentToWorldAndPackedData[1].w = posWorld.y; | |
o.tangentToWorldAndPackedData[2].w = posWorld.z; | |
#else | |
o.posWorld = posWorld; | |
#endif | |
#endif | |
// clip position | |
o.pos = UnityObjectToClipPos(v.vertex); | |
// uv | |
o.tex = TexCoords(v); | |
o.eyeVec.xyz = posWorld.xyz - _WorldSpaceCameraPos; | |
// normal | |
float3 normalWorld = UnityObjectToWorldNormal(v.normal); | |
#ifdef _TANGENT_TO_WORLD | |
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); | |
float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); | |
o.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0]; | |
o.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1]; | |
o.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2]; | |
#else | |
o.tangentToWorldAndPackedData[0].xyz = 0; | |
o.tangentToWorldAndPackedData[1].xyz = 0; | |
o.tangentToWorldAndPackedData[2].xyz = normalWorld; | |
#endif | |
// light coord and shadow coord (AutoLight.cginc) | |
UNITY_TRANSFER_LIGHTING(o, v.uv1); | |
// ambient and lightmap uv | |
half4 ambientOrLightmapUV = 0; | |
#ifdef LIGHTMAP_ON | |
ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw; | |
ambientOrLightmapUV.zw = 0; | |
#elif UNITY_SHOULD_SAMPLE_SH | |
#ifdef VERTEXLIGHT_ON | |
// Approximated illumination from non-important point lights | |
ambientOrLightmapUV.rgb = Shade4PointLights ( | |
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, | |
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, | |
unity_4LightAtten0, posWorld, normalWorld); | |
#endif | |
ambientOrLightmapUV.rgb = ShadeSHPerVertex (normalWorld, ambientOrLightmapUV.rgb); | |
#endif | |
// realtime gi | |
#ifdef DYNAMICLIGHTMAP_ON | |
ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; | |
#endif | |
o.ambientOrLightmapUV = ambientOrLightmapUV; | |
// parallax | |
#ifdef _PARALLAXMAP | |
TANGENT_SPACE_ROTATION; | |
half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex)); | |
o.tangentToWorldAndPackedData[0].w = viewDirForParallax.x; | |
o.tangentToWorldAndPackedData[1].w = viewDirForParallax.y; | |
o.tangentToWorldAndPackedData[2].w = viewDirForParallax.z; | |
#endif | |
// fog | |
UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o,o.pos); | |
return o; | |
} | |
//-------------------------------------------- | |
// fragment function | |
//-------------------------------------------- | |
fixed4 fragBase(VertexOutputForwardBase i) : SV_Target | |
{ | |
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy); | |
// uv | |
float4 i_tex = i.tex; | |
// parallax | |
i_tex = Parallax(i_tex, IN_VIEWDIR4PARALLAX(i)); | |
// alpha | |
half alpha = Alpha(i_tex.xy); | |
// alpha test | |
#if defined(_ALPHATEST_ON) | |
clip (alpha - _Cutoff); | |
#endif | |
// p, n, v | |
float3 worldPos = IN_WORLDPOS(i); | |
half3 normal = PerPixelWorldNormal(i_tex, i.tangentToWorldAndPackedData); | |
half3 eyeVec = normalize(i.eyeVec.xyz); | |
half3 view = -eyeVec; | |
half nv = max(0, dot(normal, view)); | |
// surface data | |
half2 metallicGloss = MetallicGloss(i_tex.xy); | |
half metallic = metallicGloss.x; | |
half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m. | |
half perceptualRoughness = 1 - smoothness; | |
half roughness = perceptualRoughness * perceptualRoughness; | |
half oneMinusReflectivity; | |
half3 specColor; | |
half3 diffColor = DiffuseAndSpecularFromMetallic(Albedo(i_tex), metallic, /*out*/specColor, /*out*/oneMinusReflectivity); | |
// NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha) | |
diffColor = PreMultiplyAlpha(diffColor, alpha, oneMinusReflectivity, /*out*/alpha); | |
UNITY_SETUP_INSTANCE_ID(i); | |
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); | |
// occlusion | |
half occlusion = tex2D(_OcclusionMap, i.tex.xy).g; | |
occlusion = LerpOneTo(occlusion, _OcclusionStrength); | |
// shadowing | |
UNITY_LIGHT_ATTENUATION(atten, i, worldPos); | |
// GI | |
half3 gi_diffuse = GI_diffuse(diffColor, worldPos, normal, i.ambientOrLightmapUV, atten, occlusion); | |
half3 gi_specular = GI_specular(specColor, smoothness, perceptualRoughness, roughness, normal, view, nv, occlusion, oneMinusReflectivity); | |
// main directional light | |
UnityLight mainLight; | |
#if defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) | |
mainLight.color = half3(0, 0, 0); | |
mainLight.dir = half3(0, 1, 0); | |
#else | |
mainLight.color = _LightColor0.rgb * atten; | |
mainLight.dir = _WorldSpaceLightPos0.xyz; | |
#endif | |
// brdf | |
half4 output = BRDF(diffColor, specColor, oneMinusReflectivity, smoothness, normal, view, mainLight); | |
// emission | |
output.rgb += Emission(i.tex.xy); | |
// fog | |
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i); | |
UNITY_APPLY_FOG(_unity_fogCoord, c.rgb); | |
// alpha | |
#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON) | |
output.a = s.alpha; | |
#else | |
output.a = 1; | |
#endif | |
return output; | |
} | |
// ------------------------------------------------------------------ | |
// Additive forward pass (one light per pass) | |
struct VertexOutputForwardAdd | |
{ | |
UNITY_POSITION(pos); | |
float4 tex : TEXCOORD0; | |
float4 eyeVec : TEXCOORD1; // eyeVec.xyz | fogCoord | |
float4 tangentToWorldAndLightDir[3] : TEXCOORD2; // [3x3:tangentToWorld | 1x3:lightDir] | |
float3 posWorld : TEXCOORD5; | |
UNITY_LIGHTING_COORDS(6, 7) | |
// next ones would not fit into SM2.0 limits, but they are always for SM3.0+ | |
#if defined(_PARALLAXMAP) | |
half3 viewDirForParallax : TEXCOORD8; | |
#endif | |
UNITY_VERTEX_OUTPUT_STEREO | |
}; | |
VertexOutputForwardAdd vertAdd(VertexInput v) | |
{ | |
UNITY_SETUP_INSTANCE_ID(v); | |
VertexOutputForwardAdd o; | |
UNITY_INITIALIZE_OUTPUT(VertexOutputForwardAdd, o); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); | |
float4 posWorld = mul(unity_ObjectToWorld, v.vertex); | |
o.pos = UnityObjectToClipPos(v.vertex); | |
o.tex = TexCoords(v); | |
o.eyeVec.xyz = posWorld.xyz - _WorldSpaceCameraPos; | |
o.posWorld = posWorld.xyz; | |
float3 normalWorld = UnityObjectToWorldNormal(v.normal); | |
#ifdef _TANGENT_TO_WORLD | |
float4 tangentWorld = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); | |
float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld.xyz, tangentWorld.w); | |
o.tangentToWorldAndLightDir[0].xyz = tangentToWorld[0]; | |
o.tangentToWorldAndLightDir[1].xyz = tangentToWorld[1]; | |
o.tangentToWorldAndLightDir[2].xyz = tangentToWorld[2]; | |
#else | |
o.tangentToWorldAndLightDir[0].xyz = 0; | |
o.tangentToWorldAndLightDir[1].xyz = 0; | |
o.tangentToWorldAndLightDir[2].xyz = normalWorld; | |
#endif | |
//We need this for shadow receiving and lighting | |
UNITY_TRANSFER_LIGHTING(o, v.uv1); | |
float3 lightDir = _WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w; | |
o.tangentToWorldAndLightDir[0].w = lightDir.x; | |
o.tangentToWorldAndLightDir[1].w = lightDir.y; | |
o.tangentToWorldAndLightDir[2].w = lightDir.z; | |
#ifdef _PARALLAXMAP | |
TANGENT_SPACE_ROTATION; | |
o.viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex)); | |
#endif | |
UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o, o.pos); | |
return o; | |
} | |
half4 fragAdd(VertexOutputForwardAdd i) : SV_Target // backward compatibility (this used to be the fragment entry function) | |
{ | |
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy); | |
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); | |
// uv | |
float4 i_tex = i.tex; | |
// parallax | |
i_tex = Parallax(i_tex, IN_VIEWDIR4PARALLAX_FWDADD(i)); | |
// alpha | |
half alpha = Alpha(i_tex.xy); | |
// p, n, v | |
float3 worldPos = IN_WORLDPOS_FWDADD(i); | |
half3 normal = PerPixelWorldNormal(i_tex, i.tangentToWorldAndLightDir); | |
half3 eyeVec = normalize(i.eyeVec.xyz); | |
half3 view = -eyeVec; | |
half nv = max(0, dot(normal, view)); | |
// surface data | |
half2 metallicGloss = MetallicGloss(i_tex.xy); | |
half metallic = metallicGloss.x; | |
half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m. | |
half perceptualRoughness = 1 - smoothness; | |
half roughness = perceptualRoughness * perceptualRoughness; | |
half oneMinusReflectivity; | |
half3 specColor; | |
half3 diffColor = DiffuseAndSpecularFromMetallic(Albedo(i_tex), metallic, /*out*/specColor, /*out*/oneMinusReflectivity); | |
// NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha) | |
diffColor = PreMultiplyAlpha(diffColor, alpha, oneMinusReflectivity, /*out*/alpha); | |
// shadow | |
UNITY_LIGHT_ATTENUATION(atten, i, worldPos) | |
// additional light | |
UnityLight light; | |
light.color = _LightColor0.rgb; | |
light.dir = IN_LIGHTDIR_FWDADD(i); | |
#ifndef USING_DIRECTIONAL_LIGHT | |
light.dir = normalize(light.dir); | |
#endif | |
light.color *= atten; | |
half4 output = BRDF(diffColor, specColor, oneMinusReflectivity, smoothness, normal, view, light); | |
// fog | |
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i); | |
UNITY_APPLY_FOG_COLOR(_unity_fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass | |
// alpha | |
#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON) | |
output.a = s.alpha; | |
#else | |
output.a = 1; | |
#endif | |
return output; | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copyright(c) 2016 Unity Technologies | |
Permission is hereby granted, free of charge, to any person obtaining a copy of | |
this software and associated documentation files(the "Software"), to deal in | |
the Software without restriction, including without limitation the rights to | |
use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies | |
of the Software, and to permit persons to whom the Software is furnished to do | |
so, subject to the following conditions : | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR | |
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
Shader "TKMNY/StandardVariant" | |
{ | |
Properties | |
{ | |
_Color("Color", Color) = (1,1,1,1) | |
_MainTex("Albedo", 2D) = "white" {} | |
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 | |
_Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 | |
_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 | |
[Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 | |
[Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 | |
_MetallicGlossMap("Metallic", 2D) = "white" {} | |
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 | |
[ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0 | |
_BumpScale("Scale", Float) = 1.0 | |
_BumpMap("Normal Map", 2D) = "bump" {} | |
_Parallax("Height Scale", Range(0.005, 0.08)) = 0.02 | |
_ParallaxMap("Height Map", 2D) = "black" {} | |
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 | |
_OcclusionMap("Occlusion", 2D) = "white" {} | |
_EmissionColor("Color", Color) = (0,0,0) | |
_EmissionMap("Emission", 2D) = "white" {} | |
_DetailMask("Detail Mask", 2D) = "white" {} | |
_DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {} | |
_DetailNormalMapScale("Scale", Float) = 1.0 | |
_DetailNormalMap("Normal Map", 2D) = "bump" {} | |
[Enum(UV0,0,UV1,1)] _UVSec("UV Set for secondary textures", Float) = 0 | |
// Blending state | |
[HideInInspector] _Mode("__mode", Float) = 0.0 | |
[HideInInspector] _SrcBlend("__src", Float) = 1.0 | |
[HideInInspector] _DstBlend("__dst", Float) = 0.0 | |
[HideInInspector] _ZWrite("__zw", Float) = 1.0 | |
} | |
CGINCLUDE | |
#define UNITY_SETUP_BRDF_INPUT MetallicSetup | |
ENDCG | |
SubShader | |
{ | |
Tags { "RenderType" = "Opaque" "PerformanceChecks" = "False" } | |
LOD 300 | |
Pass | |
{ | |
Name "FORWARD" | |
Tags { "LightMode" = "ForwardBase" } | |
Blend[_SrcBlend][_DstBlend] | |
ZWrite[_ZWrite] | |
CGPROGRAM | |
#pragma target 3.0 | |
#pragma shader_feature _NORMALMAP | |
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON | |
#pragma shader_feature _EMISSION | |
#pragma shader_feature _METALLICGLOSSMAP | |
#pragma shader_feature ___ _DETAIL_MULX2 | |
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF | |
#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF | |
#pragma shader_feature _PARALLAXMAP | |
#pragma shader_feature _KANIKAMA_MODE_SINGLE _KANIKAMA_MODE_ARRAY _KANIKAMA_MODE_DIRECTIONAL | |
#pragma multi_compile_fwdbase | |
#pragma multi_compile_fog | |
#pragma multi_compile_instancing | |
#pragma vertex vertBase | |
#pragma fragment fragBase | |
#include <StandardVariant.hlsl> | |
ENDCG | |
} | |
Pass | |
{ | |
Name "FORWARD_DELTA" | |
Tags { "LightMode" = "ForwardAdd" } | |
Blend[_SrcBlend] One | |
Fog { Color(0,0,0,0) } // in additive pass fog should be black | |
ZWrite Off | |
ZTest LEqual | |
CGPROGRAM | |
#pragma target 3.0 | |
#pragma shader_feature _NORMALMAP | |
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON | |
#pragma shader_feature _METALLICGLOSSMAP | |
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF | |
#pragma shader_feature ___ _DETAIL_MULX2 | |
#pragma shader_feature _PARALLAXMAP | |
#pragma multi_compile_fwdadd_fullshadows | |
#pragma multi_compile_fog | |
#pragma vertex vertBase | |
#pragma fragment fragBase | |
#include <StandardVariant.hlsl> | |
ENDCG | |
} | |
Pass | |
{ | |
Name "ShadowCaster" | |
Tags { "LightMode" = "ShadowCaster" } | |
ZWrite On ZTest LEqual | |
CGPROGRAM | |
#pragma target 3.0 | |
#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON | |
#pragma shader_feature _METALLICGLOSSMAP | |
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma shader_feature _PARALLAXMAP | |
#pragma multi_compile_shadowcaster | |
#pragma multi_compile_instancing | |
#pragma vertex vertShadowCaster | |
#pragma fragment fragShadowCaster | |
#include "UnityStandardShadow.cginc" | |
ENDCG | |
} | |
Pass | |
{ | |
Name "META" | |
Tags { "LightMode" = "Meta" } | |
Cull Off | |
CGPROGRAM | |
#pragma vertex vert_meta | |
#pragma fragment frag_meta | |
#pragma shader_feature _EMISSION | |
#pragma shader_feature _METALLICGLOSSMAP | |
#pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A | |
#pragma shader_feature ___ _DETAIL_MULX2 | |
#pragma shader_feature EDITOR_VISUALIZATION | |
#include "UnityStandardMeta.cginc" | |
ENDCG | |
} | |
} | |
FallBack "VertexLit" | |
CustomEditor "StandardShaderGUI" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment