Added terrain and basic terrain textures
This commit is contained in:
715
Assets/Filamented/UnityStandardCore.cginc
Normal file
715
Assets/Filamented/UnityStandardCore.cginc
Normal file
@ -0,0 +1,715 @@
|
||||
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
|
||||
|
||||
#ifndef UNITY_STANDARD_CORE_INCLUDED
|
||||
#define UNITY_STANDARD_CORE_INCLUDED
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityShaderVariables.cginc"
|
||||
#include "UnityLightingCommon.cginc"
|
||||
|
||||
// Workaround for some failsafes
|
||||
#define UNITY_BRDF_PBS
|
||||
|
||||
#include "FilamentMaterialInputs.cginc"
|
||||
#include "FilamentCommonMath.cginc"
|
||||
#include "FilamentCommonLighting.cginc"
|
||||
#include "FilamentCommonMaterial.cginc"
|
||||
#include "FilamentCommonShading.cginc"
|
||||
#include "FilamentShadingParameters.cginc"
|
||||
|
||||
#include "UnityStandardConfig.cginc"
|
||||
#include "UnityStandardInput.cginc"
|
||||
//#include "UnityPBSLighting.cginc"
|
||||
#include "UnityStandardUtils.cginc"
|
||||
#include "UnityImageBasedLightingMinimal.cginc"
|
||||
#include "UnityGBuffer.cginc"
|
||||
#include "UnityGlobalIllumination.cginc"
|
||||
|
||||
#include "FilamentShadingLit.cginc"
|
||||
|
||||
#include "SharedFilteringLib.hlsl"
|
||||
// Note: AutoLight.cginc is included below.
|
||||
//-------------------------------------------------------------------------------------
|
||||
// counterpart for NormalizePerPixelNormal
|
||||
// skips normalization per-vertex and expects normalization to happen per-pixel
|
||||
half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow
|
||||
{
|
||||
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
|
||||
return normalize(n);
|
||||
#else
|
||||
return n; // will normalize per-pixel instead
|
||||
#endif
|
||||
}
|
||||
|
||||
float3 NormalizePerPixelNormal (float3 n)
|
||||
{
|
||||
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
|
||||
return n;
|
||||
#else
|
||||
return normalize((float3)n); // takes float to avoid overflow
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
fixed4 SampleShadowMaskBicubic(float2 uv)
|
||||
{
|
||||
#if defined(SHADER_API_D3D11)
|
||||
float width, height;
|
||||
unity_ShadowMask.GetDimensions(width, height);
|
||||
|
||||
float4 unity_ShadowMask_TexelSize = float4(width, height, 1.0/width, 1.0/height);
|
||||
|
||||
return SampleTexture2DBicubicFilter(TEXTURE2D_ARGS(unity_ShadowMask, samplerunity_ShadowMask),
|
||||
uv, unity_ShadowMask_TexelSize);
|
||||
#else
|
||||
return SAMPLE_TEXTURE2D(unity_ShadowMask, samplerunity_ShadowMask, uv);
|
||||
#endif
|
||||
}
|
||||
fixed UnitySampleBakedOcclusionBicubic (float2 lightmapUV, float3 worldPos)
|
||||
{
|
||||
#if defined (SHADOWS_SHADOWMASK)
|
||||
#if defined(LIGHTMAP_ON)
|
||||
fixed4 rawOcclusionMask = SampleShadowMaskBicubic(lightmapUV.xy);
|
||||
#else
|
||||
fixed4 rawOcclusionMask = fixed4(1.0, 1.0, 1.0, 1.0);
|
||||
#if UNITY_LIGHT_PROBE_PROXY_VOLUME
|
||||
if (unity_ProbeVolumeParams.x == 1.0)
|
||||
rawOcclusionMask = LPPV_SampleProbeOcclusion(worldPos);
|
||||
else
|
||||
rawOcclusionMask = SampleShadowMaskBicubic(lightmapUV.xy);
|
||||
#else
|
||||
rawOcclusionMask = SampleShadowMaskBicubic(lightmapUV.xy);
|
||||
#endif
|
||||
#endif
|
||||
return saturate(dot(rawOcclusionMask, unity_OcclusionMaskSelector));
|
||||
|
||||
#else
|
||||
|
||||
//In forward dynamic objects can only get baked occlusion from LPPV, light probe occlusion is done on the CPU by attenuating the light color.
|
||||
fixed atten = 1.0f;
|
||||
#if defined(UNITY_INSTANCING_ENABLED) && defined(UNITY_USE_SHCOEFFS_ARRAYS)
|
||||
// ...unless we are doing instancing, and the attenuation is packed into SHC array's .w component.
|
||||
atten = unity_SHC.w;
|
||||
#endif
|
||||
|
||||
#if UNITY_LIGHT_PROBE_PROXY_VOLUME && !defined(LIGHTMAP_ON) && !UNITY_STANDARD_SIMPLE
|
||||
fixed4 rawOcclusionMask = atten.xxxx;
|
||||
if (unity_ProbeVolumeParams.x == 1.0)
|
||||
rawOcclusionMask = LPPV_SampleProbeOcclusion(worldPos);
|
||||
return saturate(dot(rawOcclusionMask, unity_OcclusionMaskSelector));
|
||||
#endif
|
||||
|
||||
return atten;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetBakedAttenuation(inout float atten, float2 lightmapUV, float3 worldPos)
|
||||
{
|
||||
// Base pass with Lightmap support is responsible for handling ShadowMask / blending here for performance reason
|
||||
#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
|
||||
half bakedAtten = UnitySampleBakedOcclusionBicubic(lightmapUV.xy, worldPos);
|
||||
float zDist = dot(_WorldSpaceCameraPos - worldPos, UNITY_MATRIX_V[2].xyz);
|
||||
float fadeDist = UnityComputeShadowFadeDistance(worldPos, zDist);
|
||||
atten = UnityMixRealtimeAndBakedShadows(atten, bakedAtten, UnityComputeShadowFade(fadeDist));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define UnitySampleBakedOcclusion UnitySampleBakedOcclusionBicubic
|
||||
#include "AutoLight.cginc"
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Common fragment setup
|
||||
|
||||
#ifdef _PARALLAXMAP
|
||||
#define IN_VIEWDIR4PARALLAX(i) NormalizePerPixelNormal(half3(i.tangentToWorldAndPackedData[0].w,i.tangentToWorldAndPackedData[1].w,i.tangentToWorldAndPackedData[2].w))
|
||||
#define IN_VIEWDIR4PARALLAX_FWDADD(i) NormalizePerPixelNormal(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 IN_LIGHTDIR_FWDADD(i) half3(i.tangentToWorldAndLightDir[0].w, i.tangentToWorldAndLightDir[1].w, i.tangentToWorldAndLightDir[2].w)
|
||||
|
||||
#define MATERIAL_SETUP(x) MaterialInputs x = \
|
||||
MaterialSetup(i.tex, i.eyeVec.xyz, IN_VIEWDIR4PARALLAX(i), i.tangentToWorldAndPackedData, IN_WORLDPOS(i));
|
||||
|
||||
#define MATERIAL_SETUP_FWDADD(x) MaterialInputs x = \
|
||||
MaterialSetup(i.tex, i.eyeVec.xyz, IN_VIEWDIR4PARALLAX_FWDADD(i), i.tangentToWorldAndLightDir, IN_WORLDPOS_FWDADD(i));
|
||||
|
||||
#if !defined(SKIP_UNITY_STANDARD_INPUT_DEFINES)
|
||||
#if defined(SHADING_MODEL_CLOTH)
|
||||
#define SETUP_BRDF_INPUT ClothMaterialSetup
|
||||
inline MaterialInputs ClothMaterialSetup (float4 i_tex)
|
||||
{
|
||||
half4 baseColor = half4(Albedo(i_tex), Alpha(i_tex));
|
||||
half4 specGloss = SheenColorGlossCloth(i_tex.xy);
|
||||
half3 specColor = specGloss.rgb;
|
||||
half smoothness = specGloss.a;
|
||||
|
||||
MaterialInputs material = (MaterialInputs)0;
|
||||
initMaterial(material);
|
||||
material.baseColor = baseColor;
|
||||
#if defined(MATERIAL_HAS_SHEEN_COLOR)
|
||||
material.sheenColor = specColor;
|
||||
#endif
|
||||
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
|
||||
material.glossiness = smoothness;
|
||||
#else
|
||||
material.roughness = computeRoughnessFromGlossiness(smoothness);
|
||||
#endif
|
||||
return material;
|
||||
}
|
||||
#else
|
||||
|
||||
// Filament's preferred model, but not Unity's default
|
||||
#if defined(SHADING_MODEL_METALLIC_ROUGHNESS)
|
||||
#define SETUP_BRDF_INPUT RoughnessMaterialSetup
|
||||
inline MaterialInputs RoughnessMaterialSetup (float4 i_tex)
|
||||
{
|
||||
half4 baseColor = half4(Albedo(i_tex), Alpha(i_tex));
|
||||
half2 metallicGloss = MetallicRough(i_tex.xy);
|
||||
half metallic = metallicGloss.x;
|
||||
half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.
|
||||
|
||||
MaterialInputs material = (MaterialInputs)0;
|
||||
initMaterial(material);
|
||||
material.baseColor = baseColor;
|
||||
material.metallic = metallic;
|
||||
material.roughness = computeRoughnessFromGlossiness(smoothness);
|
||||
return material;
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
|
||||
#define SETUP_BRDF_INPUT SpecularMaterialSetup
|
||||
inline MaterialInputs SpecularMaterialSetup (float4 i_tex)
|
||||
{
|
||||
half4 baseColor = half4(Albedo(i_tex), Alpha(i_tex));
|
||||
half4 specGloss = SpecularGloss(i_tex.xy);
|
||||
half3 specColor = specGloss.rgb;
|
||||
half smoothness = specGloss.a;
|
||||
|
||||
MaterialInputs material = (MaterialInputs)0;
|
||||
initMaterial(material);
|
||||
material.baseColor = baseColor;
|
||||
material.specularColor = specColor;
|
||||
material.glossiness = smoothness;
|
||||
return material;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (!defined(SHADING_MODEL_SPECULAR_GLOSSINESS))
|
||||
#define SETUP_BRDF_INPUT MetallicMaterialSetup
|
||||
inline MaterialInputs MetallicMaterialSetup (float4 i_tex)
|
||||
{
|
||||
half4 baseColor = half4(Albedo(i_tex), Alpha(i_tex));
|
||||
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.
|
||||
|
||||
MaterialInputs material = (MaterialInputs)0;
|
||||
initMaterial(material);
|
||||
material.baseColor = baseColor;
|
||||
material.metallic = metallic;
|
||||
material.roughness = computeRoughnessFromGlossiness(smoothness);
|
||||
return material;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SETUP_BRDF_INPUT
|
||||
#define SETUP_BRDF_INPUT NoneMaterialSetup
|
||||
#endif
|
||||
|
||||
inline MaterialInputs NoneMaterialSetup (float4 i_tex)
|
||||
{
|
||||
MaterialInputs material = (MaterialInputs)0;
|
||||
initMaterial(material);
|
||||
return material;
|
||||
}
|
||||
|
||||
// parallax transformed texcoord is used to sample occlusion
|
||||
inline MaterialInputs MaterialSetup (inout float4 i_tex, float3 i_eyeVec, half3 i_viewDirForParallax, float4 tangentToWorld[3], float3 i_posWorld)
|
||||
{
|
||||
#if defined(SKIP_UNITY_STANDARD_INPUT_DEFINES)
|
||||
MaterialInputs material = SETUP_BRDF_INPUT (i_tex);
|
||||
return material;
|
||||
#else
|
||||
float3 viewDirWS = -normalize(i_posWorld - _WorldSpaceCameraPos);
|
||||
float3 normalWS = normalize(tangentToWorld[2]); // normalize to avoid weird values
|
||||
float parallaxLod = dot(normalWS, viewDirWS);
|
||||
|
||||
#if !defined(PARALLAX_CUSTOM_INPUT)
|
||||
i_tex = Parallax(i_tex, i_viewDirForParallax, parallaxLod);
|
||||
#endif
|
||||
|
||||
MaterialInputs material = SETUP_BRDF_INPUT (i_tex);
|
||||
|
||||
// Added tangent output
|
||||
#if _NORMALMAP
|
||||
material.normal = NormalInTangentSpace(i_tex);
|
||||
#endif
|
||||
#if _EMISSION
|
||||
material.emissive.rgb = Emission (i_tex);
|
||||
material.emissive.a = 1.0;
|
||||
#endif
|
||||
material.ambientOcclusion = Occlusion(i_tex);
|
||||
return material;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline half4 VertexGIForward(VertexInput v, float3 posWorld, half3 normalWorld)
|
||||
{
|
||||
half4 ambientOrLightmapUV = 0;
|
||||
// Static lightmaps
|
||||
#ifdef LIGHTMAP_ON
|
||||
ambientOrLightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
|
||||
ambientOrLightmapUV.zw = 0;
|
||||
// Sample light probe for Dynamic objects only (no static or dynamic lightmaps)
|
||||
#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
|
||||
|
||||
#ifdef DYNAMICLIGHTMAP_ON
|
||||
ambientOrLightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
|
||||
#endif
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLMMASK)
|
||||
if (getIsBakeryVertexMode())
|
||||
{
|
||||
ambientOrLightmapUV = unpack4NFloats(v.uv1.x);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ambientOrLightmapUV;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Base forward pass (directional light, emission, lightmaps, ...)
|
||||
|
||||
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_centroid; // 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
|
||||
|
||||
#if (defined(_NORMALMAP) && defined(NORMALMAP_SHADOW))
|
||||
float3 lightDirTS : TEXCOORD9;
|
||||
#endif
|
||||
|
||||
#if defined(_BAKERY_VERTEXLM)
|
||||
float4 color : COLOR_centroid;
|
||||
#if defined(USING_BAKERY_VERTEXLMDIR)
|
||||
float3 lightDirection : TEXCOORD10_centroid;
|
||||
#elif defined(_BAKERY_SH)
|
||||
float3 shL1x : TEXCOORD10_centroid;
|
||||
float3 shL1y : TEXCOORD11_centroid;
|
||||
float3 shL1z : TEXCOORD12_centroid;
|
||||
#endif
|
||||
#else
|
||||
#if defined(HAS_ATTRIBUTE_COLOR)
|
||||
float4 color : COLOR_centroid;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
VertexOutputForwardBase vertForwardBase (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);
|
||||
|
||||
v.normal = normalize(v.normal.xyz);
|
||||
#ifdef _TANGENT_TO_WORLD
|
||||
v.tangent.xyz = normalize(v.tangent.xyz);
|
||||
#endif
|
||||
|
||||
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
|
||||
#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.xyz;
|
||||
#endif
|
||||
#endif
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
|
||||
o.tex = TexCoords(v);
|
||||
o.eyeVec.xyz = NormalizePerVertexNormal(posWorld.xyz - _WorldSpaceCameraPos);
|
||||
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
|
||||
|
||||
//We need this for shadow receving
|
||||
UNITY_TRANSFER_LIGHTING(o, v.uv1);
|
||||
|
||||
o.ambientOrLightmapUV = VertexGIForward(v, posWorld, normalWorld);
|
||||
|
||||
#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
|
||||
|
||||
#ifdef _TANGENT_TO_WORLD
|
||||
#if defined(NORMALMAP_SHADOW)
|
||||
float3 lightDirWS = normalize(_WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w);
|
||||
o.lightDirTS = TransformToTangentSpace(tangentToWorld[0],tangentToWorld[1],tangentToWorld[2],lightDirWS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAS_ATTRIBUTE_COLOR)
|
||||
o.color = v.color;
|
||||
#endif
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLM)
|
||||
// Unpack from RGBM
|
||||
o.color = v.color;
|
||||
o.color.rgb *= o.color.a * 8.0f;
|
||||
o.color.rgb *= o.color.rgb;
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLMDIR)
|
||||
o.lightDirection = unpack3NFloats(v.uv1.y) * 2 - 1;
|
||||
#elif defined(USING_BAKERY_VERTEXLMSH)
|
||||
o.shL1x = unpack3NFloats(v.uv1.y) * 2 - 1;
|
||||
o.shL1y = unpack3NFloats(v.uv3.x) * 2 - 1;
|
||||
o.shL1z = unpack3NFloats(v.uv3.y) * 2 - 1;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o,o.pos);
|
||||
return o;
|
||||
}
|
||||
|
||||
void computeShadingParamsForwardBase(inout ShadingParams shading, VertexOutputForwardBase i, bool gl_FrontFacing = true)
|
||||
{
|
||||
float3x3 tangentToWorld;
|
||||
tangentToWorld[0] = i.tangentToWorldAndPackedData[0].xyz;
|
||||
tangentToWorld[1] = i.tangentToWorldAndPackedData[1].xyz;
|
||||
tangentToWorld[2] = i.tangentToWorldAndPackedData[2].xyz;
|
||||
|
||||
if (getIsDoubleSided()) {
|
||||
tangentToWorld[0] *= gl_FrontFacing ? 1 : -1;
|
||||
tangentToWorld[1] *= gl_FrontFacing ? 1 : -1;
|
||||
tangentToWorld[2] *= gl_FrontFacing ? 1 : -1;
|
||||
}
|
||||
|
||||
shading.geometricNormal = normalize(tangentToWorld[2].xyz);
|
||||
shading.tangentToWorld = transpose(tangentToWorld);
|
||||
|
||||
float2 viewportUV = i.pos.xy / _ScreenParams.xy;
|
||||
|
||||
#if defined(UNITY_SINGLE_PASS_STEREO)
|
||||
viewportUV.x = viewportUV.x * 2.0 - float(unity_StereoEyeIndex);
|
||||
#endif
|
||||
|
||||
shading.normalizedViewportCoord = viewportUV;
|
||||
|
||||
shading.normal = shading.geometricNormal;
|
||||
shading.position = IN_WORLDPOS(i);
|
||||
shading.view = -NormalizePerPixelNormal(i.eyeVec);
|
||||
|
||||
UNITY_LIGHT_ATTENUATION(atten, i, shading.position)
|
||||
|
||||
#if (defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON))
|
||||
GetBakedAttenuation(atten, i.ambientOrLightmapUV.xy, shading.position);
|
||||
#endif
|
||||
|
||||
shading.attenuation = atten;
|
||||
|
||||
#if (defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON))
|
||||
shading.ambient = 0;
|
||||
shading.lightmapUV = i.ambientOrLightmapUV;
|
||||
#else
|
||||
shading.ambient = i.ambientOrLightmapUV.rgb;
|
||||
shading.lightmapUV = 0;
|
||||
#endif
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLMMASK)
|
||||
if (getIsBakeryVertexMode())
|
||||
{
|
||||
shading.attenuation = saturate(dot(i.ambientOrLightmapUV, unity_OcclusionMaskSelector));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLM)
|
||||
shading.ambient = i.color;
|
||||
#endif
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLMSH)
|
||||
shading.ambientSH[0] = i.shL1x;
|
||||
shading.ambientSH[1] = i.shL1y;
|
||||
shading.ambientSH[2] = i.shL1z;
|
||||
#elif defined(USING_BAKERY_VERTEXLMDIR)
|
||||
shading.ambientDir = i.lightDirection;
|
||||
#endif
|
||||
}
|
||||
|
||||
half4 fragForwardBaseInternal (VertexOutputForwardBase i, bool gl_FrontFacing)
|
||||
{
|
||||
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
|
||||
|
||||
float4 i_texBase = i.tex;
|
||||
|
||||
MATERIAL_SETUP(material)
|
||||
|
||||
UNITY_SETUP_INSTANCE_ID(i);
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
ShadingParams shading = (ShadingParams)0;
|
||||
// Initialize shading with expected parameters
|
||||
computeShadingParamsForwardBase(shading, i, gl_FrontFacing);
|
||||
|
||||
prepareMaterial(shading, material);
|
||||
|
||||
#if ((defined(_NORMALMAP) || defined(_PARALLAXMAP)) && defined(NORMALMAP_SHADOW))
|
||||
float noise = noiseR2(i.pos.xy);
|
||||
#if defined(_PARALLAXMAP)
|
||||
PerPixelHeightDisplacementParam ppd = InitPerPixelHeightDisplacementParam(i.tex.xy);
|
||||
float hShadow = GetParallaxSelfShadow(i.lightDirTS, i.tex.xy, ppd, noise);
|
||||
shading.attenuation = min(shading.attenuation, hShadow);
|
||||
#else
|
||||
float nmShade = NormalTangentShadow (i.tex, i.lightDirTS, noise);
|
||||
shading.attenuation = min(shading.attenuation, max(1-nmShade, 0));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float4 c = evaluateMaterial (shading, material);
|
||||
|
||||
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
|
||||
UNITY_APPLY_FOG(_unity_fogCoord, c.rgb);
|
||||
return c;
|
||||
}
|
||||
|
||||
half4 fragForwardBase (VertexOutputForwardBase i, bool facing : SV_IsFrontFace) : SV_Target // backward compatibility (this used to be the fragment entry function)
|
||||
{
|
||||
return fragForwardBaseInternal(i, facing);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
#if (defined(_NORMALMAP) && defined(NORMALMAP_SHADOW))
|
||||
float3 lightDirTS : TEXCOORD9;
|
||||
#endif
|
||||
|
||||
// If Bakery LM mode is active, vertex colour is base lightmap.
|
||||
#if defined(USING_BAKERY_VERTEXLMMASK)
|
||||
fixed4 shadowMask : COLOR_centroid;
|
||||
#else
|
||||
#if defined(HAS_ATTRIBUTE_COLOR)
|
||||
float4 color : COLOR_centroid;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
VertexOutputForwardAdd vertForwardAdd (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 = NormalizePerVertexNormal(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;
|
||||
#ifndef USING_DIRECTIONAL_LIGHT
|
||||
lightDir = NormalizePerVertexNormal(lightDir);
|
||||
#endif
|
||||
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
|
||||
|
||||
#ifdef _TANGENT_TO_WORLD
|
||||
#if (defined(_NORMALMAP) && defined(NORMALMAP_SHADOW))
|
||||
float3 lightDirWS = normalize(_WorldSpaceLightPos0.xyz - posWorld.xyz * _WorldSpaceLightPos0.w);
|
||||
o.lightDirTS = TransformToTangentSpace(tangentToWorld[0],tangentToWorld[1],tangentToWorld[2],lightDirWS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLMMASK)
|
||||
o.shadowMask = unpack4NFloats(v.uv1.x);
|
||||
#else
|
||||
#if defined(HAS_ATTRIBUTE_COLOR)
|
||||
o.color = v.color;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o, o.pos);
|
||||
return o;
|
||||
}
|
||||
|
||||
void computeShadingParamsForwardAdd(inout ShadingParams shading, VertexOutputForwardAdd i, bool gl_FrontFacing = true)
|
||||
{
|
||||
float3x3 tangentToWorld;
|
||||
tangentToWorld[0] = i.tangentToWorldAndLightDir[0].xyz;
|
||||
tangentToWorld[1] = i.tangentToWorldAndLightDir[1].xyz;
|
||||
tangentToWorld[2] = i.tangentToWorldAndLightDir[2].xyz;
|
||||
|
||||
if (getIsDoubleSided()) {
|
||||
tangentToWorld[0] *= gl_FrontFacing ? 1 : -1;
|
||||
tangentToWorld[1] *= gl_FrontFacing ? 1 : -1;
|
||||
tangentToWorld[2] *= gl_FrontFacing ? 1 : -1;
|
||||
}
|
||||
|
||||
shading.geometricNormal = normalize(tangentToWorld[2].xyz);
|
||||
shading.tangentToWorld = transpose(tangentToWorld);
|
||||
|
||||
float2 viewportUV = i.pos.xy / _ScreenParams.xy;
|
||||
|
||||
#if defined(UNITY_SINGLE_PASS_STEREO)
|
||||
viewportUV.x = viewportUV.x * 2.0 - float(unity_StereoEyeIndex);
|
||||
#endif
|
||||
|
||||
shading.normalizedViewportCoord = viewportUV;
|
||||
|
||||
shading.normal = normalize(shading.geometricNormal);
|
||||
shading.position = IN_WORLDPOS_FWDADD(i);
|
||||
shading.view = -NormalizePerPixelNormal(i.eyeVec);
|
||||
|
||||
UNITY_LIGHT_ATTENUATION(atten, i, shading.position)
|
||||
shading.attenuation = atten;
|
||||
|
||||
#if defined(USING_BAKERY_VERTEXLMMASK)
|
||||
if (getIsBakeryVertexMode())
|
||||
{
|
||||
shading.attenuation *= saturate(dot(i.shadowMask, unity_OcclusionMaskSelector));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
half4 fragForwardAddInternal (VertexOutputForwardAdd i, bool gl_FrontFacing)
|
||||
{
|
||||
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
|
||||
|
||||
MATERIAL_SETUP_FWDADD(material)
|
||||
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
ShadingParams shading = (ShadingParams)0;
|
||||
// Initialize shading with expected parameters
|
||||
computeShadingParamsForwardAdd(shading, i, gl_FrontFacing);
|
||||
|
||||
prepareMaterial(shading, material);
|
||||
|
||||
#if ((defined(_NORMALMAP) || defined(_PARALLAXMAP)) && defined(NORMALMAP_SHADOW))
|
||||
float noise = noiseR2(i.pos.xy);
|
||||
#if defined(_PARALLAXMAP)
|
||||
PerPixelHeightDisplacementParam ppd = InitPerPixelHeightDisplacementParam(i.tex.xy);
|
||||
float hShadow = GetParallaxSelfShadow(i.lightDirTS, i.tex.xy, ppd, noise);
|
||||
shading.attenuation = min(shading.attenuation, hShadow);
|
||||
#else
|
||||
float nmShade = NormalTangentShadow (i.tex, i.lightDirTS, noise);
|
||||
shading.attenuation = min(shading.attenuation, max(1-nmShade, 0));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float4 c = evaluateMaterial (shading, material);
|
||||
|
||||
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
|
||||
return c;
|
||||
}
|
||||
|
||||
half4 fragForwardAdd (VertexOutputForwardAdd i, bool facing : SV_IsFrontFace) : SV_Target // backward compatibility (this used to be the fragment entry function)
|
||||
{
|
||||
return fragForwardAddInternal(i, facing);
|
||||
}
|
||||
|
||||
#endif // UNITY_STANDARD_CORE_INCLUDED
|
||||
Reference in New Issue
Block a user