2 рдбреА рд╕реНрдерд╛рдирд┐рдХ рджреВрд░реА рдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рд╣реЗрд░рдлреЗрд░

рдмрд╣реБрднреБрдЬ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╡рд╕реНрддреБ рдХреЛ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдпрджрд┐ рдЖрдк рдРрд╕реА рддрдХрдиреАрдХреЛрдВ рдХреЛ рдмреИрдЪрд┐рдВрдЧ рдФрд░ рдЗрдВрд╕реНрдЯреЗрдВрд╕рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ), рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдПрдХ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде рджреВрд░реА рдХреЗ рдЦреЗрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рджреВрд░реА рдлрд╝реАрд▓реНрдб, рдПрд╕рдбреАрдПрдл), рддреЛ рд╣рдо рдЗрд╕ рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рджреЛ рдкрджреЛрдВ рдореЗрдВ рдПрдХ рд╣реА рд╕рдордиреНрд╡рдп рд╣реИ, рддреЛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рджреВрд░реА рдХреЗ рдХрд╛рд░реНрдп рд╕рдорд╛рди рдорд╛рди рд▓реМрдЯрд╛рдПрдВрдЧреЗ, рдФрд░ рдПрдХ рдЧрдгрдирд╛ рдореЗрдВ рд╣рдо рдХрдИ рдЖрдВрдХрдбрд╝реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рджреВрд░реА рдХреЗ рдЦреЗрддреЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реНрдерд╛рди рдХреЛ рдХреИрд╕реЗ рдмрджрд▓рдирд╛ рд╣реИ, рдореИрдВ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдП рдХрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рджреВрд░реА рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдХреГрддрд┐рдпреЛрдВ рдХреЛ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП рдФрд░ sdf рдЖрдХреГрддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП ред


рд╡рд┐рдиреНрдпрд╛рд╕


рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рд▓рд┐рдП, рдореИрдВ рд╡рд░реНрдЧ рдФрд░ рд╕рд░реНрдХрд▓ рдХреЗ рдмреАрдЪ рдпреБрдЧреНрдорди рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдХрд┐рд╕реА рдЕрдиреНрдп рдЖрдХреГрддрд┐ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдкрд┐рдЫрд▓реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реИред

рдпрд╣рд╛рдВ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЖрдВрдХрдбрд╝реЗ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред

