SimpleTiles - 图1

    1. // Tiles, Bricks and other Patterns
    2. // SimpleTiles.osl, by Zap Andersson
    3. // Modified: 2019-11-25
    4. // Copyright 2019 Autodesk Inc, All rights reserved. This file is licensed under Apache 2.0 license
    5. // https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt
    6. #define PARAM lookup,fluvw+point(xx,0,0),GapWidth*0.05,Tiling,Edge*0.1,Bump,HitIdx
    7. // Do a single rectangle
    8. int doRect(float loX, float hiX, float loY, float hiY, int Tile, int InIdx, float Radius,
    9. // Layout of these match the PARAM macro above
    10. point uvw, point baseuvw, float GapWidth, vector Tiling, float Edge, output float Bump, output int Index
    11. )
    12. {
    13. float x = uvw[0] / Tiling[0], y = uvw[1] / Tiling[1];
    14. float lox = loX / Tiling[0];
    15. float hix = hiX / Tiling[0];
    16. float loy = loY / Tiling[1];
    17. float hiy = hiY / Tiling[1];
    18. // First quick rejection when being outside the rectangle
    19. if (x < lox + GapWidth ||
    20. x > hix - GapWidth ||
    21. y < loy + GapWidth ||
    22. y > hiy - GapWidth)
    23. return 0;
    24. // Turn coordinate into circle
    25. float gwr = GapWidth + Radius;
    26. float lx = x - (lox + gwr);
    27. float ly = y - (loy + gwr);
    28. float hx = x - (hix - gwr);
    29. float hy = y - (hiy - gwr);
    30. // Now compute special-circle-coordinate
    31. // which is really the edges around the rectangle
    32. vector dp = vector(lx<0?lx:(hx>0?hx:0.0), ly<0?ly:(hy>0.0?hy:0.0), 0.0);
    33. float d = length(dp);
    34. // Outside the radius - we missed
    35. if (d > Radius) return 0;
    36. // Inside? Compute the bump as a Smoothstep
    37. if (Radius > Edge)
    38. Bump = 1.0 - smoothstep(Radius-Edge, Radius+Edge, d);
    39. else
    40. {
    41. // If there is an Edge but the radius is smaller, we
    42. // need to compute the bump differently...
    43. float lx = x - (lox + GapWidth);
    44. float ly = y - (loy + GapWidth);
    45. float hx = x - (hix - GapWidth);
    46. float hy = y - (hiy - GapWidth);
    47. Bump = smoothstep(-Edge, Edge, lx);
    48. Bump *= smoothstep(-Edge, Edge, -hx);
    49. Bump *= smoothstep(-Edge, Edge, ly);
    50. Bump *= smoothstep(-Edge, Edge, -hy);
    51. }
    52. // Set index to inIdx
    53. Index = InIdx;
    54. // Return the tile ID we are in
    55. return Tile;
    56. }
    57. shader SimpleTiles
    58. [[ string help = "<font size=+1><b>Simple Tiles</b></font><br>"
    59. "Allows various kinds of Tiling. The Tiling Offset<br>"
    60. "modifies the base parameter of the tiling layout,<br>"
    61. "and can generate different effects. ",
    62. string category = "Textures",
    63. string label = "Simple Tiles" ]]
    64. (
    65. // Inputs
    66. point UVW = point(u,v,0),
    67. float Scale = 1.0
    68. [[ float min=0.000001, float max=1000000.0 ]],
    69. int TileMode = 0
    70. [[ string widget = "mapper",
    71. string label = "Tiling Mode",
    72. string options =
    73. "Checker Tiles:1"
    74. "|Running/Stack Bond:0"
    75. "|English Bond:2"
    76. "|Fine Running/Stack Bond:3"
    77. "|Twist Box:4",
    78. string help="Choose the kind of tile pattern to use. "
    79. "The 'TilingOffset' parameter adjusts the "
    80. "appearance of the tiles."
    81. ]],
    82. float U_Count = 2.0
    83. [[ string label = "Tiles in U",
    84. float min=0.000001, float max=1000000.0 ]],
    85. float V_Count = 2.0
    86. [[ string label = "Tiles in V",
    87. float min=0.000001, float max=1000000.0 ]],
    88. float TilingOffset = 0.5
    89. [[ string label = "Tiling Offset",
    90. float min=0.0, float max=1.0,
    91. string help = "An adjustable parameter which changes "
    92. "the appearance of the tiling. Does different things "
    93. "for different Tiling Modes" ]],
    94. float GapWidth = 0.1
    95. [[ string label = "Gap Width",
    96. string help = "The width of the gap between tiles",
    97. float min=0.0, float max=10.0 ]],
    98. float Radius = 0.2
    99. [[ string label = "Corner Roundness",
    100. string help = "Adds fillet radius to the corner of the tiles",
    101. float min=0.0, float max=10.0 ]],
    102. float Edge = 0.1
    103. [[ string label = "Edge Width (for Bump)",
    104. string help = "The width of a (slightly beveled) fake 'Edge' "
    105. "to give the tile a more realistic appearance",
    106. float min=0.0, float max=10.0 ]],
    107. float EdgeBump = 1.0
    108. [[ float min=-10.0, float max=10.0,
    109. string help = "The amount of Edge bump effect" ]],
    110. float ColorBump = 0.0
    111. [[ float min=-10.0, float max=10.0,
    112. string help = "Adds some contribution of the color "
    113. "settings to the Bump output" ]],
    114. color GapColor = 0.2
    115. [[ string label = "Gap Color",
    116. string help = "The color of the gap between tiles" ]],
    117. color TileColor1 = 0.4
    118. [[ string label = "Tile Color 1",
    119. string help = "First Tile Color"
    120. ]],
    121. color TileColor2 = 0.5
    122. [[ string label = "Tile Color 2",
    123. string help = "Second Tile Color"
    124. ]],
    125. color TileColor3 = 0.6
    126. [[ string label = "Tile Color 3",
    127. string help = "Third Tile Color. Not all Tiling Modes use this."
    128. ]],
    129. // Outputs
    130. output color Col = 0.0,
    131. output float Bump = 0.0,
    132. output int Tile = 0,
    133. output int TileIdx = 0,
    134. output int Index = 0
    135. )
    136. {
    137. int Overlap = 1;
    138. vector Tiling = vector(U_Count, V_Count, 0.0);
    139. Col = GapColor;
    140. point uvw = UVW * Tiling / Scale;
    141. float to = TilingOffset;
    142. float to2 = to*0.5;
    143. float Roundness = Radius / 10.0;
    144. // Floor of UVW
    145. point fluvw = floor(uvw);
    146. // Fractional UVW
    147. point fruvw = uvw - fluvw;
    148. // Loop over neighbours
    149. for (int xx = -Overlap; xx <= 0; xx++)
    150. {
    151. point lookup = uvw - fluvw - point(xx,0,0);
    152. int HitIdx = 0;
    153. // Running Bond
    154. if (TileMode == 0)
    155. {
    156. if (Tile == 0)
    157. Tile = doRect(0.0 ,1.0, 0.0, 0.5, 1, 1, Roundness, PARAM);
    158. if (Tile == 0)
    159. Tile = doRect(to, to+1.0, 0.5, 1.0, 2, 2, Roundness, PARAM);
    160. }
    161. // Stack Bond
    162. if (TileMode == 1)
    163. {
    164. if (Tile == 0)
    165. Tile = doRect(0.0 ,0.5, 0.0, 0.5, 1, 1, Roundness, PARAM);
    166. if (Tile == 0)
    167. Tile = doRect(0.0, 0.5, 0.5, 1.0, 2, 2, Roundness, PARAM);
    168. if (Tile == 0)
    169. Tile = doRect(0.5 ,1.0, 0.0, 0.5, 2, 3, Roundness, PARAM);
    170. if (Tile == 0)
    171. Tile = doRect(0.5, 1.0, 0.5, 1.0, 1, 4, Roundness, PARAM);
    172. }
    173. // English Bond
    174. if (TileMode == 2)
    175. {
    176. if (Tile == 0)
    177. Tile = doRect(0.0 ,1.0, 0.0, 0.5, 1, 1, Roundness, PARAM);
    178. if (Tile == 0)
    179. Tile = doRect(0.0+to2, 0.5+to2, 0.5, 1.0, 2, 2, Roundness, PARAM);
    180. if (Tile == 0)
    181. Tile = doRect(0.5+to2, 1.0+to2, 0.5, 1.0, 2, 3, Roundness, PARAM);
    182. }
    183. // Fine Running Bond
    184. if (TileMode == 3)
    185. {
    186. if (Tile == 0)
    187. Tile = doRect(0.0 ,1.0, 0.0, 0.5, 1, 1, Roundness, PARAM);
    188. if (Tile == 0)
    189. Tile = doRect(0.0+to, 0.5+to, 0.5, 0.75, 2, 2, Roundness, PARAM);
    190. if (Tile == 0)
    191. Tile = doRect(0.5+to, 1.0+to, 0.5, 0.75, 2, 3, Roundness, PARAM);
    192. if (Tile == 0)
    193. Tile = doRect(0.0+to2, 0.5+to2, 0.75, 1.0, 3, 4, Roundness, PARAM);
    194. if (Tile == 0)
    195. Tile = doRect(0.5+to2, 1.0+to2, 0.75, 1.0, 3, 5, Roundness, PARAM);
    196. }
    197. // Twist Box
    198. if (TileMode == 4)
    199. {
    200. if (Tile == 0)
    201. Tile = doRect(0.0, 1.0-to2, 0.0, to2, 1, 1, Roundness, PARAM);
    202. if (Tile == 0)
    203. Tile = doRect(to2, 1.0, 1.0-to2, 1.0, 1, 2, Roundness, PARAM);
    204. if (Tile == 0)
    205. Tile = doRect(0.0, to2, to2, 1.0, 2, 3, Roundness, PARAM);
    206. if (Tile == 0)
    207. Tile = doRect(1.0-to2, 1.0, 0.0, 1.0-to2, 2, 4, Roundness, PARAM);
    208. if (Tile == 0)
    209. Tile = doRect(to2, 1.0-to2, to2, 1.0-to2, 3, 5, Roundness, PARAM);
    210. }
    211. if (HitIdx > 0)
    212. {
    213. TileIdx = HitIdx;
    214. Index = HitIdx + int((float)cellnoise(fluvw+point(xx,0,0)) * 1024.0);
    215. }
    216. }
    217. if (Tile == 1) Col = TileColor1;
    218. if (Tile == 2) Col = TileColor2;
    219. if (Tile == 3) Col = TileColor3;
    220. Bump *= EdgeBump;
    221. Bump += dot(0.3333, Col) * ColorBump;
    222. }