// Upgrade NOTE: replaced 'UNITY_PASS_TEXCUBE(unity_SpecCube1)' with 'UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0)' float Test_; struct appdata { float4 vertex : POSITION; float3 normal : NORMAL0; float2 uv : TEXCOORD0; float2 uv2 : TEXCOORD1; float2 uv3 : TEXCOORD2; float2 uv4 : TEXCOORD3; float2 uv5 : TEXCOORD4; float4 Color : COLOR; uint id : SV_VertexID; float4 tangent : TANGENT; }; float FresnelDispersionPower; float FresnelDispersionScale; float ColorByDepth; float CentreIntensity; float4x4 MatrixWorldToObject; float4x4 MatrixWorldToObject2; float4 CentreModel; float lightEstimation2; float MipLevel; samplerCUBE _Environment; half4 _Environment_HDR; float FixedlightEstimation; float ColorIntensity; struct v2f { float2 uv : TEXCOORD0; float2 uv2 : TEXCOORD1; float2 uv3 : TEXCOORD2; float3 WorldBitangent : TEXCOORD3; float3 WorldNormal : TEXCOORD4; float4 vertex : SV_POSITION0; float3 Pos : TEXCOORD5; float3 Pos2 : TEXCOORD6; float3 Normal : NORMAL0; float4 Color : COLOR; uint id : TEXCOORD7; float3 worldPos : TEXCOORD8; float4 tangent : TEXCOORD9; }; // vertex shader v2f vert (appdata v) { v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); float3 _worldTangent = UnityObjectToWorldDir(v.tangent); o.tangent.xyz = _worldTangent; float3 _worldNormal = UnityObjectToWorldNormal(v.normal); o.WorldNormal.xyz = _worldNormal; float _vertexTangentSign = v.tangent.w * unity_WorldTransformParams.w; float3 _worldBitangent = cross(_worldNormal, _worldTangent) * _vertexTangentSign; o.WorldBitangent.xyz = _worldBitangent; float4 pos = v.vertex; pos.xyz = (pos.xyz - CentreModel.xyz); float3 cameraLocalPos; cameraLocalPos = mul(MatrixWorldToObject, float4(_WorldSpaceCameraPos, 1)); o.Pos2 = cameraLocalPos; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.uv2 = v.uv2; o.uv3 = v.uv3; o.Pos = float4(pos.xyz, 1); o.Normal = v.normal; o.Color = v.Color; o.id = v.id; o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; return o; } float Dispersion; float DispersionLimitedAngle; float DispersionR; float DispersionG; float DispersionB; float Brightness; float Power; float DispersionIntensity; sampler2D _ShapeTex; float _Scale; float TotalInternalReflection; int _SizeX; int _SizeY; int _PlaneCount; int _MaxReflection; samplerCUBE ReflectionCube; // samplerCUBE _Environment; // half4 _Environment_HDR; float _RefractiveIndex; float _RefractiveIndex_; float _BaseReflection; #define MAX_REFLECTION (10) float random(float2 st) { float r = frac(sin(dot(st.xy,float2(12.9898, 78.233)))* 43758.5453123); return r * clamp(pow(distance(r, 0.6), 2.5) * 100, 0, 1); } float CalcReflectionRate(float3 normal, float3 ray, float baseReflection, float borderDot) { float normalizedDot = clamp((abs(dot(normal, ray)) - borderDot) / (1.0 - borderDot), 0.0, 1.0); return baseReflection + (1.0-baseReflection)*pow(1.0-normalizedDot, 5); } half rgb2hsv(half3 c) { half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g)); half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return abs(q.z + (q.w - q.y) / (6.0 * d + e)); } float Remap(float value, float min1, float max1, float min2, float max2) { return (min2 + (value - min1) * (max2 - min2) / (max1 - min1)); } float4 GetUnpackedPlaneByIndex(uint index) { int x_index = index % _SizeX; int y_index = index / _SizeX; float ustride = 1.0 / _SizeX; float vstride = 1.0 / _SizeY; float2 uv = float2((0.5+x_index)*ustride, (0.5+y_index)*vstride); float4 packedPlane = tex2D(_ShapeTex, uv); #if !defined(UNITY_COLORSPACE_GAMMA) packedPlane.xyz = LinearToGammaSpace(packedPlane.xyz); #endif float3 normal = packedPlane.xyz*2 - float3(1,1,1); // смена диапозона return float4(normal, packedPlane.w*_Scale); } float CheckCollideRayWithPlane(float3 rayStart, float3 rayNormalized, float4 normalTriangle) // plane - normal.xyz и normal.w - distance { float dp = dot(rayNormalized, normalTriangle.xyz); if( dp < 0 ) { return -1; } else { float distanceNormalized = normalTriangle.w - dot(rayStart.xyz, normalTriangle.xyz); if( distanceNormalized < 0 ) { return -1; } return distanceNormalized / dp; } return -1; } void CollideRayWithPlane(float3 Pos, float PassCount, float3 rayNormalized, float4 TriangleNormal, float startSideRelativeRefraction, out float reflectionRate, out float reflectionRate2, out float3 reflection, out float3 refraction, out float HorizontalElementSquared) { float3 rayVertical = dot(TriangleNormal.xyz, rayNormalized) * TriangleNormal.xyz; reflection = rayNormalized - rayVertical*2.0; float3 rayHorizontal = rayNormalized - rayVertical; float3 refractHorizontal = rayHorizontal * startSideRelativeRefraction ; float horizontalElementSquared = dot(refractHorizontal, refractHorizontal); float borderDot = 0; if( startSideRelativeRefraction > 1.0 ) { borderDot = sqrt(1.0-1.0f/(startSideRelativeRefraction*startSideRelativeRefraction)); } else { borderDot = 0.0; } HorizontalElementSquared = 0; HorizontalElementSquared = horizontalElementSquared /3; if (horizontalElementSquared >= TotalInternalReflection) { HorizontalElementSquared = 0; reflectionRate = 1.0; reflectionRate2 = 1.0; refraction = TriangleNormal.xyz; return; } float verticalSizeSquared = 1-horizontalElementSquared; float3 refractVertical = rayVertical * sqrt( verticalSizeSquared / dot(rayVertical, rayVertical)); refraction = refractHorizontal + refractVertical; reflectionRate = CalcReflectionRate(rayNormalized, TriangleNormal.xyz, _BaseReflection * PassCount, borderDot); reflectionRate2 =0;// CalcReflectionRate(rayNormalized, TriangleNormal.xyz, _BaseReflection * PassCount, borderDot); return; } float3 CalcColorCoefByDistance(float distance,float4 Color) { return lerp(pow(max(Color.xyz, 0.01), distance * Color.w), Color.rgb, ColorByDepth); } float4 SampleEnvironment(float3 rayLocal) { float3 rayWorld = mul(unity_ObjectToWorld, float4(rayLocal, 0)); rayWorld = normalize(rayWorld); #if _CUBEMAPMODE_CUBEMAP float4 tex = texCUBElod(_Environment, float4(rayWorld,MipLevel)); return float4(DecodeHDR(tex, _Environment_HDR), 1); #endif #if _CUBEMAPMODE_REFLECTIONPROBE float4 tex = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0,rayWorld, MipLevel); return float4(DecodeHDR(tex, unity_SpecCube0_HDR), 1); #endif } void CheckCollideRayWithAllPlanes(float3 rayStart, float3 rayDirection, out float4 hitPlane, out float hitTime) { hitTime=1000000.0; hitPlane=float4(1,0,0,1); //[unroll(20)] for(int i=0; i<_PlaneCount; ++i) { float4 plane = GetUnpackedPlaneByIndex(i); float tmpTime = CheckCollideRayWithPlane(rayStart, rayDirection, plane); if(tmpTime >= -0.001 && tmpTime= 2) { i_Pass = 0; } if (i_Pass < 2) { i_Pass = 1; } CollideRayWithPlane(rayStart, i_Pass, tmpRayDirection, hitPlane, refractiveIndex, reflectionRate,reflectionRate2, reflectionRay, refractionRay, PlaneNull); reflectionRates[i] = reflectionRate; reflectionRates2[i] = reflectionRate2; float3 _worldViewDir = UnityWorldSpaceViewDir(rayStart.xyz); _worldViewDir = normalize(_worldViewDir); float fresnelNdotV5 = dot(tmpRayStart, _worldViewDir); float fresnelNode5 = (FresnelDispersionScale * pow(1.0 - fresnelNdotV5, FresnelDispersionPower)); fresnelNode5 = 1; DispersionR = DispersionR * Dispersion * fresnelNode5; DispersionG = DispersionG * Dispersion * fresnelNode5; DispersionB = DispersionB * Dispersion * fresnelNode5; float3 DispersionRay_r = lerp(refractionRay, lerp(rayEnd, refractionRay,2), DispersionR * PlaneNull); float3 DispersionRay_g = lerp(refractionRay, lerp(rayEnd, refractionRay, 2), DispersionG * PlaneNull); float3 DispersionRay_b = lerp(refractionRay, lerp(rayEnd, refractionRay, 2), DispersionB * PlaneNull); refractionColors3[i] = SampleEnvironment(refractionRay); refractionColors2[i] = 1; refractionColors2[i].r = SampleEnvironment(DispersionRay_r).r; refractionColors2[i].g = SampleEnvironment(DispersionRay_g).g; refractionColors2[i].b = SampleEnvironment(DispersionRay_b).b; Color.rgb = lerp(1, Color, ColorIntensity).rgb; depthColors[i] = float4(CalcColorCoefByDistance(hitTime, lerp(Color, 1, lerp(0, (refractionColors3[i].r + refractionColors3[i].g + refractionColors3[i].b) / 2, lighttransmission))), 1); refractionColors2[i] = clamp(lerp(refractionColors3[i], refractionColors2[i], DispersionIntensity),0,1); refractionColors[i] = SampleEnvironment(refractionRay); if (i == loopCount - 1) { reflectionRates[i] = 0.0; reflectionRates2[i] = 0.0; } tmpRayStart = tmpRayStart + tmpRayDirection * hitTime; tmpRayDirection = reflectionRay; } float4 tmpReflectionColor = float4(0, 0, 0, 0); for (int j = loopCount - 1; j >= 0; --j) { tmpReflectionColor = lerp(refractionColors2[j], tmpReflectionColor, reflectionRates[j]) * depthColors[j]; tmpReflectionColor = pow(tmpReflectionColor * Brightness, Power); } if (badRay > 0) { return float4(1, 0, 0, 1); } return tmpReflectionColor; } float4 CalculateContrast(float contrastValue, float4 colorTarget) { float t = 0.5 * (1.0 - contrastValue); return mul(float4x4(contrastValue, 0, 0, t, 0, contrastValue, 0, t, 0, 0, contrastValue, t, 0, 0, 0, 1), colorTarget); } //曝光、饱和、对比调整颜色 float4 ToneMap(float4 MainColor, float brightness, float Disaturate, float _max, float _min, float contrast, float Satur) { fixed4 output = MainColor; output = output * brightness; output = CalculateContrast(contrast, output); float4 disatur = dot(output, float3(0.299, 0.587, 0.114)); // Desaturate output = lerp(output, disatur, clamp(pow(((output.x + output.y + output.z) / 3) * Disaturate, 1.3), 0, 1)); output.x = clamp(Remap(output.x, 0, 1, _min, lerp(_max, 1, 0.5)), 0, 1.5); output.y = clamp(Remap(output.y, 0, 1, _min, lerp(_max, 1, 0.5)), 0, 1.5); output.z = clamp(Remap(output.z, 0, 1, _min, lerp(_max, 1, 0.5)), 0, 1.5); output = pow(output, contrast); output = lerp(clamp(output, 0, _max), output, pow(_max, 4)); output = lerp(smoothstep(output, -0.1, 0.25), output, (1 - distance(1, _max) * 2)); output = lerp(dot(output, float3(0.299, 0.587, 0.114)), output, Satur); output = output * lerp(brightness, 1, 0.75); return output; }