123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- #ifndef UNIVERSAL_SPEEDTREE8_PASSES_INCLUDED
- #define UNIVERSAL_SPEEDTREE8_PASSES_INCLUDED
-
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
- #include "SpeedTreeUtility.hlsl"
- #if defined(LOD_FADE_CROSSFADE)
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl"
- #endif
-
- struct SpeedTreeVertexInput
- {
- float4 vertex : POSITION;
- float3 normal : NORMAL;
- float4 tangent : TANGENT;
- float4 texcoord : TEXCOORD0;
- float4 texcoord1 : TEXCOORD1;
- float4 texcoord2 : TEXCOORD2;
- float4 texcoord3 : TEXCOORD3;
- float4 color : COLOR;
-
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
-
- struct SpeedTreeVertexOutput
- {
- half2 uv : TEXCOORD0;
- half4 color : TEXCOORD1;
-
- half4 fogFactorAndVertexLight : TEXCOORD2; // x: fogFactor, yzw: vertex light
-
- #ifdef EFFECT_BUMP
- half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x
- half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y
- half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z
- #else
- half3 normalWS : TEXCOORD3;
- half3 viewDirWS : TEXCOORD4;
- #endif
-
- #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
- float4 shadowCoord : TEXCOORD6;
- #endif
-
- float3 positionWS : TEXCOORD7;
- DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 8);
- float4 clipPos : SV_POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- UNITY_VERTEX_OUTPUT_STEREO
- };
-
- struct SpeedTreeVertexDepthOutput
- {
- half2 uv : TEXCOORD0;
- half4 color : TEXCOORD1;
- half3 viewDirWS : TEXCOORD2;
- float4 clipPos : SV_POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- UNITY_VERTEX_OUTPUT_STEREO
- };
-
- struct SpeedTreeVertexDepthNormalOutput
- {
- half2 uv : TEXCOORD0;
- half4 color : TEXCOORD1;
-
- #ifdef EFFECT_BUMP
- half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x
- half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y
- half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z
- #else
- half3 normalWS : TEXCOORD2;
- half3 viewDirWS : TEXCOORD3;
- #endif
-
- float4 clipPos : SV_POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- UNITY_VERTEX_OUTPUT_STEREO
- };
-
- struct SpeedTreeDepthNormalFragmentInput
- {
- SpeedTreeVertexDepthNormalOutput interpolated;
- #ifdef EFFECT_BACKSIDE_NORMALS
- FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC;
- #endif
- };
-
- struct SpeedTreeFragmentInput
- {
- SpeedTreeVertexOutput interpolated;
- #ifdef EFFECT_BACKSIDE_NORMALS
- FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC;
- #endif
- };
-
- void InitializeData(inout SpeedTreeVertexInput input, float lodValue)
- {
- #if defined(LOD_FADE_PERCENTAGE) && (!defined(LOD_FADE_CROSSFADE) && !defined(EFFECT_BILLBOARD))
- input.vertex.xyz = lerp(input.vertex.xyz, input.texcoord2.xyz, lodValue);
- #endif
-
- // wind
- #if defined(ENABLE_WIND) && !defined(_WINDQUALITY_NONE)
- if (_WindEnabled > 0)
- {
- float3 rotatedWindVector = mul(_ST_WindVector.xyz, (float3x3)UNITY_MATRIX_M);
- float windLength = length(rotatedWindVector);
- if (windLength < 1e-5)
- {
- // sanity check that wind data is available
- return;
- }
- rotatedWindVector /= windLength;
-
- float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
- float3 windyPosition = input.vertex.xyz;
-
- #ifndef EFFECT_BILLBOARD
- // geometry type
- float geometryType = (int)(input.texcoord3.w + 0.25);
- bool leafTwo = false;
- if (geometryType > GEOM_TYPE_FACINGLEAF)
- {
- geometryType -= 2;
- leafTwo = true;
- }
-
- // leaves
- if (geometryType > GEOM_TYPE_FROND)
- {
- // remove anchor position
- float3 anchor = float3(input.texcoord1.zw, input.texcoord2.w);
- windyPosition -= anchor;
-
- if (geometryType == GEOM_TYPE_FACINGLEAF)
- {
- // face camera-facing leaf to camera
- float offsetLen = length(windyPosition);
- windyPosition = mul(windyPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * windyPosition
- windyPosition = normalize(windyPosition) * offsetLen; // make sure the offset vector is still scaled
- }
-
- // leaf wind
- #if defined(_WINDQUALITY_FAST) || defined(_WINDQUALITY_BETTER) || defined(_WINDQUALITY_BEST)
- #ifdef _WINDQUALITY_BEST
- bool bBestWind = true;
- #else
- bool bBestWind = false;
- #endif
- float leafWindTrigOffset = anchor.x + anchor.y;
- windyPosition = LeafWind(bBestWind, leafTwo, windyPosition, input.normal, input.texcoord3.x, float3(0,0,0), input.texcoord3.y, input.texcoord3.z, leafWindTrigOffset, rotatedWindVector);
- #endif
-
- // move back out to anchor
- windyPosition += anchor;
- }
-
- // frond wind
- bool bPalmWind = false;
- #ifdef _WINDQUALITY_PALM
- bPalmWind = true;
- if (geometryType == GEOM_TYPE_FROND)
- {
- windyPosition = RippleFrond(windyPosition, input.normal, input.texcoord.x, input.texcoord.y, input.texcoord3.x, input.texcoord3.y, input.texcoord3.z);
- }
- #endif
-
- // branch wind (applies to all 3D geometry)
- #if defined(_WINDQUALITY_BETTER) || defined(_WINDQUALITY_BEST) || defined(_WINDQUALITY_PALM)
- float3 rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)UNITY_MATRIX_M)) * _ST_WindBranchAnchor.w;
- windyPosition = BranchWind(bPalmWind, windyPosition, treePos, float4(input.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
- #endif
-
- #endif // !EFFECT_BILLBOARD
-
- // global wind
- float globalWindTime = _ST_WindGlobal.x;
- #if defined(EFFECT_BILLBOARD) && defined(UNITY_INSTANCING_ENABLED)
- globalWindTime += UNITY_ACCESS_INSTANCED_PROP(STWind, _GlobalWindTime);
- #endif
-
- windyPosition = GlobalWind(windyPosition, treePos, true, rotatedWindVector, globalWindTime);
- input.vertex.xyz = windyPosition;
- }
- #endif
-
- #if defined(EFFECT_BILLBOARD)
- float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
- // crossfade faces
- bool topDown = (input.texcoord.z > 0.5);
- float3 viewDir = UNITY_MATRIX_IT_MV[2].xyz;
- float3 cameraDir = normalize(mul((float3x3)UNITY_MATRIX_M, _WorldSpaceCameraPos - treePos));
- float viewDot = max(dot(viewDir, input.normal), dot(cameraDir, input.normal));
- viewDot *= viewDot;
- viewDot *= viewDot;
- viewDot += topDown ? 0.38 : 0.18; // different scales for horz and vert billboards to fix transition zone
-
- // if invisible, avoid overdraw
- if (viewDot < 0.3333)
- {
- input.vertex.xyz = float3(0, 0, 0);
- }
-
- input.color = float4(1, 1, 1, clamp(viewDot, 0, 1));
-
- // adjust lighting on billboards to prevent seams between the different faces
- if (topDown)
- {
- input.normal += cameraDir;
- }
- else
- {
- half3 binormal = cross(input.normal, input.tangent.xyz) * input.tangent.w;
- float3 right = cross(cameraDir, binormal);
- input.normal = cross(binormal, right);
- }
- input.normal = normalize(input.normal);
- #endif
- }
-
- SpeedTreeVertexOutput SpeedTree8Vert(SpeedTreeVertexInput input)
- {
- SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_TRANSFER_INSTANCE_ID(input, output);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
-
- // handle speedtree wind and lod
- InitializeData(input, unity_LODFade.x);
-
- output.uv = input.texcoord.xy;
- output.color = input.color;
-
- // color already contains (ao, ao, ao, blend)
- // put hue variation amount in there
- #ifdef EFFECT_HUE_VARIATION
- float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
- float hueVariationAmount = frac(treePos.x + treePos.y + treePos.z);
- output.color.g = saturate(hueVariationAmount * _HueVariationColor.a);
- #endif
-
- VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
- half3 normalWS = TransformObjectToWorldNormal(input.normal);
-
- half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
- half fogFactor = 0.0;
- #if !defined(_FOG_FRAGMENT)
- fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
- #endif
- output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
-
- half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
-
- #ifdef EFFECT_BUMP
- real sign = input.tangent.w * GetOddNegativeScale();
- output.normalWS.xyz = normalWS;
- output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
- output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
-
- // View dir packed in w.
- output.normalWS.w = viewDirWS.x;
- output.tangentWS.w = viewDirWS.y;
- output.bitangentWS.w = viewDirWS.z;
- #else
- output.normalWS = normalWS;
- output.viewDirWS = viewDirWS;
- #endif
-
- output.positionWS = vertexInput.positionWS;
-
- #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
- output.shadowCoord = GetShadowCoord(vertexInput);
- #endif
-
- output.clipPos = vertexInput.positionCS;
-
- OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion);
-
- return output;
- }
-
- SpeedTreeVertexDepthOutput SpeedTree8VertDepth(SpeedTreeVertexInput input)
- {
- SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_TRANSFER_INSTANCE_ID(input, output);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
-
- // handle speedtree wind and lod
- InitializeData(input, unity_LODFade.x);
- output.uv = input.texcoord.xy;
- output.color = input.color;
-
- VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
-
- output.viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
-
- #ifdef SHADOW_CASTER
- half3 normalWS = TransformObjectToWorldNormal(input.normal);
-
- #if _CASTING_PUNCTUAL_LIGHT_SHADOW
- float3 lightDirectionWS = normalize(_LightPosition - vertexInput.positionWS);
- #else
- float3 lightDirectionWS = _LightDirection;
- #endif
-
- float4 positionCS = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, lightDirectionWS));
- output.clipPos = positionCS;
- #else
- output.clipPos = vertexInput.positionCS;
- #endif
-
- return output;
- }
-
- void InitializeInputData(SpeedTreeFragmentInput input, half3 normalTS, out InputData inputData)
- {
- inputData = (InputData)0;
-
- inputData.positionWS = input.interpolated.positionWS.xyz;
- inputData.positionCS = input.interpolated.clipPos;
-
- #ifdef EFFECT_BUMP
- inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz));
- inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
- inputData.viewDirectionWS = half3(input.interpolated.normalWS.w, input.interpolated.tangentWS.w, input.interpolated.bitangentWS.w);
- #else
- inputData.normalWS = NormalizeNormalPerPixel(input.interpolated.normalWS);
- inputData.viewDirectionWS = input.interpolated.viewDirWS;
- #endif
-
- inputData.viewDirectionWS = SafeNormalize(inputData.viewDirectionWS);
-
- #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
- inputData.shadowCoord = input.interpolated.shadowCoord;
- #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
- inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
- #else
- inputData.shadowCoord = float4(0, 0, 0, 0);
- #endif
-
- inputData.fogCoord = InitializeInputDataFog(float4(input.interpolated.positionWS, 1.0), input.interpolated.fogFactorAndVertexLight.x);
- inputData.vertexLighting = input.interpolated.fogFactorAndVertexLight.yzw;
- #if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
- inputData.bakedGI = SAMPLE_GI(input.interpolated.vertexSH,
- GetAbsolutePositionWS(inputData.positionWS),
- inputData.normalWS,
- inputData.viewDirectionWS,
- inputData.positionCS.xy,
- input.probeOcclusion,
- inputData.shadowMask);
- #else
- inputData.bakedGI = SAMPLE_GI(NOT_USED, input.interpolated.vertexSH, inputData.normalWS);
- #endif
-
- inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.interpolated.clipPos);
- inputData.shadowMask = half4(1, 1, 1, 1); // No GI currently.
-
- #if defined(DEBUG_DISPLAY) && !defined(LIGHTMAP_ON)
- inputData.vertexSH = input.interpolated.vertexSH;
- #endif
-
- #if defined(_NORMALMAP)
- inputData.tangentToWorld = half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz);
- #endif
- }
-
- #ifdef GBUFFER
- FragmentOutput SpeedTree8Frag(SpeedTreeFragmentInput input)
- #else
- half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target
- #endif
- {
- UNITY_SETUP_INSTANCE_ID(input.interpolated);
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated);
-
- half2 uv = input.interpolated.uv;
- half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
-
- half alpha = diffuse.a * input.interpolated.color.a;
- alpha = AlphaDiscard(alpha, 0.3333);
-
- #ifdef LOD_FADE_CROSSFADE
- LODFadeCrossFade(input.interpolated.clipPos);
- #endif
-
- half3 albedo = diffuse.rgb;
- half3 emission = 0;
- half metallic = 0;
- half smoothness = 0;
- half occlusion = 0;
- half3 specular = 0;
-
- // hue variation
- #ifdef EFFECT_HUE_VARIATION
- half3 shiftedColor = lerp(albedo, _HueVariationColor.rgb, input.interpolated.color.g);
-
- // preserve vibrance
- half maxBase = max(albedo.r, max(albedo.g, albedo.b));
- half newMaxBase = max(shiftedColor.r, max(shiftedColor.g, shiftedColor.b));
- maxBase /= newMaxBase;
- maxBase = maxBase * 0.5f + 0.5f;
- shiftedColor.rgb *= maxBase;
-
- albedo = saturate(shiftedColor);
- #endif
-
- // normal
- #ifdef EFFECT_BUMP
- half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
- #else
- half3 normalTs = half3(0, 0, 1);
- #endif
-
- // flip normal on backsides
- #ifdef EFFECT_BACKSIDE_NORMALS
- normalTs.z = IS_FRONT_VFACE(input.facing, normalTs.z, -normalTs.z);
- #endif
-
- // adjust billboard normals to improve GI and matching
- #ifdef EFFECT_BILLBOARD
- normalTs.z *= 0.5;
- normalTs = normalize(normalTs);
- #endif
-
- // extra
- #ifdef EFFECT_EXTRA_TEX
- half4 extra = tex2D(_ExtraTex, uv);
- smoothness = extra.r;
- metallic = extra.g;
- occlusion = extra.b * input.interpolated.color.r;
- #else
- smoothness = _Glossiness;
- metallic = _Metallic;
- occlusion = input.interpolated.color.r;
- #endif
-
- InputData inputData;
- InitializeInputData(input, normalTs, inputData);
- SETUP_DEBUG_TEXTURE_DATA(inputData, input.interpolated.uv);
-
- #if defined(GBUFFER) || defined(EFFECT_SUBSURFACE)
- Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
- #endif
-
- // subsurface (hijack emissive)
- #ifdef EFFECT_SUBSURFACE
- half fSubsurfaceRough = 0.7 - smoothness * 0.5;
- half fSubsurface = D_GGX(clamp(-dot(mainLight.direction.xyz, inputData.viewDirectionWS.xyz), 0, 1), fSubsurfaceRough);
-
- float4 shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
- half realtimeShadow = MainLightRealtimeShadow(shadowCoord);
- float3 tintedSubsurface = tex2D(_SubsurfaceTex, uv).rgb * _SubsurfaceColor.rgb;
- float3 directSubsurface = tintedSubsurface.rgb * mainLight.color.rgb * fSubsurface * realtimeShadow;
- float3 indirectSubsurface = tintedSubsurface.rgb * inputData.bakedGI.rgb * _SubsurfaceIndirect;
- emission = directSubsurface + indirectSubsurface;
- #endif
-
- #ifdef GBUFFER
- // in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR
- // in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer
- BRDFData brdfData;
- InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
-
- MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
- half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS);
-
- return BRDFDataToGbuffer(brdfData, inputData, smoothness, emission + color, occlusion);
-
- #else
- SurfaceData surfaceData;
-
- surfaceData.albedo = albedo;
- surfaceData.specular = specular;
- surfaceData.metallic = metallic;
- surfaceData.smoothness = smoothness;
- surfaceData.normalTS = normalTs;
- surfaceData.emission = emission;
- surfaceData.occlusion = occlusion;
- surfaceData.alpha = alpha;
- surfaceData.clearCoatMask = 0;
- surfaceData.clearCoatSmoothness = 1;
-
- #if defined(DEBUG_DISPLAY)
- inputData.uv = uv;
- #endif
-
- half4 color = UniversalFragmentPBR(inputData, surfaceData);
-
- color.rgb = MixFog(color.rgb, inputData.fogCoord);
- color.a = OutputAlpha(color.a, _Surface);
-
- return color;
-
- #endif
- }
-
- half4 SpeedTree8FragDepth(SpeedTreeVertexDepthOutput input) : SV_Target
- {
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
-
- half2 uv = input.uv;
- half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
-
- half alpha = diffuse.a * input.color.a;
- AlphaDiscard(alpha, 0.3333);
-
- #ifdef LOD_FADE_CROSSFADE
- LODFadeCrossFade(input.clipPos);
- #endif
-
- #if defined(SCENESELECTIONPASS)
- // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
- return half4(_ObjectId, _PassValue, 1.0, 1.0);
- #else
- return half4(input.clipPos.z, 0, 0, 0);
- #endif
- }
-
- SpeedTreeVertexDepthNormalOutput SpeedTree8VertDepthNormal(SpeedTreeVertexInput input)
- {
- SpeedTreeVertexDepthNormalOutput output = (SpeedTreeVertexDepthNormalOutput)0;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_TRANSFER_INSTANCE_ID(input, output);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
-
- // handle speedtree wind and lod
- InitializeData(input, unity_LODFade.x);
- output.uv = input.texcoord.xy;
- output.color = input.color;
-
- VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
- half3 normalWS = TransformObjectToWorldNormal(input.normal);
- half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
- #ifdef EFFECT_BUMP
- real sign = input.tangent.w * GetOddNegativeScale();
- output.normalWS.xyz = normalWS;
- output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
- output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
-
- // View dir packed in w.
- output.normalWS.w = viewDirWS.x;
- output.tangentWS.w = viewDirWS.y;
- output.bitangentWS.w = viewDirWS.z;
- #else
- output.normalWS = normalWS;
- output.viewDirWS = viewDirWS;
- #endif
-
- output.clipPos = vertexInput.positionCS;
- return output;
- }
-
- half4 SpeedTree8FragDepthNormal(SpeedTreeDepthNormalFragmentInput input) : SV_Target
- {
- UNITY_SETUP_INSTANCE_ID(input.interpolated);
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated);
-
- half2 uv = input.interpolated.uv;
- half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
-
- half alpha = diffuse.a * input.interpolated.color.a;
- AlphaDiscard(alpha, 0.3333);
-
- #ifdef LOD_FADE_CROSSFADE
- LODFadeCrossFade(input.interpolated.clipPos);
- #endif
-
- // normal
- #if defined(EFFECT_BUMP)
- half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
- #else
- half3 normalTs = half3(0, 0, 1);
- #endif
-
- // flip normal on backsides
- #ifdef EFFECT_BACKSIDE_NORMALS
- if (input.facing < 0.5)
- {
- normalTs.z = -normalTs.z;
- }
- #endif
-
- // adjust billboard normals to improve GI and matching
- #if defined(EFFECT_BILLBOARD)
- normalTs.z *= 0.5;
- normalTs = normalize(normalTs);
- #endif
-
- #if defined(EFFECT_BUMP)
- float3 normalWS = TransformTangentToWorld(normalTs, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz));
- return half4(NormalizeNormalPerPixel(normalWS), 0.0h);
- #else
- return half4(NormalizeNormalPerPixel(input.interpolated.normalWS), 0.0h);
- #endif
- }
-
- #endif
|