
// Tiles, Bricks and other Patterns// SimpleTiles.osl, by Zap Andersson// Modified: 2019-11-25// Copyright 2019 Autodesk Inc, All rights reserved. This file is licensed under Apache 2.0 license// https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt#define PARAM lookup,fluvw+point(xx,0,0),GapWidth*0.05,Tiling,Edge*0.1,Bump,HitIdx// Do a single rectangle int doRect(float loX, float hiX, float loY, float hiY, int Tile, int InIdx, float Radius, // Layout of these match the PARAM macro above point uvw, point baseuvw, float GapWidth, vector Tiling, float Edge, output float Bump, output int Index){ float x = uvw[0] / Tiling[0], y = uvw[1] / Tiling[1]; float lox = loX / Tiling[0]; float hix = hiX / Tiling[0]; float loy = loY / Tiling[1]; float hiy = hiY / Tiling[1]; // First quick rejection when being outside the rectangle if (x < lox + GapWidth || x > hix - GapWidth || y < loy + GapWidth || y > hiy - GapWidth) return 0; // Turn coordinate into circle float gwr = GapWidth + Radius; float lx = x - (lox + gwr); float ly = y - (loy + gwr); float hx = x - (hix - gwr); float hy = y - (hiy - gwr); // Now compute special-circle-coordinate // which is really the edges around the rectangle vector dp = vector(lx<0?lx:(hx>0?hx:0.0), ly<0?ly:(hy>0.0?hy:0.0), 0.0); float d = length(dp); // Outside the radius - we missed if (d > Radius) return 0; // Inside? Compute the bump as a Smoothstep if (Radius > Edge) Bump = 1.0 - smoothstep(Radius-Edge, Radius+Edge, d); else { // If there is an Edge but the radius is smaller, we // need to compute the bump differently... float lx = x - (lox + GapWidth); float ly = y - (loy + GapWidth); float hx = x - (hix - GapWidth); float hy = y - (hiy - GapWidth); Bump = smoothstep(-Edge, Edge, lx); Bump *= smoothstep(-Edge, Edge, -hx); Bump *= smoothstep(-Edge, Edge, ly); Bump *= smoothstep(-Edge, Edge, -hy); } // Set index to inIdx Index = InIdx; // Return the tile ID we are in return Tile;}shader SimpleTiles [[ string help = "<font size=+1><b>Simple Tiles</b></font><br>" "Allows various kinds of Tiling. The Tiling Offset<br>" "modifies the base parameter of the tiling layout,<br>" "and can generate different effects. ", string category = "Textures", string label = "Simple Tiles" ]]( // Inputs point UVW = point(u,v,0), float Scale = 1.0 [[ float min=0.000001, float max=1000000.0 ]], int TileMode = 0 [[ string widget = "mapper", string label = "Tiling Mode", string options = "Checker Tiles:1" "|Running/Stack Bond:0" "|English Bond:2" "|Fine Running/Stack Bond:3" "|Twist Box:4", string help="Choose the kind of tile pattern to use. " "The 'TilingOffset' parameter adjusts the " "appearance of the tiles." ]], float U_Count = 2.0 [[ string label = "Tiles in U", float min=0.000001, float max=1000000.0 ]], float V_Count = 2.0 [[ string label = "Tiles in V", float min=0.000001, float max=1000000.0 ]], float TilingOffset = 0.5 [[ string label = "Tiling Offset", float min=0.0, float max=1.0, string help = "An adjustable parameter which changes " "the appearance of the tiling. Does different things " "for different Tiling Modes" ]], float GapWidth = 0.1 [[ string label = "Gap Width", string help = "The width of the gap between tiles", float min=0.0, float max=10.0 ]], float Radius = 0.2 [[ string label = "Corner Roundness", string help = "Adds fillet radius to the corner of the tiles", float min=0.0, float max=10.0 ]], float Edge = 0.1 [[ string label = "Edge Width (for Bump)", string help = "The width of a (slightly beveled) fake 'Edge' " "to give the tile a more realistic appearance", float min=0.0, float max=10.0 ]], float EdgeBump = 1.0 [[ float min=-10.0, float max=10.0, string help = "The amount of Edge bump effect" ]], float ColorBump = 0.0 [[ float min=-10.0, float max=10.0, string help = "Adds some contribution of the color " "settings to the Bump output" ]], color GapColor = 0.2 [[ string label = "Gap Color", string help = "The color of the gap between tiles" ]], color TileColor1 = 0.4 [[ string label = "Tile Color 1", string help = "First Tile Color" ]], color TileColor2 = 0.5 [[ string label = "Tile Color 2", string help = "Second Tile Color" ]], color TileColor3 = 0.6 [[ string label = "Tile Color 3", string help = "Third Tile Color. Not all Tiling Modes use this." ]], // Outputs output color Col = 0.0, output float Bump = 0.0, output int Tile = 0, output int TileIdx = 0, output int Index = 0 ){ int Overlap = 1; vector Tiling = vector(U_Count, V_Count, 0.0); Col = GapColor; point uvw = UVW * Tiling / Scale; float to = TilingOffset; float to2 = to*0.5; float Roundness = Radius / 10.0; // Floor of UVW point fluvw = floor(uvw); // Fractional UVW point fruvw = uvw - fluvw; // Loop over neighbours for (int xx = -Overlap; xx <= 0; xx++) { point lookup = uvw - fluvw - point(xx,0,0); int HitIdx = 0; // Running Bond if (TileMode == 0) { if (Tile == 0) Tile = doRect(0.0 ,1.0, 0.0, 0.5, 1, 1, Roundness, PARAM); if (Tile == 0) Tile = doRect(to, to+1.0, 0.5, 1.0, 2, 2, Roundness, PARAM); } // Stack Bond if (TileMode == 1) { if (Tile == 0) Tile = doRect(0.0 ,0.5, 0.0, 0.5, 1, 1, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.0, 0.5, 0.5, 1.0, 2, 2, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.5 ,1.0, 0.0, 0.5, 2, 3, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.5, 1.0, 0.5, 1.0, 1, 4, Roundness, PARAM); } // English Bond if (TileMode == 2) { if (Tile == 0) Tile = doRect(0.0 ,1.0, 0.0, 0.5, 1, 1, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.0+to2, 0.5+to2, 0.5, 1.0, 2, 2, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.5+to2, 1.0+to2, 0.5, 1.0, 2, 3, Roundness, PARAM); } // Fine Running Bond if (TileMode == 3) { if (Tile == 0) Tile = doRect(0.0 ,1.0, 0.0, 0.5, 1, 1, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.0+to, 0.5+to, 0.5, 0.75, 2, 2, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.5+to, 1.0+to, 0.5, 0.75, 2, 3, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.0+to2, 0.5+to2, 0.75, 1.0, 3, 4, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.5+to2, 1.0+to2, 0.75, 1.0, 3, 5, Roundness, PARAM); } // Twist Box if (TileMode == 4) { if (Tile == 0) Tile = doRect(0.0, 1.0-to2, 0.0, to2, 1, 1, Roundness, PARAM); if (Tile == 0) Tile = doRect(to2, 1.0, 1.0-to2, 1.0, 1, 2, Roundness, PARAM); if (Tile == 0) Tile = doRect(0.0, to2, to2, 1.0, 2, 3, Roundness, PARAM); if (Tile == 0) Tile = doRect(1.0-to2, 1.0, 0.0, 1.0-to2, 2, 4, Roundness, PARAM); if (Tile == 0) Tile = doRect(to2, 1.0-to2, to2, 1.0-to2, 3, 5, Roundness, PARAM); } if (HitIdx > 0) { TileIdx = HitIdx; Index = HitIdx + int((float)cellnoise(fluvw+point(xx,0,0)) * 1024.0); } } if (Tile == 1) Col = TileColor1; if (Tile == 2) Col = TileColor2; if (Tile == 3) Col = TileColor3; Bump *= EdgeBump; Bump += dot(0.3333, Col) * ColorBump;}