180 likes | 421 Views
RenderMan - Writing RenderMan Shaders (2)- . Transforming Tiles. Transforming texture coordinates has an "inverse" effect on the appearance of the pattern
E N D
Transforming Tiles • Transforming texture coordinates has an "inverse" effect on the appearance of the pattern • if you scale the texture coordinates by a factor of 2, the frequency of the pattern will double and the pattern will appear twice as small • positive translations will move the pattern up and to the left (the opposite direction) • positive clockwise rotations will rotate the pattern counter-clockwise
Transforming Tiles • Rotating Tiles • rotate2d(float x, y, angle, ox, oy, rx, ry) • Rotates a 2D point (x, y) clockwise by a specified angle (in radians) about an origin (ox, oy) and stores the resulting point in (rx, ry). • To rotate the ‘cross’ shader, we replace the lines ss = repeat(s, freq); tt = repeat(t, freq); with rotate2d(s, t, radians(45), 0.5, 0.5, ss, tt); ss = repeat(ss, freq); tt = repeat(tt, freq);
/* rotcross.sl */ surface rotcross() { color surface_color, layer_color, surface_opac, layer_opac; float fuzz = 0.05; float ss, tt; float freq = 4; /* background layer */ surface_color = Cs; surface_opac = Os; /* rotate 45 degrees and repeat pattern 'freq' times horizontally & vertically */ rotate2d(s, t, radians(45), 0.5, 0.5, ss, tt); ss = repeat(ss, freq); tt = repeat(tt, freq); /* vertical bar layer */ layer_color = color (0.1, 0.5, 0.1); layer_opac = pulse(0.35, 0.65, fuzz, ss); surface_color = blend(surface_color, layer_color, layer_opac); /* horizontal bar layer */ layer_color = color (0.1, 0.1, 0.3); layer_opac = pulse(0.35, 0.65, fuzz, tt); surface_color = blend(surface_color, layer_color, layer_opac); /* output */ Oi = surface_opac; Ci = surface_opac * surface_color; }
Transforming Tiles • Shifting Rows or Columns of Tiles • Alternating rows (or columns) of tiles can be staggered by • using repeat, whichtile, and odd and/or even to determine if the current tile is in an odd or even row; and then • shifting or not shifting texture or coordinates appropriately. • to shift even rows of a pattern by a 1/2 tile, you would add 0.5 to ss after it has been repeated. You still need to remember to mod ss with 1 so that it stays in the range 0 to 1. row = whichtile(t, freq); if (even(row)) ss = mod(ss + 0.5, 1);
/* shiftedblocks.sl */ surface shiftedblocks() { color surface_color, layer_color; color layer_opac; float ss, tt; float row; float fuzz = 0.05; float freq = 4; surface_color = Cs; /* shift even rows 1/2 tile */ ss = repeat(s, freq); tt = repeat(t, freq); row = whichtile(t, freq); if (even(row)) ss = mod(ss + 0.5, 1); /* squares */ layer_color = color (0.3, 0.0, 0.3); layer_opac = intersection(pulse(0.35, 0.65, fuzz, ss), pulse(0.35, 0.65, fuzz, tt)); surface_color = blend(surface_color, layer_color, layer_opac); /* output */ Ci = surface_color; }
Transforming Tiles • Polar Coordinates • Polar coordinates are useful for generating radially shaped patterns (flowers, stars, etc.). The convenience function topolar2d converts a 2-D point in Cartesian coordinates to polar coordinates. • topolar2d(float x, y, r, theta) • Transforms a 2-D point (x,y) in Cartesian coordinates to polar coordinates expressed in terms of r (distance from the origin) and theta (the angle expressed in radians). theta will be in the range [-PI, PI].
Shape Generation • Simple, geometric shapes can be made in the RenderMan Shading Language using smoothstep or pulse often with one of two shading language distance functions: • float distance(point p1, p2) • float ptlined(point a, b, p)
Shape Generation • Rectangles • Rectangular shapes can be made by intersecting (multiplying) a vertical pulse and a horizontal pulse. • you can use intersection instead of the multiplication operator.
/* rect.sl */ surface rect() { color surface_color, layer_color; color layer_opac; float fuzz = 0.025; color red = color (1,0,0); float left, right, top, bottom; surface_color = Cs; layer_color = red; left = 0.05; right = 0.75; /* rectangle sides */ top = 0.1; bottom = 0.7; layer_opac = pulse(left, right, fuzz, s) * pulse(top, bottom, fuzz, t); surface_color = blend(surface_color, layer_color, layer_opac); Ci = surface_color; }
Shape Generation • Disks and Rings • disks and rings can be generated using distance and either smoothstep (for a disk) or pulse (for a ring). • this pulse is generated by 1 - smoothstep(radius - fuzz, radius, d)
surface disk() { color surface_color, layer_color; color layer_opac; float fuzz = 0.025; color blue = color (0,0,1); point center; float radius; float d; surface_color = Cs; layer_color = blue; center = (0.5, 0.5, 0); /* location of center of disk */ radius = 0.35; /* radius of disk */ d = distance(center, (s, t, 0)); layer_opac = 1 - smoothstep(radius - fuzz, radius, d); surface_color = blend(surface_color, layer_color, layer_opac); Ci = surface_color; } surface ring() { color surface_color, layer_color; color layer_opac; float fuzz = 0.025; color blue = color (0,0,1); point center; float radius, half_width; float d; surface_color = Cs; layer_color = blue; center = (0.5, 0.5, 0); /* position of ring */ radius = 0.35; /* radius of ring */ half_width = 0.05; /* 1/2 width of ring */ d = distance(center, (s, t, 0)); layer_opac = pulse(radius - half_width, radius + half_width, fuzz, d); surface_color = blend(surface_color, layer_color, layer_opac); Ci = surface_color; }
Shape Generation • Lines
surface line() { color surface_color, layer_color; color layer_opac; float fuzz = 0.025; color green = color (0,0.5,0); point p1, p2; float half_width; float d; surface_color = Cs; layer_color = green; p1 = (0.25, 0.15, 0); /* endpoint #1 */ p2 = (0.85, 0.7, 0); /* endpoint #2 */ half_width = 0.05; /* 1/2 line width */ d = ptlined(p1, p2, (s, t, 0)); layer_opac = 1 - smoothstep(half_width - fuzz, half_width, d); surface_color = blend(surface_color, layer_color, layer_opac); Ci = surface_color; }
surface moon() { color surface_color, layer_color; color layer_opac; float fuzz = 0.01; float circle1, circle2, radius, d; point center; surface_color = color (0.05, 0.05, 0.15); fuzz = 0.01; /* moon radius */ radius = 0.45; /* moon color */ layer_color = color(1, 1, 0.9); /* first circle */ center = (.5, .5, 0); d = distance(center, (s, t, 0)); circle1 = 1 - smoothstep(radius - fuzz, radius, d); /* second circle */ center = (.65, .5, 0); d = distance(center, (s, t, 0)); circle2 = 1 - smoothstep(radius - fuzz, radius, d); /* use difference of two circles to create moon */ layer_opac = difference(circle1, circle2); surface_color = blend(surface_color, layer_color, layer_opac); Ci = surface_color; }
disk = D square = S union(D,S) intersection(D,S) difference(D,S) difference(S,D) complement (difference(D,S)) union(difference(S,D), difference(D,S)) Shape Generation • Boolean Operations • various boolean operations based on disk and square shapes.
surface diskring() { color surface_color = 0, layer_color, color layer_opac; float fuzz = 0.01; point center; float ss, tt; float radius, d, half_width; float disk, ring; /* disk */ ss = repeat(s, 2); tt = repeat(t, 2); center = (0.5, 0.5, 0); radius = 0.35; d = distance(center, (ss, tt, 0)); disk = 1 - smoothstep(radius - fuzz, radius, d); /* ring */ ss = repeat(s, 5); tt = repeat(t, 5); center = (0.5, 0.5, 0); radius = 0.35; half_width = 0.05; d = distance(center, (ss, tt, 0)); ring = pulse(radius - half_width, radius + half_width, fuzz, d); /* bool disk & ring */ layer_color = color (1, 0.2, 0.2); layer_opac = union(difference(disk, ring), difference(ring, disk)); surface_color = blend(surface_color, layer_color, layer_opac); Ci = surface_color; }
Homework • 태극기 Shader • flag.rib, flag.sl, flag.tif • mailto:blue@cglab.cse.cau.ac.kr • 다음주 수요일까지