Added terrain and basic terrain textures

This commit is contained in:
2026-06-12 20:57:07 +01:00
parent 65e0008b90
commit b86da7a45a
197 changed files with 20733 additions and 0 deletions

View 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