Added new stocking scope to shader gui;
Added new stocking surface feature; Added unity 6.3 support; Fixed the issue that ssr weight does not blend ibl and ssr properly; Fixed the issue that material recive ssr regardless of specular ambient mode;
This commit is contained in:
@@ -55,50 +55,35 @@ float Random(float2 uv)
|
||||
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
float unity_noise_interpolate (float a, float b, float t)
|
||||
inline float2 voronoi_noise_random_vector (float2 UV, float offset)
|
||||
{
|
||||
return (1.0-t)*a + (t*b);
|
||||
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
|
||||
UV = frac(sin(mul(UV, m)) * 46839.32);
|
||||
return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
|
||||
}
|
||||
|
||||
float ValueNoise (float2 uv)
|
||||
float Voronoi(float2 UV, float AngleOffset, float CellDensity)
|
||||
{
|
||||
float2 i = floor(uv);
|
||||
float2 f = frac(uv);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float2 g = floor(UV * CellDensity);
|
||||
float2 f = frac(UV * CellDensity);
|
||||
float t = 8.0;
|
||||
float res = 8.0;
|
||||
|
||||
uv = abs(frac(uv) - 0.5);
|
||||
float2 c0 = i + float2(0.0, 0.0);
|
||||
float2 c1 = i + float2(1.0, 0.0);
|
||||
float2 c2 = i + float2(0.0, 1.0);
|
||||
float2 c3 = i + float2(1.0, 1.0);
|
||||
float r0 = Random(c0);
|
||||
float r1 = Random(c1);
|
||||
float r2 = Random(c2);
|
||||
float r3 = Random(c3);
|
||||
for(int y=-1; y<=1; y++)
|
||||
{
|
||||
for(int x=-1; x<=1; x++)
|
||||
{
|
||||
float2 lattice = float2(x,y);
|
||||
float2 offset = voronoi_noise_random_vector(lattice + g, AngleOffset);
|
||||
float d = distance(lattice + offset, f);
|
||||
if(d < res)
|
||||
{
|
||||
res = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x);
|
||||
float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
|
||||
float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
|
||||
return t;
|
||||
}
|
||||
|
||||
float SimpleNoise(float2 UV, float Scale)
|
||||
{
|
||||
float t = 0.0;
|
||||
|
||||
float freq = pow(2.0, float(0));
|
||||
float amp = pow(0.5, float(3-0));
|
||||
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
|
||||
|
||||
freq = pow(2.0, float(1));
|
||||
amp = pow(0.5, float(3-1));
|
||||
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
|
||||
|
||||
freq = pow(2.0, float(2));
|
||||
amp = pow(0.5, float(3-2));
|
||||
t += ValueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
|
||||
|
||||
return t;
|
||||
return res;
|
||||
}
|
||||
|
||||
float Dither(float In, float4 positionSS)
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
#ifndef UTS_SURFACE_FEATURE_EVALUATION
|
||||
#define UTS_SURFACE_FEATURE_EVALUATION
|
||||
|
||||
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, float3 normalWS, float3 V, inout AggregateLighting aggregateLighting)
|
||||
void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, PreLightData preLightData, float3 N, float3 V, inout AggregateLighting aggregateLighting)
|
||||
{
|
||||
float NdotV = saturate(dot(normalize(V), normalWS));
|
||||
float fresnel = pow(preLightData.NdotV, _StockingFresnelWidth);
|
||||
|
||||
NdotV = pow(NdotV, 2.0);
|
||||
#if _STOCKING_SPARKING_MAP
|
||||
float viewAngleFactor = saturate(1.0 - preLightData.NdotV);
|
||||
float2 shiftedNDC = posInput.positionNDC.xy + viewAngleFactor * 0.05;
|
||||
float spacing = (1.0 - posInput.linearDepth) * _StockingSparkleSpacing;
|
||||
|
||||
// TODO: Move sparkle to bsdf evaluation?
|
||||
// float sparkle = Random(posInput.positionNDC.xy);
|
||||
// sparkle = step(0.995, sparkle);
|
||||
// float noise = SimpleNoise(posInput.positionNDC.xy, 500.0);
|
||||
// sparkle = noise < sparkle ? 1.0 : 0.0;
|
||||
// NOTE: Should we use sparkle texture instead of Voronoi?
|
||||
float screenSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleAmount), 1, 1.0 - Voronoi(shiftedNDC * _ScreenParams.xy / spacing, 5, 5.0));
|
||||
float objectSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleSize), 1, 1.0 - Voronoi(input.texCoord0, 5, 100.0));
|
||||
float sparkle = objectSparkle * screenSparkle * _StockingSparkleIntensity * 5;
|
||||
aggregateLighting.direct.specular += sparkle * aggregateLighting.direct.specular;
|
||||
#endif
|
||||
|
||||
aggregateLighting.direct.diffuse *= NdotV;
|
||||
// aggregateLighting.direct.specular = saturate(aggregateLighting.direct.specular + sparkle * (1.0 - NdotV) * 0.5);
|
||||
aggregateLighting.direct.diffuse *= fresnel;
|
||||
}
|
||||
|
||||
DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData
|
||||
|
||||
@@ -112,7 +112,7 @@ IndirectLighting UtsEvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput,
|
||||
// Apply the weight on the ssr contribution (if required)
|
||||
ApplyScreenSpaceReflectionWeight(ssrLighting);
|
||||
|
||||
reflectionHierarchyWeight = ssrLighting.a;
|
||||
reflectionHierarchyWeight = ssrLighting.a * _SSRWeight;
|
||||
lighting.specularReflected = lerp(lighting.specularReflected, ssrLighting.rgb * preLightData.specularFGD, _SSRWeight);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
|
||||
// 3. Sky Reflection
|
||||
|
||||
// Apply SSR.
|
||||
#if (defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR_TRANSPARENT)) || (!defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR))
|
||||
#if (defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR_TRANSPARENT)) || (!defined(_SURFACE_TYPE_TRANSPARENT) && !defined(_DISABLE_SSR)) && defined(_INDIRECT_SPECULAR_MODE_IBL)
|
||||
{
|
||||
IndirectLighting lighting = UtsEvaluateBSDF_ScreenSpaceReflection(posInput, preLightData, reflectionHierarchyWeight);
|
||||
AccumulateIndirectLighting(lighting, aggregateLighting);
|
||||
@@ -327,9 +327,10 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
|
||||
#endif
|
||||
}
|
||||
|
||||
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING))
|
||||
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
|
||||
{
|
||||
UtsEvaluateLighting_Stocking(fragInputs, posInput, bsdfData.normalWS, V, aggregateLighting);
|
||||
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
|
||||
AccumulateDirectLighting(lighting, aggregateLighting);
|
||||
}
|
||||
|
||||
#ifndef _LIGHT_BASE_RIM_LIGHT_ON
|
||||
@@ -340,10 +341,9 @@ void UtsLightLoop(FragInputs fragInputs, PositionInputs posInput, UtsBSDFData bs
|
||||
}
|
||||
#endif
|
||||
|
||||
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_ANGEL_RING))
|
||||
if (HasFlag(bsdfData.surfaceFeatures, SURFACEFEATURE_STOCKING))
|
||||
{
|
||||
DirectLighting lighting = UtsEvaluateLighting_AngelRing(fragInputs, bsdfData.normalWS, V);
|
||||
AccumulateDirectLighting(lighting, aggregateLighting);
|
||||
UtsEvaluateLighting_Stocking(fragInputs, posInput, preLightData, bsdfData.normalWS, V, aggregateLighting);
|
||||
}
|
||||
|
||||
UtsPostEvaluateBSDF(posInput, preLightData, bsdfData, builtinData, aggregateLighting, lightLoopOutput);
|
||||
|
||||
@@ -117,10 +117,9 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
|
||||
|
||||
if (Max3(lightColor.r, lightColor.g, lightColor.b) > 0.0)
|
||||
{
|
||||
//SHADOW_TYPE sharpShadow = smoothstep(0.4, 0.6, shadow);
|
||||
SHADOW_TYPE sharpShadow = shadow;
|
||||
SHADOW_TYPE sharpShadow = smoothstep(0.3, 0.7, shadow);
|
||||
#if _RECEIVE_HAIR_SHADOW_ON && ENABLE_UTS_HAIR_SHAOW
|
||||
sharpShadow *= GetHairShadow(posInput, L);
|
||||
sharpShadow *= GetHairShadow(posInput, L, bsdfData.normalWS);
|
||||
#endif
|
||||
|
||||
#if _SHADING_MODE_SDF
|
||||
@@ -133,6 +132,8 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
|
||||
|
||||
float3 diffuseTerm = 0.0;
|
||||
float3 specularTerm = ComputeSpecularTerm(bsdfData, preLightData, V, L);
|
||||
|
||||
float NdotL = dot(bsdfData.normalWS, L);
|
||||
|
||||
#if _USE_SHADING_RAMP_MAP_ON
|
||||
float rampMask = _ShadingRampMask;
|
||||
@@ -141,7 +142,6 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
|
||||
#endif
|
||||
|
||||
#if _SHADING_MODE_STANDARD
|
||||
float NdotL = dot(bsdfData.normalWS, L);
|
||||
float halfLambert = 0.5 * NdotL + 0.5;
|
||||
|
||||
float3 rampColor = SAMPLE_TEXTURE2D_ARRAY_LOD(_ShadingRampMap, s_linear_clamp_sampler, float2(halfLambert * sharpShadow.x, rampMask), _ShadingIndex, 0).rgb;
|
||||
@@ -156,7 +156,6 @@ DirectLighting UtsShadeSurface(PositionInputs posInput, UtsBSDFData bsdfData, Pr
|
||||
#endif
|
||||
#else
|
||||
#if _SHADING_MODE_STANDARD
|
||||
float NdotL = dot(bsdfData.normalWS, L);
|
||||
float halfLambert = 0.5 * NdotL + 0.5;
|
||||
|
||||
// float firstColorFeatherForMask = lerp(_1stShadeColorFeather, 0.0, max(_ComposerMaskMode, _FirstShadeOverridden));
|
||||
|
||||
@@ -12,7 +12,6 @@ float3 UtsGetShadowNormal(UtsBSDFData bsdfData)
|
||||
|
||||
float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
|
||||
{
|
||||
// TODO: Move sdf sample result to UtsBSDFData to avoid sampleing in a loop
|
||||
float2 right_uv = float2(1 - uv.x, uv.y);
|
||||
float3 left_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, uv).rgb;
|
||||
float3 right_SDFTex = SAMPLE_TEXTURE2D(_SDFShadingMap, sampler_SDFShadingMap, right_uv).rgb;
|
||||
@@ -27,7 +26,7 @@ float3 SampleSDFTexture(float3 L, float2 uv, out float angle)
|
||||
return isRightSide ? right_SDFTex : left_SDFTex;
|
||||
}
|
||||
|
||||
float GetHairShadow(PositionInputs posInput, float3 L)
|
||||
float GetHairShadow(PositionInputs posInput, float3 L, float N)
|
||||
{
|
||||
float shadow = 1.0;
|
||||
|
||||
@@ -37,16 +36,21 @@ float GetHairShadow(PositionInputs posInput, float3 L)
|
||||
if (hairShadowOpacity > 0.0)
|
||||
{
|
||||
float3 viewLightDir = TransformWorldToViewDir(L);
|
||||
float3 viewOffsetPos = TransformWorldToView(posInput.positionWS) + viewLightDir * _HairShadowDistance * 0.01;
|
||||
float distance = _HairShadowDistance + max(0.0, posInput.linearDepth * _HairShadowDistanceScaleFactor);
|
||||
float3 viewOffsetPos = TransformWorldToView(posInput.positionWS) + viewLightDir * distance * 0.01;
|
||||
float4 clipPos = mul(UNITY_MATRIX_P, float4(viewOffsetPos, 1.0));
|
||||
float2 samplingPointSS = clipPos.xy / clipPos.w;
|
||||
samplingPointSS = samplingPointSS * 0.5 + 0.5;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
samplingPointSS.y = 1.0 - samplingPointSS.y;
|
||||
#endif
|
||||
|
||||
|
||||
float NdotL = saturate(dot(N, L));
|
||||
float slopeBias = (1.0 - NdotL) * _HairShadowDepthBias;
|
||||
|
||||
float2 scaledUVs = samplingPointSS * _RTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
|
||||
float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + _HairShadowDepthBias)).r;
|
||||
float hairShadow = SAMPLE_TEXTURE2D_SHADOW(_HairShadowTex, s_linear_clamp_compare_sampler, float3(scaledUVs, posInput.deviceDepth + slopeBias)).r;
|
||||
shadow = lerp(1.0 - hairShadowOpacity, 1.0, hairShadow);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ TEXTURE2D(_SSSLutMap);
|
||||
TEXTURE2D(_HairBlendingMap);
|
||||
SAMPLER(sampler_HairBlendingMap);
|
||||
|
||||
// Stocking
|
||||
TEXTURE2D(_StockingSparkingMap);
|
||||
SAMPLER(sampler_StockingSparkingMap);
|
||||
|
||||
// Global
|
||||
TEXTURE2D(_HairShadowTex);
|
||||
TEXTURE2D_X(_HairBlendingTex);
|
||||
|
||||
@@ -86,6 +86,13 @@ float _IndirectSpecularMatCapLod;
|
||||
float _IndirectSpecularIntensity;
|
||||
float _SSRWeight;
|
||||
|
||||
// Angle Ring
|
||||
float4 _AngelRingColor;
|
||||
float4 _AngelRingColorMap_ST;
|
||||
float _AngelRingIntensity;
|
||||
float _AngelRingOffsetU;
|
||||
float _AngelRingOffsetV;
|
||||
|
||||
//Rim Light
|
||||
float4 _RimLightColor;
|
||||
float _RimLightIntensity;
|
||||
@@ -96,12 +103,12 @@ float _RimLightClippingLevel;
|
||||
|
||||
float _LightDirectionRimLightLevel;
|
||||
|
||||
// Angle Ring
|
||||
float4 _AngelRingColor;
|
||||
float4 _AngelRingColorMap_ST;
|
||||
float _AngelRingIntensity;
|
||||
float _AngelRingOffsetU;
|
||||
float _AngelRingOffsetV;
|
||||
// Stocking
|
||||
float _StockingFresnelWidth;
|
||||
float _StockingSparkleSpacing;
|
||||
float _StockingSparkleAmount;
|
||||
float _StockingSparkleSize;
|
||||
float _StockingSparkleIntensity;
|
||||
|
||||
// Outline
|
||||
float _OutlineWidth;
|
||||
@@ -127,10 +134,6 @@ float _Minimal_Diffuse_Contribution;
|
||||
// Light Loop
|
||||
float3 _ObjectCenterPositionWS;
|
||||
|
||||
// NOTE: Not sure what these are for
|
||||
// float _FirstShadeOverridden;
|
||||
// float _SecondShadeOverridden;
|
||||
|
||||
float _UseShadowThreshold;
|
||||
float _AlphaCutoffShadow;
|
||||
float _ComposerMaskMode;
|
||||
|
||||
Reference in New Issue
Block a user