Shader "Tutorial/036_SDF_Space_Manpulation/Type"{ Properties{ _InsideColor("Inside Color", Color) = (.5, 0, 0, 1) _OutsideColor("Outside Color", Color) = (0, .5, 0, 1) _LineDistance("Mayor Line Distance", Range(0, 2)) = 1 _LineThickness("Mayor Line Thickness", Range(0, 0.1)) = 0.05 [IntRange]_SubLines("Lines between major lines", Range(1, 10)) = 4 _SubLineThickness("Thickness of inbetween lines", Range(0, 0.05)) = 0.01 } SubShader{ //the material is completely non-transparent and is rendered at the same time as the other opaque geometry Tags{ "RenderType"="Opaque" "Queue"="Geometry"} Pass{ CGPROGRAM #include "UnityCG.cginc" #include "2D_SDF.cginc" #pragma vertex vert #pragma fragment frag struct appdata{ float4 vertex : POSITION; }; struct v2f{ float4 position : SV_POSITION; float4 worldPos : TEXCOORD0; }; v2f vert(appdata v){ v2f o; //calculate the position in clip space to render the object o.position = UnityObjectToClipPos(v.vertex); //calculate world position of vertex o.worldPos = mul(unity_ObjectToWorld, v.vertex); return o; } float scene(float2 position) { // manipulate position with cool methods here! float2 squarePosition = position; squarePosition = translate(squarePosition, float2(2, 2)); squarePosition = rotate(squarePosition, .125); float squareShape = rectangle(squarePosition, float2(1, 1)); float2 circlePosition = position; circlePosition = translate(circlePosition, float2(1, 1.5)); float circleShape = circle(circlePosition, 1); float combination = merge(circleShape, squareShape); return combination; } float4 _InsideColor; float4 _OutsideColor; float _LineDistance; float _LineThickness; float _SubLines; float _SubLineThickness; fixed4 frag(v2f i) : SV_TARGET{ float dist = scene(i.worldPos.xz); fixed4 col = lerp(_InsideColor, _OutsideColor, step(0, dist)); float distanceChange = fwidth(dist) * 0.5; float majorLineDistance = abs(frac(dist / _LineDistance + 0.5) - 0.5) * _LineDistance; float majorLines = smoothstep(_LineThickness - distanceChange, _LineThickness + distanceChange, majorLineDistance); float distanceBetweenSubLines = _LineDistance / _SubLines; float subLineDistance = abs(frac(dist / distanceBetweenSubLines + 0.5) - 0.5) * distanceBetweenSubLines; float subLines = smoothstep(_SubLineThickness - distanceChange, _SubLineThickness + distanceChange, subLineDistance); return col * majorLines * subLines; } ENDCG } } FallBack "Standard" } 

рдФрд░ shader рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕реНрдерд┐рдд 2D_SDF.cginc рдлрд╝рдВрдХреНрд╢рди, рдЬрд┐рд╕реЗ рд╣рдо рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗ, рдкрд╣рд▓реЗ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 #ifndef SDF_2D #define SDF_2D //transforms float2 rotate(float2 samplePosition, float rotation){ const float PI = 3.14159; float angle = rotation * PI * 2 * -1; float sine, cosine; sincos(angle, sine, cosine); return float2(cosine * samplePosition.x + sine * samplePosition.y, cosine * samplePosition.y - sine * samplePosition.x); } float2 translate(float2 samplePosition, float2 offset){ //move samplepoint in the opposite direction that we want to move shapes in return samplePosition - offset; } float2 scale(float2 samplePosition, float scale){ return samplePosition / scale; } //combinations ///basic float merge(float shape1, float shape2){ return min(shape1, shape2); } float intersect(float shape1, float shape2){ return max(shape1, shape2); } float subtract(float base, float subtraction){ return intersect(base, -subtraction); } float interpolate(float shape1, float shape2, float amount){ return lerp(shape1, shape2, amount); } /// round float round_merge(float shape1, float shape2, float radius){ float2 intersectionSpace = float2(shape1 - radius, shape2 - radius); intersectionSpace = min(intersectionSpace, 0); float insideDistance = -length(intersectionSpace); float simpleUnion = merge(shape1, shape2); float outsideDistance = max(simpleUnion, radius); return insideDistance + outsideDistance; } float round_intersect(float shape1, float shape2, float radius){ float2 intersectionSpace = float2(shape1 + radius, shape2 + radius); intersectionSpace = max(intersectionSpace, 0); float outsideDistance = length(intersectionSpace); float simpleIntersection = intersect(shape1, shape2); float insideDistance = min(simpleIntersection, -radius); return outsideDistance + insideDistance; } float round_subtract(float base, float subtraction, float radius){ return round_intersect(base, -subtraction, radius); } ///champfer float champfer_merge(float shape1, float shape2, float champferSize){ const float SQRT_05 = 0.70710678118; float simpleMerge = merge(shape1, shape2); float champfer = (shape1 + shape2) * SQRT_05; champfer = champfer - champferSize; return merge(simpleMerge, champfer); } float champfer_intersect(float shape1, float shape2, float champferSize){ const float SQRT_05 = 0.70710678118; float simpleIntersect = intersect(shape1, shape2); float champfer = (shape1 + shape2) * SQRT_05; champfer = champfer + champferSize; return intersect(simpleIntersect, champfer); } float champfer_subtract(float base, float subtraction, float champferSize){ return champfer_intersect(base, -subtraction, champferSize); } /// round border intersection float round_border(float shape1, float shape2, float radius){ float2 position = float2(shape1, shape2); float distanceFromBorderIntersection = length(position); return distanceFromBorderIntersection - radius; } float groove_border(float base, float groove, float width, float depth){ float circleBorder = abs(groove) - width; float grooveShape = subtract(circleBorder, base + depth); return subtract(base, grooveShape); } //shapes float circle(float2 samplePosition, float radius){ //get distance from center and grow it according to radius return length(samplePosition) - radius; } float rectangle(float2 samplePosition, float2 halfSize){ float2 componentWiseEdgeDistance = abs(samplePosition) - halfSize; float outsideDistance = length(max(componentWiseEdgeDistance, 0)); float insideDistance = min(max(componentWiseEdgeDistance.x, componentWiseEdgeDistance.y), 0); return outsideDistance + insideDistance; } #endif 


рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐


рджрд░реНрдкрдг рдкреНрд░рддрд┐рдмрд┐рдВрдм


рд╕рдмрд╕реЗ рд╕рд░рд▓ рдСрдкрд░реЗрд╢рдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рджреБрдирд┐рдпрд╛ рдПрдХ рдЕрдХреНрд╖ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛ рд░рд╣реА рд╣реИред рдЗрд╕реЗ y рдЕрдХреНрд╖ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рджрд░реНрдкрдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХреЗ x рдШрдЯрдХ рдХрд╛ рдирд┐рд░рдкреЗрдХреНрд╖ рдорд╛рди рд▓реЗрддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрдХреНрд╖ рдХреЗ рджрд╛рдИрдВ рдФрд░ рдмрд╛рдИрдВ рдУрд░ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕рдорд╛рди рд╣реЛрдВрдЧреЗред (-1, 1) (1, 1) рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕рдордиреНрд╡рдп рдореВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ (1, 1) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╕рд░реНрдХрд▓ рдХреЗ рдЕрдВрджрд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ 0 рд╕реЗ рдЕрдзрд┐рдХ рддреНрд░рд┐рдЬреНрдпрд╛ рдХреЗ рд╕рд╛рде рд╣реЛрддрд╛ рд╣реИред

рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдб position = mirror(position); рдЬреИрд╕рд╛ рдХреБрдЫ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ position = mirror(position); рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдХреЗрд╡рд▓ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдерд┐рддрд┐ рддрд░реНрдХ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрдм рддрд░реНрдХ рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЙрд╕ рдЪрд░ рдХреЛ рднреА рдмрджрд▓ рджреЗрдЧрд╛ рдЬрд┐рд╕реЗ рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рддрдм рдкреНрд░рдХрд╛рд░ рд╢реВрдиреНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЕрднреА рднреА рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

 //in 2D_SDF.cginc void mirror(inout float2 position){ position.x = abs(position.x); } 

 //in shader function mirror(position); 


рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рд╣рдореЗрдВ рдорд┐рд░рд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдзреБрд░реА рдорд┐рд▓рддреА рд╣реИред рд╣рдо рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреЛ рдШреБрдорд╛рдХрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдЖрдВрдХрдбрд╝реЗ рдХреЛ рдШреБрдорд╛рддреЗ рд╕рдордп рдХрд┐рдпрд╛ рдерд╛ред рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреЛ рдШреБрдорд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдлрд┐рд░ рдЗрд╕реЗ рджрд░реНрдкрдг рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдЪрд╛рд▓реВ рдХрд░реЗрдВред рдЗрд╕ рддрд░рд╣ рд╣рдо рдХрд┐рд╕реА рднреА рдХреЛрдг рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдорд┐рд░рд░рд┐рдВрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕реНрдкреЗрд╕ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рддреЗ рд╕рдордп рдФрд░ рдорд┐рд░рд░рд┐рдВрдЧ рдХреЗ рдмрд╛рдж рд░рд┐рд╡рд░реНрд╕ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рддреЗ рд╕рдордп рднреА рдРрд╕рд╛ рд╣реА рд╕рдВрднрд╡ рд╣реИред (рдпрджрд┐ рдЖрдк рджреЛрдиреЛрдВ рдСрдкрд░реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдорд┐рд░рд░рд┐рдВрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдкрд╣рд▓реЗ рдЯреНрд░рд╛рдВрд╕рдлрд╝рд░ рдХрд░рдирд╛ рди рднреВрд▓реЗрдВ, рдФрд░ рдлрд┐рд░ рдореБрдбрд╝реЗрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдЯрд░реНрди рдкрд╣рд▓реЗ рдЖрдПрдЧрд╛ред)

 //in shader function float rotation = _Time.y * 0.25; position = rotate(position, rotation); mirror(position); position = rotate(position, -rotation); 


рдХреЛрд╢рд┐рдХрд╛рдУрдВ


рдпрджрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╢реЛрд░ рдкреАрдврд╝реА рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рддреЛ рдЖрдк рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП рд╣рдо рдЕрдХреНрд╕рд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВ рдФрд░ рдЫреЛрдЯреЗ рд╕реЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рд╕рдорд╛рди рд╣реЛрддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рддреБрдЪреНрдЫ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВред рд╣рдо рджреВрд░ рдХреЗ рдЦреЗрддреЛрдВ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЪреВрдВрдХрд┐ fmod рдлрд╝рдВрдХреНрд╢рди (рд╢реЗрд╖ рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП% рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рд╣рдореЗрдВ рд╢реЗрд╖ рджреЗрддрд╛ рд╣реИ, рд╢реЗрд╖ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдирд╣реАрдВ, рд╣рдореЗрдВ рдПрдХ рдЪрд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо fmod рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдкреВрд░реНрдгрд╛рдВрдХ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд╢реЗрд╖ рднрд╛рдЧ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВред рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╡рд╣реА рд╣реИ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдирдХрд╛рд░рд╛рддреНрдордХ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрд░рд┐рдгрд╛рдо рд╣реИ рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдЕрд╡рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдк рдЗрд╕реЗ рдПрдХ рдЕрд╡рдзрд┐ рдЬреЛрдбрд╝рдХрд░ рдФрд░ рдлрд┐рд░ рд╕реЗ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд╢реЗрд╖ рднрд╛рдЧ рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХ рдЕрд╡рдзрд┐ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдирдХрд╛рд░рд╛рддреНрдордХ рдЗрдирдкреБрдЯ рдорд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓реЗрдЧрд╛, рдФрд░ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдЗрдирдкреБрдЯ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдореВрд▓реНрдп рдПрдХ рдЕрд╡рдзрд┐ рдЕрдзрд┐рдХ рд╣реИред рд╡рд┐рднрд╛рдЬрди рдХреЗ рджреВрд╕рд░реЗ рд╢реЗрд╖ рдирдХрд╛рд░рд╛рддреНрдордХ рдЗрдирдкреБрдЯ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 0 рд╕реЗ рдЕрд╡рдзрд┐ рддрдХ рдХреА рд╕реАрдорд╛ рдореЗрдВ рд╣реИрдВ, рдФрд░ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдЗрдирдкреБрдЯ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдо рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рдЕрд╡рдзрд┐ рдШрдЯрд╛рддреЗ рд╣реИрдВред

 //in 2D_SDF.cginc void cells(inout float2 position, float2 period){ position = fmod(position, period); //negative positions lead to negative modulo position += period; //negative positions now have correct cell coordinates, positive input positions too high position = fmod(position, period); //second mod doesn't change values between 0 and period, but brings down values that are above period. } 

 //in shader function cells(position, float2(3, 3)); 


рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдирд┐рд░рдВрддрд░рддрд╛ рдЦреЛ рджреЗрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдо рджреВрд░реА рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ рдкреНрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ рдЕрдЧрд░ рдЖрдХреГрддрд┐рдпрд╛рдБ рдХреЗрд╡рд▓ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рдмреАрдЪ рдореЗрдВ рд╣реЛрддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдКрдкрд░ рджрд┐рдЦрд╛рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд▓рд╛рдХреГрддрд┐рдпреЛрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рдирд╕реЗ рджреВрд░реА рдХреЗ рдЦреЗрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рджреВрд░реА рдХреЗ рдЦреЗрддреЛрдВ рдХреЛ рдЖрдорддреМрд░ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рд╣рд░ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЕрджреНрднреБрдд рд╣реИ: рд╣рд░ рджреВрд╕рд░реЗ рд╕реЗрд▓ рдХреЛ рдорд┐рд░рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдкрд┐рдХреНрд╕реЗрд▓ рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рднреА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрд╡рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, 0-1 рдкрд╣рд▓реА рд╕реЗрд▓ рд╣реИ, 1-2 рджреВрд╕рд░реА рд╣реИ, рдФрд░ рдЗрд╕реА рддрд░рд╣ ... рдФрд░ рд╣рдо рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВред рд╕реЗрд▓ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рддрдм рдореВрд▓реНрдп рдХреЛ рдЧреЛрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рджреЛрд╣рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрд╖ рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕реЗрд▓ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ; рдЕрдиреНрдпрдерд╛, рд╣рдореЗрдВ рд╣рд░ рдЬрдЧрд╣ рд╕реВрдЪрдХрд╛рдВрдХ 0 рдорд┐рд▓реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдерд┐рддрд┐ рдЕрд╡рдзрд┐ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред

 //in 2D_SDF.cginc float2 cells(inout float2 position, float2 period){ position = fmod(position, period); //negative positions lead to negative modulo position += period; //negative positions now have correct cell coordinates, positive input positions too high position = fmod(position, period); //second mod doesn't change values between 0 and period, but brings down values that are above period. float2 cellIndex = position / period; cellIndex = floor(cellIndex); return cellIndex; } 

рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рде, рд╣рдо рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдлреНрд▓рд┐рдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдлреНрд▓рд┐рдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╛ рдирд╣реАрдВ, рд╣рдо рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдореЛрдбреБрд▓реЛ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВред 2 рдЗрд╕ рдСрдкрд░реЗрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ 0 рдФрд░ 1 рдпрд╛ -1 рд╣реИ рдЬреЛ рд╣рд░ рджреВрд╕рд░реЗ рд╕реЗрд▓ рдореЗрдВ рд╣реИред рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЕрдзрд┐рдХ рд╕реНрдерд╛рдпреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рд░рдкреЗрдХреНрд╖ рдореВрд▓реНрдп рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ 0 рдФрд░ 1 рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реИред

рд╕рд╛рдорд╛рдиреНрдп рдФрд░ рдлрд╝реНрд▓рд┐рдкреНрдб рдкреЛрдЬрд╝рд┐рд╢рди рдХреЗ рдмреАрдЪ рдлрд╝реНрд▓рд┐рдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдлрдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╡реЗрд▓реНрдпреВ 0 рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЬрд┐рд╕ рдкреЛрдЬрд╝рд┐рд╢рди рдореЗрдВ рдлрд╝реНрд▓рд┐рдкрд┐рдВрдЧ рд╣реЛрддрд╛ рд╣реИ, рдЙрд╕ рдкреЛрдЬрд╝рд┐рд╢рди рдХреЛ рдШрдЯрд╛рддрд╛ рд╣реИред 1. рдпрд╣реА рд╣реИ, рд╣рдо рдлреНрд▓рд┐рдк рд╡реИрд░рд┐рдПрдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╕реЗ рдлрд╝реНрд▓рд┐рдк рдкреЛрдЬрд╝рд┐рд╢рди рдХрд╛ рд░реИрдЦрд┐рдХ рдкреНрд░рдХреНрд╖реЗрдк рдХрд░рддреЗ рд╣реИрдВред ред рдЪреВрдВрдХрд┐ рдлреНрд▓рд┐рдк рдЪрд░ 2d рд╡реЗрдХреНрдЯрд░ рд╣реИ, рдЗрд╕рдХреЗ рдШрдЯрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдлрд╝реНрд▓рд┐рдк рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

 //in shader function float2 period = 3; float2 cell = cells(position, period); float2 flip = abs(fmod(cell, 2)); position = lerp(position, period - position, flip); 


рд░реЗрдбрд┐рдпрд▓ рдХреЛрд╢рд┐рдХрд╛рдПрдВ


рдПрдХ рдФрд░ рдорд╣рд╛рди рд╡рд┐рд╢реЗрд╖рддрд╛ рд░реЗрдбрд┐рдпрд▓ рдкреИрдЯрд░реНрди рдореЗрдВ рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╣реИред

рдЗрд╕ рдкреНрд░рднрд╛рд╡ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкрд╣рд▓реЗ рд░реЗрдбрд┐рдпрд▓ рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо x рдЕрдХреНрд╖ рдХреЗ рдХреЗрдВрджреНрд░ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдХреЛрдг рдФрд░ y рдЕрдХреНрд╖ рдХреЗ рд╕рд╛рде рдХреЗрдВрджреНрд░ рд╕реЗ рджреВрд░реА рдХреЛ рд╕рд╛рдВрдХреЗрддрд┐рдХ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВред

 float2 radialPosition = float2(atan2(position.x, position.y), length(position)); 

рдлрд┐рд░ рд╣рдо рдХреЛрдиреЗ рдХреЛ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЯреБрдХрдбрд╝реЗ рдХреЗ рдХреЛрдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ, рд╣рдо рдкрд╣рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдЯреБрдХрдбрд╝реЗ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдкреВрд░рд╛ рд╕рд░реНрдХрд▓ 2 * pi рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рд╣реА рднрд╛рдЧ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо 2 * pi рдХреЛ рд╕реЗрд▓ рдЖрдХрд╛рд░ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВред

 const float PI = 3.14159; float cellSize = PI * 2 / cells; 

рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рде, рд╣рдо рд░реЗрдб рд╕реЗрд▓ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ x рдШрдЯрдХ рдХреЛ рд╣рд░ рд╕реЗрд▓рд╕рд╛рдЗрдЬрд╝ рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ рджреЛрд╣рд░рд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рд╢реЗрд╖ рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрди рджреНрд╡рд╛рд░рд╛ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП, рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рд╣рдореЗрдВ рдирдХрд╛рд░рд╛рддреНрдордХ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рдорд┐рд▓рддреА рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рд╢реЗрд╖ рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрди рдХреЗ рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдорджрдж рд╕реЗ рд╕рдорд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

 radialPosition.x = fmod(fmod(radialPosition.x, cellSize) + cellSize, cellSize); 

рдлрд┐рд░ рдЖрдкрдХреЛ рдирдИ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп xy рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкрд░ рд╡рд╛рдкрд╕ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рд╣рдо рд░реЗрдбрд┐рдпрд▓ рд╕реНрдерд┐рддрд┐ рдХреЗ x рдШрдЯрдХ рдХреЗ рд╕рд╛рде sincos рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдХреЛрдг рдХреЛ x рдХреЛ рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рдордиреНрд╡рдп рдФрд░ y рдХреЛ рд╕рдордиреНрд╡рдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЗрди рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЗрд╕ рдХрджрдо рд╕реЗ рд╣рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреА рд╣реИред рдХреЗрдВрджреНрд░ рд╕реЗ рд╕рд╣реА рджрд┐рд╢рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕реЗ рд░реЗрдбрд┐рдпрд▓ рд╕реНрдерд┐рддрд┐ рдХреЗ рдШрдЯрдХ y рджреНрд╡рд╛рд░рд╛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд▓рдВрдмрд╛рдИ рд╣реИред

 //in 2D_SDF.cginc void radial_cells(inout float2 position, float cells){ const float PI = 3.14159; float cellSize = PI * 2 / cells; float2 radialPosition = float2(atan2(position.x, position.y), length(position)); radialPosition.x = fmod(fmod(radialPosition.x, cellSize) + cellSize, cellSize); sincos(radialPosition.x, position.x, position.y); position = position * radialPosition.y; } 

 //in shader function float2 period = 6; radial_cells(position, period, false); 


рдлрд┐рд░ рд╣рдо рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдФрд░ рдорд┐рд░рд░рд┐рдВрдЧ рднреА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдирд┐рдпрдорд┐рдд рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдерд╛ред

рд░реЗрдбрд┐рдпрд▓ рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд┐рднрд╛рдЬрди рд╕реЗ рдЗрд╕рдХреЗ рд╢реЗрд╖ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗред рд╣рдо рд░реЗрдбрд┐рдпрд▓ рд╕реНрдерд┐рддрд┐ рдХреЗ рдПрдХреНрд╕ рдШрдЯрдХ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдиреАрдЪреЗ рдХреА рдУрд░ рдЧреЛрд▓ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реВрдЪрдХрд╛рдВрдХ рдирдХрд╛рд░рд╛рддреНрдордХ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдпрджрд┐ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╡рд┐рд╖рдо рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 3 рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ 0 рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд╕рд╛рде 1 рд╕реЗрд▓, -1 рдХреЗ рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рд╕рд╛рде 1 рд╕реЗрд▓ рдФрд░ рдЗрдВрдбреЗрдХреНрд╕ 1 рдФрд░ -2 рдХреЗ рд╕рд╛рде 2 рдЖрдзрд╛ рд╕реЗрд▓ рдорд┐рд▓рддреЗ рд╣реИрдВред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ рдиреАрдЪреЗ рд╡рд╛рд▓реЗ рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╕реЗрд▓ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рд╢реЗрд╖ рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВред

 //in 2D_SDF.cginc float cellIndex = fmod(floor(radialPosition.x / cellSize) + cells, cells); //at the end of the function: return cellIndex; 

рдЗрд╕реЗ рдорд┐рд░рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд░реЗрдбрд┐рдпрди рдореЗрдВ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрд╛рд╣рд░ рд░реЗрдбрд┐рдпрд▓ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмреВрд▓ рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рдореЗрдВ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдЬреЛрдбрд╝реЗрдВрдЧреЗред рдЖрдорддреМрд░ рдкрд░ рд╢реЗрдбреНрд╕ рдореЗрдВ, рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ (рдпрджрд┐ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реИ) рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрдХреНрд░реАрди рдкрд░ рд╕рднреА рдкрд┐рдХреНрд╕реЗрд▓ рдПрдХ рд╣реА рдкрде рдХреЗ рд╕рд╛рде рдЬрд╛рдПрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдареАрдХ рд╣реИред

рдорд┐рд░рд░рд┐рдВрдЧ рд░реЗрдбрд┐рдпрд▓ рд╕рдордиреНрд╡рдп рдХреЗ рд▓реВрдк рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдпрд╣ рд╡рд╛рдкрд╕ рдЕрдкрдиреА рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рдПред рд╣рдо рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗ рдХрд┐ рдХреНрдпрд╛ рд╣рдореЗрдВ рд╢реЗрд╖ рдХреЗ рд╕рд╛рде рд╕реЗрд▓ рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ 2 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рдлреНрд▓рд┐рдк рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рд╣рдореЗрдВ рд╢реВрдиреНрдп рдФрд░ рд▓реЛрдЧреЛрдВ рдХреЛ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдИ рдЬреБрдбрд╝рд╡рд╛рдВ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдЬреАрдм рд╣реИ, рдФрд░ рдлрд┐рд░ рднреА рд╣рдо рдЗрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред Deuces рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд╕ рдлреНрд▓рд┐рдк рд╡реЗрд░рд┐рдПрдмрд▓ рд╕реЗ 1 рдШрдЯрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдирд┐рд░рдкреЗрдХреНрд╖ рдорд╛рди рд▓реЗрддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╢реВрдиреНрдп рдФрд░ рдбреНрдпреВрдЬ рдПрдХ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЗрдХрд╛рдЗрдпрд╛рдВ рд╢реВрдиреНрдп рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдореЗрдВ рдЬрд░реВрд░рдд рд╣реИ, рдХреЗрд╡рд▓ рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВред

рдЪреВрдВрдХрд┐ рд╢реВрдиреНрдп рдФрд░ рдЧрд▓рдд рдХреНрд░рдо рдореЗрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрд▓реНрдЯреЗ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдЙрд▓реНрдЯрд╛ рд╕рдВрд╕реНрдХрд░рдг рддрдХ, рдФрд░ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рдЙрд▓реНрдЯрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд╕рдордиреНрд╡рдп рдХреЛ рдкрд▓рдЯрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреЗрд╡рд▓ рд╕реЗрд▓ рдЖрдХрд╛рд░ рд╕реЗ рд╕реНрдерд┐рддрд┐ рдХреЛ рдШрдЯрд╛рддреЗ рд╣реИрдВред

 //in 2D_SDF.cginc float radial_cells(inout float2 position, float cells, bool mirrorEverySecondCell = false){ const float PI = 3.14159; float cellSize = PI * 2 / cells; float2 radialPosition = float2(atan2(position.x, position.y), length(position)); float cellIndex = fmod(floor(radialPosition.x / cellSize) + cells, cells); radialPosition.x = fmod(fmod(radialPosition.x, cellSize) + cellSize, cellSize); if(mirrorEverySecondCell){ float flip = fmod(cellIndex, 2); flip = abs(flip-1); radialPosition.x = lerp(cellSize - radialPosition.x, radialPosition.x, flip); } sincos(radialPosition.x, position.x, position.y); position = position * radialPosition.y; return cellIndex; } 

 //in shader function float2 period = 6; radial_cells(position, period, true); 


рд╕реНтАНрдкреЗрд╕рд┐рдВрдЧ рд╕реНтАНрдкреЗрд╕


рд▓реЗрдХрд┐рди рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рджреЛрд╣рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореВрд▓ рдмрд╛рддреЗрдВ рдкрд░ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рд╣рдордиреЗ рдЗрд╕реЗ рдШреБрдорд╛рдпрд╛, рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕реЗ рдмрдврд╝рд╛рдпрд╛ред рдЖрдк рдирд┐рдореНрди рдХрд╛рд░реНрдп рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рдкреНрд░рддреНрдпреЗрдХ рдЕрдХреНрд╖ рдХреЛ рдПрдХ рд╕рд╛рдЗрди рд╡реЗрд╡ рдХреЗ рд╕рд╛рде рджреВрд╕рд░реЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВред рдЗрд╕рд╕реЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рджреВрд░реА рдлрд╝рдВрдХреНрд╢рди рдХреА рджреВрд░реА рдХрдо рд╕рдЯреАрдХ рд╣реЛ рдЬрд╛рдПрдЧреА, рд▓реЗрдХрд┐рди рдЬрдм рддрдХ рд╡реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реНрд╡рд┐рдВрдЧ рдирд╣реАрдВ рдХрд░рддреЗ, рддрдм рддрдХ рд╕рдм рдХреБрдЫ рдареАрдХ рд░рд╣реЗрдЧрд╛ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо x рдФрд░ y рдШрдЯрдХреЛрдВ рдХреЛ рдлрд╝реНрд▓рд┐рдк рдХрд░рдХреЗ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рднрдпрд╛рд╡рд╣рддрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рд╡реЙрдмрд▓ рдЖрд╡реГрддреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВред рдлрд┐рд░ рд╣рдо рд╕рд╛рдЗрди рдХреЛ рдЗрд╕ рдореВрд▓реНрдп рд╕реЗ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЙрд╕ рд╡реЙрдмрд▓ рдХреА рдорд╛рддреНрд░рд╛ рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдмрд╕ рдЗрд╕ рдбрдЧрдордЧрд╛рдиреЗ рдХрд╛рд░рдХ рдХреЛ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рд╕реНрдерд┐рддрд┐ рдкрд░ рдкрд░рд┐рдгрд╛рдо рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред

 //in 2D_SDF.cginc void wobble(inout float2 position, float2 frequency, float2 amount){ float2 wobble = sin(position.yx * frequency) * amount; position = position + wobble; } 

 //in shader function wobble(position, 5, .05); 


рд╣рдо рдЗрд╕ рд▓рд╣рд░рд╛рддреЗ рдХреЛ рднреА рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдСрдлрд╕реЗрдЯ рд╕реНрдерд┐рддрд┐ рдкрд░ рд▓рд╣рд░рд╛рддреЗ рд╣реБрдП рдФрд░ рд╡рд╛рдкрд╕ рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рд▓реМрдЯ рд╕рдХрддреЗ рд╣реИрдВред рддрд╛рдХрд┐ рдлрд╝реНрд▓реЛрдЯрд┐рдВрдЧ рдкреЙрдЗрдВрдЯ рд╕рдВрдЦреНрдпрд╛ рдмрд╣реБрдд рдмрдбрд╝реА рди рд╣реЛ рдЬрд╛рдП, рдореИрдВ рдмрдЪреЗ рд╣реБрдП pi * 2 рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрди рдХрд░рддрд╛ рд╣реВрдВ рд╡реЛрдмрдмрд▓ рдлрд╝реНрд░реАрдХреНрд╡реЗрдВрд╕реА рдХреЗ рд╕рд╛рде, рдпрд╣ рд╡реЙрдпрдмрд▓ рдХреЗ рд╕рд╛рде рд╕рд╣рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрддрд╛ рд╣реИ (рд╕рд╛рдЗрдирд╕реЙрдЗрдб рд╣рд░ pi * 2 рдпреВрдирд┐рдЯ рдХреЛ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП рд╣рдо рдЬрдВрдк рдФрд░ рдмрд╣реБрдд рдмрдбрд╝реЗ рдСрдлрд╝рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред

 //in shader function const float PI = 3.14159; float frequency = 5; float offset = _Time.y; offset = fmod(offset, PI * 2 / frequency); position = translate(position, offset); wobble(position, 5, .05); position = translate(position, -offset); 


рд╕реНрд░реЛрдд рдХреЛрдб


2 рдбреА рдПрд╕рдбреАрдПрдл рд▓рд╛рдЗрдмреНрд░реЗрд░реА



 #ifndef SDF_2D #define SDF_2D //transforms float2 rotate(float2 samplePosition, float rotation){ const float PI = 3.14159; float angle = rotation * PI * 2 * -1; float sine, cosine; sincos(angle, sine, cosine); return float2(cosine * samplePosition.x + sine * samplePosition.y, cosine * samplePosition.y - sine * samplePosition.x); } float2 translate(float2 samplePosition, float2 offset){ //move samplepoint in the opposite direction that we want to move shapes in return samplePosition - offset; } float2 scale(float2 samplePosition, float scale){ return samplePosition / scale; } //combinations ///basic float merge(float shape1, float shape2){ return min(shape1, shape2); } float intersect(float shape1, float shape2){ return max(shape1, shape2); } float subtract(float base, float subtraction){ return intersect(base, -subtraction); } float interpolate(float shape1, float shape2, float amount){ return lerp(shape1, shape2, amount); } /// round float round_merge(float shape1, float shape2, float radius){ float2 intersectionSpace = float2(shape1 - radius, shape2 - radius); intersectionSpace = min(intersectionSpace, 0); float insideDistance = -length(intersectionSpace); float simpleUnion = merge(shape1, shape2); float outsideDistance = max(simpleUnion, radius); return insideDistance + outsideDistance; } float round_intersect(float shape1, float shape2, float radius){ float2 intersectionSpace = float2(shape1 + radius, shape2 + radius); intersectionSpace = max(intersectionSpace, 0); float outsideDistance = length(intersectionSpace); float simpleIntersection = intersect(shape1, shape2); float insideDistance = min(simpleIntersection, -radius); return outsideDistance + insideDistance; } float round_subtract(float base, float subtraction, float radius){ return round_intersect(base, -subtraction, radius); } ///champfer float champfer_merge(float shape1, float shape2, float champferSize){ const float SQRT_05 = 0.70710678118; float simpleMerge = merge(shape1, shape2); float champfer = (shape1 + shape2) * SQRT_05; champfer = champfer - champferSize; return merge(simpleMerge, champfer); } float champfer_intersect(float shape1, float shape2, float champferSize){ const float SQRT_05 = 0.70710678118; float simpleIntersect = intersect(shape1, shape2); float champfer = (shape1 + shape2) * SQRT_05; champfer = champfer + champferSize; return intersect(simpleIntersect, champfer); } float champfer_subtract(float base, float subtraction, float champferSize){ return champfer_intersect(base, -subtraction, champferSize); } /// round border intersection float round_border(float shape1, float shape2, float radius){ float2 position = float2(shape1, shape2); float distanceFromBorderIntersection = length(position); return distanceFromBorderIntersection - radius; } float groove_border(float base, float groove, float width, float depth){ float circleBorder = abs(groove) - width; float grooveShape = subtract(circleBorder, base + depth); return subtract(base, grooveShape); } // space repetition void mirror(inout float2 position){ position.x = abs(position.x); } float2 cells(inout float2 position, float2 period){ //find cell index float2 cellIndex = position / period; cellIndex = floor(cellIndex); //negative positions lead to negative modulo position = fmod(position, period); //negative positions now have correct cell coordinates, positive input positions too high position += period; //second mod doesn't change values between 0 and period, but brings down values that are above period. position = fmod(position, period); return cellIndex; } float radial_cells(inout float2 position, float cells, bool mirrorEverySecondCell = false){ const float PI = 3.14159; float cellSize = PI * 2 / cells; float2 radialPosition = float2(atan2(position.x, position.y), length(position)); float cellIndex = fmod(floor(radialPosition.x / cellSize) + cells, cells); radialPosition.x = fmod(fmod(radialPosition.x, cellSize) + cellSize, cellSize); if(mirrorEverySecondCell){ float flip = fmod(cellIndex, 2); flip = abs(flip-1); radialPosition.x = lerp(cellSize - radialPosition.x, radialPosition.x, flip); } sincos(radialPosition.x, position.x, position.y); position = position * radialPosition.y; return cellIndex; } void wobble(inout float2 position, float2 frequency, float2 amount){ float2 wobble = sin(position.yx * frequency) * amount; position = position + wobble; } //shapes float circle(float2 samplePosition, float radius){ //get distance from center and grow it according to radius return length(samplePosition) - radius; } float rectangle(float2 samplePosition, float2 halfSize){ float2 componentWiseEdgeDistance = abs(samplePosition) - halfSize; float outsideDistance = length(max(componentWiseEdgeDistance, 0)); float insideDistance = min(max(componentWiseEdgeDistance.x, componentWiseEdgeDistance.y), 0); return outsideDistance + insideDistance; } #endif 

рдмреБрдирд┐рдпрд╛рджреА рдбреЗрдореЛ shader



 Shader "Tutorial/036_SDF_Space_Manpulation/Mirror"{ Properties{ _InsideColor("Inside Color", Color) = (.5, 0, 0, 1) _OutsideColor("Outside Color", Color) = (0, .5, 0, 1) _LineDistance("Mayor Line Distance", Range(0, 2)) = 1 _LineThickness("Mayor Line Thickness", Range(0, 0.1)) = 0.05 [IntRange]_SubLines("Lines between major lines", Range(1, 10)) = 4 _SubLineThickness("Thickness of inbetween lines", Range(0, 0.05)) = 0.01 } SubShader{ //the material is completely non-transparent and is rendered at the same time as the other opaque geometry Tags{ "RenderType"="Opaque" "Queue"="Geometry"} Pass{ CGPROGRAM #include "UnityCG.cginc" #include "2D_SDF.cginc" #pragma vertex vert #pragma fragment frag struct appdata{ float4 vertex : POSITION; }; struct v2f{ float4 position : SV_POSITION; float4 worldPos : TEXCOORD0; }; v2f vert(appdata v){ v2f o; //calculate the position in clip space to render the object o.position = UnityObjectToClipPos(v.vertex); //calculate world position of vertex o.worldPos = mul(unity_ObjectToWorld, v.vertex); return o; } float scene(float2 position) { // modify position here! float2 squarePosition = position; squarePosition = translate(squarePosition, float2(2, 2)); squarePosition = rotate(squarePosition, .125); float squareShape = rectangle(squarePosition, float2(1, 1)); float2 circlePosition = position; circlePosition = translate(circlePosition, float2(1, 1.5)); float circleShape = circle(circlePosition, 1); float combination = merge(circleShape, squareShape); return combination; } float4 _InsideColor; float4 _OutsideColor; float _LineDistance; float _LineThickness; float _SubLines; float _SubLineThickness; fixed4 frag(v2f i) : SV_TARGET{ float dist = scene(i.worldPos.xz); fixed4 col = lerp(_InsideColor, _OutsideColor, step(0, dist)); float distanceChange = fwidth(dist) * 0.5; float majorLineDistance = abs(frac(dist / _LineDistance + 0.5) - 0.5) * _LineDistance; float majorLines = smoothstep(_LineThickness - distanceChange, _LineThickness + distanceChange, majorLineDistance); float distanceBetweenSubLines = _LineDistance / _SubLines; float subLineDistance = abs(frac(dist / distanceBetweenSubLines + 0.5) - 0.5) * distanceBetweenSubLines; float subLines = smoothstep(_SubLineThickness - distanceChange, _SubLineThickness + distanceChange, subLineDistance); return col * majorLines * subLines; } ENDCG } } FallBack "Standard" //fallback adds a shadow pass so we get shadows on other objects } 

рдЕрдм рдЖрдк рд╕рд╛рдЗрди рдбрд┐рд╕реНрдЯреЗрдВрд╕ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд╕рднреА рдореВрд▓ рдмрд╛рддреЗрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдпрд╛рдж рд░рдЦ рд╕рдХрддрд╛ рд╣реВрдВред рдЕрдЧрд▓реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рдореИрдВ рдЙрдирдХреЗ рд╕рд╛рде рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдБрдЧрд╛ред

Source: https://habr.com/ru/post/hi439000/


All Articles