Shader "Custom/StandartTile" { Properties { _TileTexture("Tile Texture", 2D) = "white" {} _GroutTexture("Grout Texture", 2D) = "black" {} _TileNormalMap("Tile Normal Map", 2D) = "bump" {} _TileWidth("Tile Width (in)", Float) = 6.0 _TileHeight("Tile Height (in)", Float) = 6.0 _GroutWidth("Grout Width (in)", Float) = 2.0 _RotationAngle("Rotation Angle (degrees)", Float) = 0.0 _TileSmoothness("Tile Smoothness", Range(0, 1)) = 0.5 _TileNormalScale("Tile Normal Scale", Range(0, 10)) = 1.0 _GroutColor("Grout Color", Color) = (0.1, 0.1, 1, 1) } SubShader { Tags { "RenderType" = "Opaque" } LOD 200 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _TileTexture; sampler2D _GroutTexture; sampler2D _TileNormalMap; float _TileWidth; float _TileHeight; float _GroutWidth; float _RotationAngle; float _TileSmoothness; float _TileNormalScale; fixed4 _GroutColor; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); // Поворачиваем UV-координаты на указанный угол float rad = radians(_RotationAngle); float2 rotatedUV = float2(v.uv.x * cos(rad) - v.uv.y * sin(rad), v.uv.x * sin(rad) + v.uv.y * cos(rad)); o.uv = rotatedUV; return o; } fixed4 frag(v2f i) : SV_Target { float tileWidthMeters = _TileWidth * 0.0254; float tileHeightMeters = _TileHeight * 0.0254; float groutWidthMeters = _GroutWidth * 0.0254; float2 tileSize = float2(tileWidthMeters, tileHeightMeters); float2 groutSize = float2(groutWidthMeters, groutWidthMeters); float2 tileWithGroutSize = tileSize + groutSize; float2 tilePos = frac(float2(i.uv.x, 1.0 - i.uv.y) / tileWithGroutSize); bool isTile = tilePos.x < tileWidthMeters / tileWithGroutSize.x && tilePos.y < tileHeightMeters / tileWithGroutSize.y; fixed4 color = isTile ? tex2D(_TileTexture, tilePos / (tileWidthMeters / tileWithGroutSize.x)) : _GroutColor; float3 normalTex = isTile ? UnpackNormal(tex2D(_TileNormalMap, tilePos / (tileWidthMeters / tileWithGroutSize.x))) : float3(0.0, 0.0, 1.0); float normalScale = isTile ? _TileNormalScale : 1.0; // Scale the normal float3 normal = normalize(float3(normalTex.xy * normalScale, normalTex.z)); float smoothness = isTile ? _TileSmoothness : 0.0; // Simulate fixed lighting effect float3 fixedLightDir = normalize(float3(0.5, 0.5, 0.5)); float NdotL = max(0.0, dot(normal, fixedLightDir)); float3 reflectDir = reflect(-fixedLightDir, normal); float3 specular = pow(max(dot(reflectDir, fixedLightDir), 0.0), 16.0) * smoothness; float3 ambient = 0.5 * color.rgb; // Increased ambient for visibility float3 diffuse = NdotL * color.rgb; float3 finalColor = ambient + diffuse + specular; return fixed4(finalColor, color.a); } ENDCG } } FallBack "Diffuse" }