|
|
|
|
@ -1,9 +1,8 @@
|
|
|
|
|
// Material Properties
|
|
|
|
|
float _BladeWidth, _BendStrength;
|
|
|
|
|
float4 _Color0, _Color1, _Color2, _Color3, _InnerColor;
|
|
|
|
|
float _SegmentsMinusOne, _FieldSize, _AOStrength, _Translucency, _SSSStrength, _Metallic, _Roughness,
|
|
|
|
|
_BladeBow, _MaxBladeHeight, _HighlightStrength, _BladeWidthTexStrength;
|
|
|
|
|
sampler2D _FrabVarianz, _BladeWidthTex;
|
|
|
|
|
float4 _InnerColor;
|
|
|
|
|
float _AOStrength, _Translucency, _SSSStrength, _Metallic, _Roughness, _NormalCurvature, _BladeWidthTexStrength;
|
|
|
|
|
sampler2D _FieldColor, _BladeWidthTex;
|
|
|
|
|
|
|
|
|
|
float2 _TransitionRange;
|
|
|
|
|
|
|
|
|
|
@ -24,12 +23,12 @@ struct v2g {
|
|
|
|
|
struct g2f {
|
|
|
|
|
float4 pos : SV_POSITION;
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
float3 normal : NORMAL;
|
|
|
|
|
float3 worldPos : TEXCOORD3;
|
|
|
|
|
float3 localNormal : NORMAL;
|
|
|
|
|
float2 uv : TEXCOORD0; // bottom left 0.0 top right 1.1 (values converge - 0 and 1 meet at the tip)
|
|
|
|
|
SHADOW_COORDS(1) // put shadows data into TEXCOORD1
|
|
|
|
|
float transitionInterpolator : TEXCOORD2;
|
|
|
|
|
float3 worldPos : TEXCOORD2;
|
|
|
|
|
#endif
|
|
|
|
|
float3 debug : TEXCOORD3;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
v2g vert (MeshData v) {
|
|
|
|
|
@ -40,10 +39,6 @@ v2g vert (MeshData v) {
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float getCameraDistance(float3 pos) {
|
|
|
|
|
return distance(_MainCameraPosition, pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if _LOD_LOD_0
|
|
|
|
|
[MaxVertexCount(4 + ( 11 - 1 ) * 2)]
|
|
|
|
|
#elif _LOD_LOD_1
|
|
|
|
|
@ -56,7 +51,6 @@ float getCameraDistance(float3 pos) {
|
|
|
|
|
void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
|
|
|
|
const float3 basePos = IN[0].vertex.xyz;
|
|
|
|
|
const float3 tipOffset = IN[0].tipOffset;
|
|
|
|
|
const float3 tipPosObjectSpace = basePos + tipOffset;
|
|
|
|
|
|
|
|
|
|
// const float4 basePosClipSpace = UnityObjectToClipPos(float4(basePos, 1));
|
|
|
|
|
// const float4 tipPosClipSpace = UnityObjectToClipPos(float4(tipPosObjectSpace, 1));
|
|
|
|
|
@ -64,9 +58,9 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
|
|
|
|
|
|
|
|
|
const float3 basePosWS = mul(unity_ObjectToWorld, float4(basePos.xyz, 1.0)).xyz;
|
|
|
|
|
|
|
|
|
|
const float cameraDistance = getCameraDistance(basePosWS);
|
|
|
|
|
const float mainCamDist = distance(_MainCameraPosition, basePosWS);
|
|
|
|
|
|
|
|
|
|
float interpolator = invLerp(_TransitionRange.x, _TransitionRange.y, cameraDistance);
|
|
|
|
|
float interpolator = invLerp(_TransitionRange.x, _TransitionRange.y, mainCamDist);
|
|
|
|
|
|
|
|
|
|
float halfWidth = _BladeWidth/2;
|
|
|
|
|
|
|
|
|
|
@ -78,16 +72,16 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// randomly shrink shadow blades to create a smooth transition between shadowed and non-shadowed area
|
|
|
|
|
#ifdef IS_IN_SHADOW_PASS
|
|
|
|
|
#if _LOD_LOD_1
|
|
|
|
|
#ifdef IS_IN_SHADOW_PASS
|
|
|
|
|
#if _LOD_LOD_1
|
|
|
|
|
float widthMultiplier = remap(N21(basePos.xz) * 0.5, 1, 1, 0, interpolator);
|
|
|
|
|
widthMultiplier = max(0, widthMultiplier);
|
|
|
|
|
halfWidth *= widthMultiplier;
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
g2f o;
|
|
|
|
|
float3 previousSegmentCenter = basePos - float3(0,-1,0); // point beneath the basePos
|
|
|
|
|
o.debug = float3(0,0,0);
|
|
|
|
|
|
|
|
|
|
int numSegments;
|
|
|
|
|
#if _LOD_LOD_0
|
|
|
|
|
@ -100,196 +94,197 @@ void geom(point v2g IN[1], inout TriangleStream<g2f> triStream) {
|
|
|
|
|
numSegments = 1;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
float3 localCameraPos = mul(unity_WorldToObject, float4(_MainCameraPosition.xyz, 1.0)).xyz;
|
|
|
|
|
const float lowerThickness = 0.8;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < numSegments; i++) {
|
|
|
|
|
const float lowerThickness = 0.8;
|
|
|
|
|
|
|
|
|
|
// LOD 3 has a different algorithm
|
|
|
|
|
#if _LOD_LOD_3
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141), .8);
|
|
|
|
|
const float3 widthOffset = getWidthOffset(segmentWidth, tipOffset.xz) * max(1, cameraDistance / 10);
|
|
|
|
|
float3 segmentCenterBase = basePos;
|
|
|
|
|
float3 segmentCenterTip = basePos + tipOffset;
|
|
|
|
|
const float3 vertLeftBase = segmentCenterBase + widthOffset * 2.5;
|
|
|
|
|
const float3 vertRightBase = segmentCenterBase - widthOffset * 2.5;
|
|
|
|
|
const float3 vertLeftTip = segmentCenterTip + widthOffset * 0.4;
|
|
|
|
|
const float3 vertRightTip = segmentCenterTip - widthOffset * 0.4;
|
|
|
|
|
|
|
|
|
|
const float3 surfTangent1 = vertLeftBase - vertLeftTip;
|
|
|
|
|
const float3 surfTangent2 = vertLeftBase - vertRightBase;
|
|
|
|
|
const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize
|
|
|
|
|
float3 normalWS = UnityObjectToWorldNormal(normal);
|
|
|
|
|
|
|
|
|
|
const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141), .8);
|
|
|
|
|
const float3 widthOffset = getWidthOffset(tipOffset.xz) * segmentWidth * max(1, mainCamDist / 10);
|
|
|
|
|
float3 segmentCenterBase = basePos;
|
|
|
|
|
float3 segmentCenterTip = basePos + tipOffset;
|
|
|
|
|
const float3 vertLeftBase = segmentCenterBase + widthOffset * 2.5;
|
|
|
|
|
const float3 vertRightBase = segmentCenterBase - widthOffset * 2.5;
|
|
|
|
|
const float3 vertLeftTip = segmentCenterTip + widthOffset * 0.4;
|
|
|
|
|
const float3 vertRightTip = segmentCenterTip - widthOffset * 0.4;
|
|
|
|
|
|
|
|
|
|
const float3 surfTangent1 = vertRightBase - segmentCenterTip;
|
|
|
|
|
const float3 surfTangent2 = vertLeftBase - segmentCenterTip;
|
|
|
|
|
const float3 normal = cross(surfTangent1, surfTangent2);
|
|
|
|
|
|
|
|
|
|
const float3 camVec = normalize(vertLeftBase - localCameraPos);
|
|
|
|
|
|
|
|
|
|
// at which side of the blade are we looking?
|
|
|
|
|
const bool lookingFromAbove = dot(camVec, normalWS) > 0;
|
|
|
|
|
if (lookingFromAbove) {
|
|
|
|
|
normalWS = -normalWS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//normalWS = float3(1,1,1) * lookingFromAbove;
|
|
|
|
|
//normalWS = basePosWS - _MainCameraPosition.xyz;
|
|
|
|
|
//normalWS = camVec;
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertLeftBase);
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
|
|
|
|
|
o.uv = float2(0, 0);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = normalWS;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftBase,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertRightBase);
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
o.uv = float2(1, 0);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = normalWS;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertRightBase,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertLeftTip);
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
o.uv = float2(0, 1);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = normalWS;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftTip,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertRightTip);
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
o.uv = float2(1, 1);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = normalWS;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertRightTip,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertRightBase);
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(1, 0);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.localNormal = normal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertRightBase,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// in "blade space"
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertLeftBase);
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(0, 0);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.localNormal = normal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftBase,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertRightTip);
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(1, 1);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.localNormal = normal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertRightTip,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertLeftTip);
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(0, 1);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.localNormal = normal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertLeftTip,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
const float3 widthOffset = getWidthOffset(tipOffset.xz) * max(1, mainCamDist / 10);
|
|
|
|
|
|
|
|
|
|
// previous vertex positions, used for normal calculation
|
|
|
|
|
float3 previousVertLeft;
|
|
|
|
|
float3 previousVertRight;
|
|
|
|
|
for (int i = 0; i < numSegments; i++) {
|
|
|
|
|
const float segmentWidth = halfWidth * pow(sin(lowerThickness * 3.141 * (numSegments - i) / numSegments), .8);
|
|
|
|
|
const float3 segmentWidthOffset = widthOffset * segmentWidth;
|
|
|
|
|
const float segmentHeightNormalized = i / (float)numSegments;
|
|
|
|
|
// float nextSegmentHeightNormalized = (i+1) / (float)numSegments;
|
|
|
|
|
|
|
|
|
|
// generate new verts
|
|
|
|
|
const float3 widthOffset = getWidthOffset(segmentWidth, tipOffset.xz) * max(1, cameraDistance / 10);
|
|
|
|
|
float3 segmentCenter = basePos + bendParabula(tipOffset, segmentHeightNormalized, _BendStrength);
|
|
|
|
|
const float3 segmentCenterSnapshot = segmentCenter;
|
|
|
|
|
|
|
|
|
|
const float3 vertLeft = segmentCenter + widthOffset;
|
|
|
|
|
const float3 vertRight = segmentCenter - widthOffset;
|
|
|
|
|
//const float3 nextSegmentCenter = basePos + bendParabula(tipPos, nextSegmentHeight01);
|
|
|
|
|
const float3 segmentCenter = basePos + bendParabula(tipOffset, segmentHeightNormalized, _BendStrength);
|
|
|
|
|
const float3 vertLeft = segmentCenter + segmentWidthOffset;
|
|
|
|
|
const float3 vertRight = segmentCenter - segmentWidthOffset;
|
|
|
|
|
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
// calculate normal
|
|
|
|
|
const float3 surfTangent1 = previousSegmentCenter - segmentCenter;
|
|
|
|
|
const float3 surfTangent2 = previousSegmentCenter - vertLeft;
|
|
|
|
|
const float3 normal = normalize(cross(surfTangent1, surfTangent2)); // TODO remove normalize
|
|
|
|
|
float3 normalWS = UnityObjectToWorldNormal(normal);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const float3 camVec = normalize(segmentCenter - localCameraPos);
|
|
|
|
|
|
|
|
|
|
// at which side of the blade are we looking?
|
|
|
|
|
const bool lookingFromAbove = dot(camVec, normalWS) > 0;
|
|
|
|
|
if (lookingFromAbove) {
|
|
|
|
|
normalWS = -normalWS;
|
|
|
|
|
float3 surfTangent1, surfTangent2;
|
|
|
|
|
if (i == 0) {
|
|
|
|
|
// for the normals at the bottom vertices, use the normals of the next segment
|
|
|
|
|
const float nextSegmentHeightNormalized = (i+1) / (float)numSegments;
|
|
|
|
|
const float3 nextSegmentCenter = basePos + bendParabula(tipOffset, nextSegmentHeightNormalized, _BendStrength);
|
|
|
|
|
surfTangent1 = nextSegmentCenter - vertRight;
|
|
|
|
|
surfTangent2 = nextSegmentCenter - vertLeft;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
surfTangent1 = segmentCenter - previousVertRight;
|
|
|
|
|
surfTangent2 = segmentCenter - previousVertLeft;
|
|
|
|
|
}
|
|
|
|
|
const float3 normal = cross(surfTangent1, surfTangent2);
|
|
|
|
|
|
|
|
|
|
#if _LOD_LOD_0
|
|
|
|
|
const float curvature = _NormalCurvature;
|
|
|
|
|
#elif _LOD_LOD_1
|
|
|
|
|
const float curvature = lerp(_NormalCurvature, 0.0, interpolator);
|
|
|
|
|
#else
|
|
|
|
|
const float curvature = 0.0;
|
|
|
|
|
#endif
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertLeft);
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
o.uv = float2(0, segmentHeightNormalized);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(normalize(widthOffset)), _BladeBow));
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz;
|
|
|
|
|
float3 leftCurvedNormal = normalize(normalize(normal) + widthOffset * curvature);
|
|
|
|
|
float3 rightCurvedNormal = normalize(normalize(normal) - widthOffset * curvature);
|
|
|
|
|
|
|
|
|
|
previousVertLeft = vertLeft;
|
|
|
|
|
previousVertRight = vertRight;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertRight);
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(1, segmentHeightNormalized);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = normalize(lerp(normalWS, UnityObjectToWorldNormal(-normalize(widthOffset)), _BladeBow));
|
|
|
|
|
o.localNormal = rightCurvedNormal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertRight,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
previousSegmentCenter = segmentCenterSnapshot;
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(vertLeft);
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(0, segmentHeightNormalized);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.localNormal = leftCurvedNormal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(vertLeft,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o.pos = UnityObjectToClipPos(basePos + tipOffset * float3(_BendStrength, 1, _BendStrength));
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
|
|
|
|
|
// tip vertex
|
|
|
|
|
const float3 tipPosObjectSpace = basePos + tipOffset;
|
|
|
|
|
const float3 surfTangent1 = tipPosObjectSpace - previousVertRight;
|
|
|
|
|
const float3 surfTangent2 = tipPosObjectSpace - previousVertLeft;
|
|
|
|
|
const float3 normal = cross(surfTangent1, surfTangent2);
|
|
|
|
|
o.pos = UnityObjectToClipPos(tipPosObjectSpace * float3(_BendStrength, 1, _BendStrength));
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
o.uv = float2(.5, 1);
|
|
|
|
|
TRANSFER_SHADOW(o)
|
|
|
|
|
o.transitionInterpolator = interpolator;
|
|
|
|
|
o.normal = o.normal > 0 ? float3(0, 1, 0) : float3(0, -1, 0);
|
|
|
|
|
o.localNormal = normal;
|
|
|
|
|
o.worldPos = mul(unity_ObjectToWorld, float4(tipPosObjectSpace,1.0)).xyz;
|
|
|
|
|
#endif
|
|
|
|
|
triStream.Append(o);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float4 frag(g2f i) : SV_Target{
|
|
|
|
|
#ifndef IS_IN_SHADOW_PASS
|
|
|
|
|
float3 worldNormal = normalize(i.normal);
|
|
|
|
|
float4 frag(g2f i, bool isFrontFace : SV_IsFrontFace) : SV_Target {
|
|
|
|
|
#ifdef IS_IN_BASE_PASS
|
|
|
|
|
float3 localPos = mul(unity_WorldToObject, float4(i.worldPos, 1)).xyz;
|
|
|
|
|
float d = distance(localPos, i.debug) * 50;
|
|
|
|
|
float k = frac(d);
|
|
|
|
|
// return float4(k,k,k, 1);
|
|
|
|
|
// return float4(i.debug,1);
|
|
|
|
|
|
|
|
|
|
float3 worldNormal = UnityObjectToWorldNormal(i.localNormal);
|
|
|
|
|
|
|
|
|
|
// at which side of the blade are we looking?
|
|
|
|
|
// VERY INACCURATE, because the normals don't match the geometry (smoothing, fake curvature)
|
|
|
|
|
if (!isFrontFace) {
|
|
|
|
|
worldNormal = -worldNormal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
|
|
|
|
|
|
|
|
|
|
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
|
|
|
|
|
float3 worldRefl = reflect(-worldViewDir, worldNormal);
|
|
|
|
|
|
|
|
|
|
// same as in previous shader
|
|
|
|
|
half4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldRefl, 0);
|
|
|
|
|
float4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldRefl, 0);
|
|
|
|
|
float3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR);
|
|
|
|
|
|
|
|
|
|
float3 lightReflectDirection = reflect(-lightDirection, worldNormal);
|
|
|
|
|
float3 viewDirection = normalize(float3(float4(_MainCameraPosition.xyz, 1.0) - i.worldPos.xyz));
|
|
|
|
|
|
|
|
|
|
float atten = 1.0;
|
|
|
|
|
|
|
|
|
|
float3 translucency = atten * _LightColor0.xyz * max(0.0, dot(worldNormal, -lightDirection)) * _Translucency;
|
|
|
|
|
float3 translucency = _LightColor0.xyz * max(0.0, dot(worldNormal, -lightDirection)) * _Translucency;
|
|
|
|
|
float3 subsurf = max(0.0, dot(lightReflectDirection, -viewDirection)) * _SSSStrength * _InnerColor;
|
|
|
|
|
const fixed shadow = SHADOW_ATTENUATION(i);
|
|
|
|
|
const float shadow = max(.35, SHADOW_ATTENUATION(i));
|
|
|
|
|
|
|
|
|
|
float3 lightFinal = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, worldNormal, 2.0);
|
|
|
|
|
lightFinal += translucency;
|
|
|
|
|
lightFinal += subsurf;
|
|
|
|
|
lightFinal *= max(.35, shadow);
|
|
|
|
|
lightFinal *= 1.0;
|
|
|
|
|
lightFinal *= shadow;
|
|
|
|
|
|
|
|
|
|
// ATTENTION DO NOT TRY TO UNDERSTAND THE CODE BELOW (or you will go crazy)
|
|
|
|
|
|
|
|
|
|
float4 middleCol = min(1, abs(i.uv.x - 0.5) * 1);
|
|
|
|
|
float4 col = max(0.87, pow(middleCol, .01));
|
|
|
|
|
float4 farbvarianz = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 40, 0, 3));
|
|
|
|
|
float4 farbvarianz2 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 10, 0, 3));
|
|
|
|
|
float4 farbvarianz3 = tex2Dlod(_FrabVarianz, float4(i.worldPos.xz / 3, 0, 3));
|
|
|
|
|
float3 c0 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 40, 0, 3)).xyz;
|
|
|
|
|
float3 c1 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 10, 0, 3)).xyz;
|
|
|
|
|
float3 c2 = tex2Dlod(_FieldColor, float4(i.worldPos.xz / 3, 0, 3)).xyz;
|
|
|
|
|
float4 bladeWidthTex = tex2Dlod(_BladeWidthTex, float4(i.uv.x, 0, 0, 3));
|
|
|
|
|
|
|
|
|
|
float4 albedo = lerp(farbvarianz2, farbvarianz3, 0.4);
|
|
|
|
|
albedo = lerp(albedo, farbvarianz, _Metallic) * 0.7;
|
|
|
|
|
float3 albedo = lerp(c1, c2, 0.4);
|
|
|
|
|
albedo = lerp(albedo, c0, _Metallic) * 0.7;
|
|
|
|
|
albedo *= 1 + _AOStrength;
|
|
|
|
|
albedo *= lerp(1, bladeWidthTex.x * 2.5, _BladeWidthTexStrength);
|
|
|
|
|
|
|
|
|
|
fixed3 color = fixed3(skyColor * max(.35, shadow) * .2 + lightFinal * albedo * col);
|
|
|
|
|
fixed3 highlightedColor = lerp(color, fixed3(2.5, 0.7, 0.5), 0.5);
|
|
|
|
|
fixed3 finalTestColor = albedo.xyz ;
|
|
|
|
|
float3 color = float3(skyColor * shadow * .2 + lightFinal * albedo * col);
|
|
|
|
|
float3 highlightedColor = lerp(color, float3(2.5, 0.7, 0.5), 0.5);
|
|
|
|
|
float3 finalTestColor = albedo.xyz ;
|
|
|
|
|
|
|
|
|
|
lightFinal = min(1.4, max(0.4, lightFinal));
|
|
|
|
|
|
|
|
|
|
return float4(worldNormal, 1);
|
|
|
|
|
return float4(color, 1);
|
|
|
|
|
#endif
|
|
|
|
|
return 0; // shadow pass
|
|
|
|
|
}
|
|
|
|
|
|