• 沒有找到結果。

describe their characteristics These parameters describe their characteristics. These parameters are often spatially varying and textures are used to model such spatial variations

N/A
N/A
Protected

Academic year: 2022

Share "describe their characteristics These parameters describe their characteristics. These parameters are often spatially varying and textures are used to model such spatial variations"

Copied!
96
0
0

加載中.... (立即查看全文)

全文

(1)

Texture

Digital Image Synthesis g g y Yung-Yu Chuang

with slides by Pat Hanrahan and Mario Costa Sousa

(2)

Texture

• Recall that materials requires parameters to

describe their characteristics These parameters describe their characteristics. These parameters are often spatially varying and textures are used to model such spatial variations

to model such spatial variations.

• Textures is a function that maps points in some

d i t l i th d i

domain to values in some other domain.

• core/texture.* mipmap.h texture/* (currently 12 plug-ins in total)

• In pbrt, pattern generation is separated from p , p g p

material implementation so that it is more

flexible.

(3)

Texture maps

• How is a texture mapped to the surface?

Di i lit 1D 2D 3D – Dimensionality: 1D, 2D, 3D – Texture coordinates (s,t)

S f t ( )

• Surface parameters (u,v)

• Projection: spherical, cylindrical, planar

• ReparameterizationReparameterization

• What can a texture control?

Surface color and transparency – Surface color and transparency

– Illumination: environment maps, shadow maps Reflection function: reflectance maps

– Reflection function: reflectance maps

– Geometry: displacement and bump maps

(4)

Texture mapping

scene scene (u,v) mapping

p

pp g

(s,t)

T(s,t)

footprint

screen texture T

p

(5)

Texture

(6)

History

• 1974 basic idea (Catmull/Williams) 1976 fl i (Bli /N ll)

• 1976 reflection maps (Blinn/Newell)

• 1978 bump mapping (Blinn)

• 1983 mipmap (Williams)

• 1984 illumination (Miller/Hoffman)

• 1984 illumination (Miller/Hoffman)

• 1985 solid texture (Perlin)

(7)

Texture maps

(8)

Reflection maps

(9)

Environment maps

(10)

Bump/displacement maps

(11)

Illumination maps

(12)

Illumination maps

(13)

Solid textures

(14)

Sampling and antialiasing

• A source of high-frequency variation in the final image Aliasing could be reduced by sampling image. Aliasing could be reduced by sampling, but it is more efficient if a good approximation can be provided

can be provided.

(15)

Sampling and antialiasing

• Antialiasing for textures is not as hopeless as we have seen in chapter 7 because there are we have seen in chapter 7 because there are either analytical forms or ways to avoid adding high frequency

high frequency

• Two problems that must be addressed

1. Compute the sampling rate in texture space 2. Apply sampling theory to guide texture

i

computation

(16)

Finding the texture sampling rate

scene p

p

scene

p

x

p

y

screen texture

(17)

Differential geometry

• DifferentialGeometry : a self-contained representation for a particular point on a

representation for a particular point on a

surface so that all the other operations in pbrt can be executed without referring to the

can be executed without referring to the original shape. It contains

P iti

• Position

• Surface normal

• Parameterization

• Parametric derivatives

• Parametric derivatives

• Derivatives of normals P i t t h

• Pointer to shape

(18)

DifferentialGeometry

struct DifferentialGeometry { ...

// DifferentialGeometry Public Data Point p;

Normal nn;

float u, v;

const Shape *shape;

const Shape *shape;

Vector dpdu, dpdv;

Normal dndu, dndv; ,

mutable Vector dpdx, dpdy;

mutable float dudx, dvdx, dudy, dvdy;

} };

Intersection:GetBSDF() calls

DifferentialGeometry::ComputeDifferentials()

DifferentialGeometry::ComputeDifferentials()

to calculate these values.

(19)

ComputeDifferentials

scene n

p

p

scene

p

x

p

y

n x n p = 0 n

x - n

p = 0

d n

o n p

n

  t

screen n d

(20)

ComputeDifferentials(RayDifferential&)

float d = -Dot(nn, Vector(p.x, p.y, p.z));

Vector rxv(ray.rx.o.x, ray.rx.o.y, ray.rx.o.z);

Vector rxv(ray.rx.o.x, ray.rx.o.y, ray.rx.o.z);

float tx = -(Dot(nn, rxv) + d) / Dot(nn, ray.rx.d); y

Point px = ray.rx.o + tx * ray.rx.d;

Vector ryv(ray.ry.o.x, ray.ry.o.y, ray.ry.o.z);

float ty = -(Dot(nn, ryv) + d)

/ D t( d)

/ Dot(nn, ray.ry.d);

Point py = ray.ry.o + ty * ray.ry.d;

dpdx = px - p;

dpdy = py - p; n d

o n p

n   

dpdy = py p; t nd

(21)

ComputeDifferentials

scene

x v

p

p

scene

v p

v

x

p

x

u p

u

x u

p

y u

p

p

 

' v

p u

p p

p

u v

 

 

 '

 

 

 

 

 

 

v u

p

v

p u

p p p'

screen   

v

(22)

ComputeDifferentials

float A[2][2], Bx[2], By[2], x[2];

// we only need 2 equations; select two axes int axes[2];

if (fabsf(nn.x) > fabsf(nn.y)

&& fabsf(nn.x) > fabsf(nn.z)) { axes[0] = 1; axes[1] = 2;

axes[0] = 1; axes[1] = 2;

}

else if (fabsf(nn.y) > fabsf(nn.z)) { y axes[0] = 0; axes[1] = 2;

}

l {

else {

axes[0] = 0; axes[1] = 1;

}

}

(23)

ComputeDifferentials

// matrices for chosen projection plane A[0][0] = dpdu[axes[0]]; [ ][ ] p [ [ ]]

A[0][1] = dpdv[axes[0]];

A[1][0] = dpdu[axes[1]];

A[1][1] = dpdv[axes[1]];

Bx[0] = px[axes[0]] - p[axes[0]];

Bx[1] = px[axes[1]] - p[axes[1]];

Bx[1] = px[axes[1]] - p[axes[1]];

By[0] = py[axes[0]] - p[axes[0]];

By[1] = py[axes[1]] - p[axes[1]]; y py p

(24)

ComputeDifferentials

if (SolveLinearSystem2x2(A, Bx, x)) { dudx = x[0]; dvdx = x[1]; [ ] [ ]

}

else {

dudx = 1.; dvdx = 0.;

}

if (SolveLinearSystem2x2(A, By, x)) { dudy = x[0]; dvdy = x[1]; y y

}

else {

d d 0 d d 1

dudy = 0.; dvdy = 1.;

}

(25)

Texture coordinate generation

• We use (s,t) for texture coordinate and (u,v) for parametric coordinate

parametric coordinate.

• Creating smooth parameterization of complex h ith l di t ti i till ti meshes with low distortion is still an active research area in graphics.

• Two classes, TextureMapping2D and

TextureMapping3D , provide an interface for

computing these 2D or 3D texture coordinates.

(26)

Texture coordinate generation

class TextureMapping2D {

virtual ~ TextureMapping2D() { }

virtual void Map(const DifferentialGeometry &dg,

float *s, float *t, float *dsdx, float *dtdx, float *dsdy, float *dtdy) const = 0;

};

(u,v) spherical cylindrical planar

(27)

(u.v)-mapping

class UVMapping2D : public TextureMapping2D {

UVMapping2D(float su = 1, float sv = 1,pp g ( , ,

scale

float du = 0, float dv = 0);

...

offset d

u s

s   ts vd

}

void UVMapping2D::Map(const DifferentialGeometry &dg, float *s float *t float *dsdx float *dtdx

u

u

u d

s

st s

v

vd

v

float *s, float *t, float *dsdx, float *dtdx, float *dsdy, float *dtdy) const

{ {

*s = su * dg.u + du; *t = sv * dg.v + dv;

s u v

s u

s

s

 

 

 

x is a function of u v

*dsdx = su * dg.dudx; *dtdx = sv * dg.dvdx;

*dsdy = su * dg dudy; *dtdy = sv * dg dvdy;

s x x

v x

u

x

u

 

 

x is a function of u,v

*dsdy = su * dg.dudy; *dtdy = sv * dg.dvdy;

}

(28)

Spherical mapping

class SphericalMapping2D : public TextureMapping2D { ...

SphericalMapping2D(const Transform &toSph) : WorldToTexture(toSph) { } };

(29)

Spherical mapping

void sphere(Point &p, float *s, float *t) {

Vector v=Normalize(WorldToTexture(p)-Point(0 0 0));

Vector v Normalize(WorldToTexture(p) Point(0,0,0));

float theta = SphericalTheta(v);

float phi = SphericalPhi(v);

*s = theta * INV_PI;

*t = phi * INV_TWOPI;

}

 

s f

s

( p p x ) f

s

( p )

 

x

(30)

Spherical mapping

void SphericalMapping2D::Map(...) {

sphere(dg.p, s, t);

float sx, tx, sy, ty;

const float delta = 1f;

const float delta = .1f;

sphere(dg.p + delta * dg.dpdx, &sx, &tx);

*dsdx = (sx - *s) / delta;

*dtdx = (tx - *t) / delta;

if (*dtdx > .5) *dtdx = 1.f - *dtdx;

else if (*dtdx < -.5f) *dtdx = -(*dtdx + 1);

avoid seam at t=1

else if ( dtdx < .5f) dtdx ( dtdx + 1);

sphere(dg.p + delta * dg.dpdy, &sy, &ty);

*dsdy = (sy - *s) / delta;

*d d ( * ) / d l

*dtdy = (ty - *t) / delta;

if (*dtdy > .5) *dtdy = 1.f - *dtdy;

else if (*dtdy < -.5f) *dtdy = -(*dtdy + 1); ( y ) y ( y );

}

(31)

Spherical mapping

(32)

Cylindrical mapping

t

void cylinder(const Point &p, float *s, float *t) { Vector v=Normalize(WorldToTexture(p)-Point(0 0 0));

s

Vector v=Normalize(WorldToTexture(p) Point(0,0,0));

*s = (M_PI + atan2f(v.y, v.x)) / (2.f * M_PI);

*t = v.z;

}

How to calculate differentials?

}

How to calculate differentials?

(33)

Cylindrical mapping

(34)

Planar mapping

void PlanarMapping2D::Map(DifferentialGeometry &dg, float *s, float *t, float *dsdx, float *dtdx,, , , , float *dsdy, float *dtdy) const {

Vector vec = dg.p - Point(0,0,0);

*s = ds + Dot(vec, vs);

*t = dt + Dot(vec, vt);

*dsdx = Dot(dg dpdx vs);

*dsdx = Dot(dg.dpdx, vs);

*dtdx = Dot(dg.dpdx, vt);

*dsdy = Dot(dg.dpdy, vs);

v

t

y ( g p y, )

v

*dtdy = Dot(dg.dpdy, vt);

}

v

s

d

s,

d

t

Example, for z=0 plane,

v =(1 0 0) v =(0 1 0) d =d =0

v

s

=(1,0,0), v

t

=(0,1,0), d

s

=d

t

=0

(35)

Planar mapping

(36)

3D mapping

class TextureMapping3D { public:

virtual ~TextureMapping3D() { }

virtual Point Map(const DifferentialGeometry &dg, Vector *dpdx Vector *dpdy) const = 0;

Vector *dpdx, Vector *dpdy) const = 0;

};

Point IdentityMapping3D::Map(

const DifferentialGeometry &dg, Vector *dpdx, Vector *dpdy) const Vector dpdx, Vector dpdy) const {

*dpdx = WorldToTexture(dg.dpdx);

*dpdy = WorldToTexture(dg.dpdy);

return WorldToTexture(dg.p);

} }

(37)

Texture

template <class T> class Texture { public:

p

virtual T Evaluate(DifferentialGeometry &) = 0;

virtual ~Texture() { } };

pbrt currently uses only fl t and S t textures

pbrt currently uses only float and Spectrum textures.

(38)

ConstantTexture

template <class T>

class ConstantTexture : public Texture<T> { public:

ConstantTexture(const T &v) { value = v; }

T Evaluate(const DifferentialGeometry &) const { T Evaluate(const DifferentialGeometry &) const {

return value;

}

private:

T value;

};

};

It can be accurately reconstructed from any sampling rate and therefore needs no antialiasing

and therefore needs no antialiasing.

(39)

ScaleTexture

template <class T1, class T2>

class ScaleTexture : public Texture<T2> { public:

// ScaleTexture Public Methods

ScaleTexture(Reference<Texture<T1> > t1 ScaleTexture(Reference<Texture<T1> > t1,

Reference<Texture<T2> > t2) {

tex1 = t1; tex2 = t2;

}

T2 Evaluate(const DifferentialGeometry &dg) const T2 Evaluate(const DifferentialGeometry &dg) const

{

return tex1->Evaluate(dg) * tex2->Evaluate(dg);

} Leave antialiasing to tex1 and tex2; ignore antialiasing of }

private:

Reference<Texture<T1> > tex1;

Leave antialiasing to tex1 and tex2; ignore antialiasing of the product, it is generally fine

Reference<Texture<T2> > tex2;

};

(40)

MixTexture

template <class T>

class MixTexture : public Texture<T> { public:

MixTexture(Reference<Texture<T> > t1, Reference<Texture<T> > t2,

Reference<Texture<float> > amt) {

tex1 = t1; tex2 = t2; amount = amt;; ; ; }

T Evaluate(const DifferentialGeometry &dg) const { T t1=tex1->Evaluate(dg) t2=tex2->Evaluate(dg);

T t1=tex1 >Evaluate(dg), t2=tex2 >Evaluate(dg);

float amt = amount->Evaluate(dg);

return (1.f - amt) * t1 + amt * t2;

} i i ti li i i h

}

private:

Reference<Texture<T> > tex1, tex2;

f fl

again, ignore antialiasing issue here Reference<Texture<float> > amount;

};

(41)

BilerpTexture

BilerpTexture::BilerpTexture(TextureMapping2D *m, const T &t00, const T &t01, const T &t10, const T &t11) {

mapping = m;

v00 = t00;

v01 = t01;

v10 = t10;

v00 s v10

; v11 = t11;

} (s,t)

t T Evaluate(... &dg)

{ fl

float s, t, ...;

mapping->Map(dg, &s, &t,...);

...

}

v01 v11

(42)

Image texture

class ImageTexture : public Texture<T> { public:

ImageTexture(TextureMapping2D *m, string &filename, bool doTri, float maxAniso, ImageWrap wm);

T Evaluate(const DifferentialGeometry &);

only one copy even

~ImageTexture();

private:

static MIPMap<T>

• only one copy even if it is used multiple times

C t d t t T p

*GetTexture(

string &filename, bool doTrilinear

• Converted to type T

• Failed-> 1-image bool doTrilinear,

float maxAniso, ImageWrap wm);

...

MIPMap<T> *mipmap;

TextureMapping2D *mapping;

} };

(43)

Mip maps

• It is more efficient to do antialiasing for textures because

textures because

1. Less expensive to get samples

2 W l filt i i th t t

2. We can apply pre-filtering since the texture function is fully defined

However the sampling

• However, the sampling rate is spatially varying, need to filter over

need to filter over arbitrary regions efficiently

efficiently

• A mipmap takes at most 1/3 more memory

1/3 more memory

(44)

Mipmaps

• Resize by resampling if the original resolution is not power of 2 Apply a box filter to do

not power of 2. Apply a box filter to do downsampling.

typedef enum { TEXTURE_REPEAT, TEXTURE_BLACK, TEXTURE_CLAMP } ImageWrap;

• Use 4 points and Lanczos reconstruction filter

• Implemented as a BlockedArray to improve performance

performance

(45)

Access texel at a level

const T &MIPMap<T>::texel(int level, int s, int t) { const BlockedArray<T> &l = *pyramid[level];

switch (wrapMode) {

case TEXTURE_REPEAT:

s = Mod(s, l.uSize());

t = Mod(t, l.vSize()); break;

case TEXTURE_CLAMP:

s = Clamp(s, 0, l.uSize() - 1);p( , , () );

t = Clamp(t, 0, l.vSize() - 1); break;

case TEXTURE_BLACK: {

static const T black = 0 f;

static const T black = 0.f;

if (s < 0 || s >= l.uSize() ||

t < 0 || t >= l.vSize()) return black; break;

return black; break;

} }

l( )

return l(s, t);

}

(46)

Mipmap lookup

• Return the texel value for a given (s, t)

T h d

• Two methods:

– Triangle filter

– EWA filter

(47)

Mipmap lookup

• Trilinear filtering: level Res.

Lookup(float s, float t, float width)

l n

 2

1

1 ln  1  log w

0 2

n-1

1

w 2 ln 1  log w

choose the level to

: :

l 2

n-1-l

choose the level to

cover four texels : :

n-1 1

(48)

Trilinear filtering

(49)

Trilinear filtering

T Lookup(float s, float t, float width){

float level = nLevels - 1 + Log2(max(width, g ( ( , 1e-8f));

if (level < 0) if (level < 0)

return triangle(0, s, t);

else if (level >= nLevels - 1) else if (level > nLevels 1)

return texel(nLevels-1, 0, 0);

else {

int iLevel = Floor2Int(level);

float delta = level - iLevel;

return (1 delta)*triangle(iLevel s t) return (1-delta)*triangle(iLevel, s, t)

+ delta * triangle(iLevel+1, s, t);

}

}

}

(50)

Trilinear filtering

T triangle(int level, float s, float t) {

{

level = Clamp(level, 0, nLevels-1);

s = s * pyramid[level] >uSize() 0 5f;

s = s * pyramid[level]->uSize() - 0.5f;

t = t * pyramid[level]->vSize() - 0.5f;

int s0 Floor2Int(s) t0 Floor2Int(t);

int s0 = Floor2Int(s), t0 = Floor2Int(t);

float ds = s - s0, dt = t - t0;

t (1 d )*(1 f dt)*t l(l l 0 t0) return (1-ds)*(1.f-dt)*texel(level,s0,t0)

+(1-ds)*dt * texel(level, s0, t0+1) d *(1 dt) * t l(l l 0 1 t0) +ds*(1-dt) * texel(level, s0+1, t0) +ds*dt * texel(level, s0+1, t0+1);

}

(51)

Mipmap lookup

• Elliptically weighted average filtering

(52)

Mipmaps

trilinear EWA

(53)

Solid and procedural texturing

• Solid texture: textures defined over 3D domains;

often requiring a large amount of storage often requiring a large amount of storage

• Procedural texture: short programs are used to

t t t l ( i )

generate texture values (e.g. sine waves)

– Less storage

– Better details (evaluate accurate values when needed; resolution independent)

H d l

– Harder to control

– More difficult to do antialising

(54)

UV texture

Convert (s, t) into first 2 components of

spectrum, mostly for debugging.

(55)

UV texture

Spectrum Evaluate(const DifferentialGeometry &dg) { float s, t, dsdx, dtdx, dsdy, dtdy;, , , , y, y;

mapping->Map(dg, &s, &t, &dsdx,&dtdx,&dsdy,&dtdy);

float cs[COLOR_SAMPLES];

memset(cs, 0, COLOR_SAMPLES * sizeof(float));

cs[0] = s - Floor2Int(s);

cs[1] = t Floor2Int(t);

cs[1] = t - Floor2Int(t);

return Spectrum(cs);

} }

(56)

Checkboard

(57)

Checkerboard2D

class Checkerboard2D : public Texture<T> { Checkerboard2D(TextureMapping2D *m,

Reference<Texture<T>> c1, Reference<Texture<T>> c2, const string &aa);

...

T Evaluate(const DifferentialGeometry &dg) const { float s, t, dsdx, dtdx, dsdy, dtdy;

mapping->Map(dg, &s, &t,&dsdx,&dtdx,&dsdy,&dtdy);

if (aaMethod==CLOSEFORM) {...}

else if (aaMethod==SUPERSAMPLE) { } else if (aaMethod SUPERSAMPLE) {...}

else { // no antialiasing

if ((Floor2Int(s) + Floor2Int(t)) % 2 == 0) return tex1->Evaluate(dg);

return tex2->Evaluate(dg);

} } }

(58)

Close-form

float ds = max(fabsf(dsdx), fabsf(dsdy));

float dt = max(fabsf(dtdx), fabsf(dtdy));

float s0 = s - ds, s1 = s + ds;

float t0 = t - dt, t1 = t + dt;

if (Floor2Int(s0) == Floor2Int(s1) &&( ( ) ( ) Floor2Int(t0) == Floor2Int(t1)) {

if ((Floor2Int(s) + Floor2Int(t)) % 2 == 0)

return tex1->Evaluate(dg);

point sampling

) ,

( t

s t

s    

return tex1 >Evaluate(dg);

return tex2->Evaluate(dg);

}

point sampling

t

 ) ,

( yy )

,

( x

t t x s s

 

 

) ,

( ts ( , )

x t t

x s s

 

 

(59)

Close-form

#define BUMPINT(x) \

(Floor2Int((x)/2) + \

( (( )/ ) \

2.f * max((x/2)-Floor2Int(x/2) - .5f, 0.f)) float sint = (BUMPINT(s1) - BUMPINT(s0)) / (2.f*ds);

float tint = (BUMPINT(t1) - BUMPINT(t0)) / (2.f*dt);

float area2 = sint + tint - 2.f * sint * tint;

if (ds > 1 f || dt > 1 f) area2 = 5f;

if (ds > 1.f || dt > 1.f) area2 = .5f;

return (1.f - area2) * tex1->Evaluate(dg) + area2 * tex2->Evaluate(dg);( g)

x x  x x 1 

( ) 2 2max 2 2 21,0

0

x x

dx x x c

(60)

Close-form

(61)

Supersampling

• Takes a fixed number of stratified samples and applies a Gaussian filter for reconstruction

applies a Gaussian filter for reconstruction

#define SQRT SAMPLES 4

#define SQRT_SAMPLES 4

#define N_SAMPLES (SQRT_SAMPLES * SQRT_SAMPLES) float samples[2*N_SAMPLES];

StratifiedSample2D(samples,SQRT_SAMPLES,SQRT_SAMPLES);

T value = 0.;

fl t filt S 0 float filterSum = 0.;

(62)

Supersampling

for (int i = 0; i < N_SAMPLES; ++i) { float dx = samples[2*i] - 0.5f;

float dy = samples[2*i+1] - 0.5f;

DifferentialGeometry dgs = dg;

dgs p += dx * dgs dpdx + dy * dgs dpdy;

dgs.p += dx dgs.dpdx + dy dgs.dpdy;

dgs.u += dx * dgs.dudx + dy * dgs.dudy;

dgs.v += dx * dgs.dvdx + dy * dgs.dvdy;

...

float ss, ts, dsdxs, dtdxs, dsdys, dtdys;

mapping->Map(dgs,&ss,&ts,&dsdxs,&dtdxs,&dsdys,&dtdys);pp g p( g , , , , , y , y );

float wt = expf(-2.f * (dx*dx + dy*dy));

filterSum += wt;

if ((Fl 2I t( ) + Fl 2I t(t )) % 2 0) if ((Floor2Int(ss) + Floor2Int(ts)) % 2 == 0)

value += wt * tex1->Evaluate(dgs);

else value += wt * tex2->Evaluate(dgs);

}

return value / filterSum;

(63)

Comparisons

no antialiasing

closed-form

l li i

less aliasing but blurring

supersampling

supersampling

less blurring

susceptible to p

aliasing

(64)

Solid checkboard

Checkerboard3D(TextureMapping3D *m,

Reference<Texture<T>> c1, Reference<Texture<T>> c2) , ) {

mapping = m;

tex1 = c1;

tex2 = c2;

} }

if ((Floor2Int(P.x)+Floor2Int(P.y)+ Floor2Int(P.z)) (( ( ) ( y) ( ))

% 2 == 0)

value += wt * tex1->Evaluate(dgs);

else

value += wt * tex2->Evaluate(dgs);

for supersampling

(65)

Solid checkboard

(66)

Some other procedure textures

• Stripe

R d i

• Ramp and sine

• Rings

• Wood

(67)

Stripes on teapot

• Find the integer part of the x-, y-, or z-value of each point of the object

point of the object.

• If resulting value is even

• If resulting value is even,

– then choose red;

– else choose white.

(68)

Ramp and Sine Functions

• A nice ramp: mod(x,a)/a

• This ramp function has a range of zero to one as does

• This ramp function has a range of zero to one, as does (sin(x)+1)/2.

Magenta to value of zero; and yellow to the value one

(69)

Rings on teapot

• Use the x- and y-components to compute the distance of a point from the object’s center, and truncate the p j , result.

• If the resulting value is even,

– then we choose red;

– else we choose white.

(70)

Wood grain

• r=x

2

+y

2

i ( ) (i ( )) % 2

• ring(r) = (int (r)) % 2

• Wobble(r) = ring( r/M + k*sin(θ/N)) z

(71)

Noise

• Real-world objects have both regularity and irregularity in nature

irregularity in nature.

(72)

Perlin noise

• For example, we might want to add “noise” to the stripe function One possibility would be to the stripe function. One possibility would be to add random numbers to the stripe function.

This won’t look good because it looks just like This won t look good because it looks just like white noise in TV.

W t t k it th ith t l i

• We want to make it smoother without losing the random quality.

• Another option is to take a random value at

every lattice point and interpolate them. This

often makes the lattice too obvious.

(73)

Smooth out randomness (1D)

(74)

Perlin noise

• Developed by Ken Perlin for TRON (1982) TRON i h fi 3D h d d hi i

• TRON is the first 3D shaded graphics in a Hollywood film

• Perlin used some tricks to improve the basic to improve the basic lattice approach to achieve “determined achieve determined and coherent

randomness”

randomness

• float Noise(float x,

float y, float z) in

pbrt

(75)

Perlin noise

• Hermite interpolation

Random vectors instead of random values;

• Random vectors instead of random values;

values are derived using inner product Hashing for randomness

• Hashing for randomness

 

 

 

  

1 1 1

( , , )

) , , (

x y z

ijk

x i y j z k

z y x n

 

 

  

 

) ,

, (

) , , (

x

i j y k z

ijk

y j

y

)) ,

, ( )(

( ) ( ) ( )

, ,

( u v w u v w

ijk

u v w

ijk

  

   

1 t

0 1 t

3 t

2 )

( t

3

2

  

)))) (

( (

( i j k

G   

ijk

G (  ( i   ( j   ( k ))))

]

% [ )

( iP i n

P is an array of length n containing a permutation of 0 n-1; n=256 in practice

of 0..n 1; n 256 in practice

G is a precomputed array of n random unit vectors

(76)

Perlin noise (2D illustration)

ijij

j i 1) (

(i1)j

) 1 (

i j

) 1 )(

1

(

(ii1)( jj1)

(77)

Improving Perlin noise (Perlin 2002)

• Two deficiencies:

I t l ti f ti ’ 2 d d i ti i t 12t-6 t – Interpolation function’s 2nd derivative is not zero at either t=0 or t=1, creating 2nd order discontinuities.

Gradient in G are distributed uniformly over a – Gradient in G are distributed uniformly over a

sphere; but, cubic grid has directional biases

(78)

Improving Perlin noise (Perlin 2002)

( t ) 6 t

5

15 t

4

10 t

3

0 t 1 30t

4

-60t

3

+30t

2

120t

3

-180t

2

+60t

• Use only 12 vectors, defined by the directions

120t 180t +60t

from the center of a cube to its edges. It is not

necessary for G to be random since P provides

plenty of randomness.

(79)

Improving Perlin noise (Perlin 2002)

3 4

5

1 10

6 )

1 ( t

3 t

2 )

( t

3

2

  ( t ) 6 t

5

15 t

4

10 t

3

(80)

Improving Perlin noise (Perlin 2002)

uniformly sampled from a sphere use only 12 vectors;

uniformly sampled from a sphere use only 12 vectors;

also faster

(81)

Random Polka dots

• Divide texture space into regular cells; each cell has a 50% chance of having a dot inside it cell has a 50% chance of having a dot inside it.

DotsTexture(TextureMapping2D *m,

Reference<Texture<T>> c1, Reference<Texture<T>> c2) { mapping = m;

{ pp g ;

outsideDot = c1;

insideDot = c2;

} }

(82)

Random Polka dots

T Evaluate(const DifferentialGeometry &dg) const { float s, t, dsdx, dtdx, dsdy, dtdy;

mapping->Map(dg,&s,&t,&dsdx,&dtdx,&dsdy,&dtdy);

int sCell = Floor2Int(s + .5f), tCell = Floor2Int(t + .5f);

if (Noise(sCell+.5f, tCell+.5f) > 0) { float radius = .35f;

float maxShift = 0.5f - radius;

It is deterministic so that it makes consistent decision for pixels.

;

float sCenter = sCell + maxShift *

Noise(sCell + 1.5f, tCell + 2.8f);

float tCenter = tCell + maxShift * float tCenter = tCell + maxShift

Noise(sCell + 4.5f, tCell + 9.8f);

float ds = s - sCenter, dt = t - tCenter;

if (ds*ds + dt*dt < radius*radius) if (ds*ds + dt*dt < radius*radius)

return insideDot->Evaluate(dg);

}

id l (d )

return outsideDot->Evaluate(dg);

}

(83)

Random Polka dots

(84)

Multiple-scale Perlin noise

• Many applications would like to have variation over multiple scales

over multiple scales.

i i

s

x w f s x

f ( )  ( )

i

2

1

i

i

s

1

s 2

1

i

i

w

w

• Application of this to Perlin noise leads to

“Fractional Brownian motion” (FBm)

2

Fractional Brownian motion (FBm)

• Turblence

f

f ( )  ( )

i

i i

s

x w f s x

f ( ) ( )

(85)

(1-D) Perlin Noise Function :

• Get lots of such smooth functions,

with various frequencies and amplitudes

(86)

(1-D) Perlin Noise Function :

• Get lots of such smooth functions,

with various frequencies and amplitudes

• Add them all together to create a nice noisy functiong y

+ + +

+ + =

(87)

(2-D) Perlin Noise Function

(88)

(2-D) Perlin Noise Function

+ + +

+ + =

(89)

Bumpy and wrinkled textures

• FBmTexture uses FBm to compute offset and WrinkledTexture uses Turbulence to do so WrinkledTexture uses Turbulence to do so.

FBmTexture WrinkledTexture

(90)

FBmTexture

FBmTexture(int oct, float roughness, TextureMapping3D *map) {

TextureMapping3D *map) { omega = roughness;

octaves = oct;

octaves = oct;

mapping = map;

} }

T E l t ( t Diff ti lG t &d ){

T Evaluate(const DifferentialGeometry &dg){

Vector dpdx, dpdy;

P i t P i M (d d d d d )

Point P = mapping->Map(dg, &dpdx, &dpdy);

return FBm(P, dpdx, dpdy, omega, octaves);

}

(91)

Windy waves

T WindyTexture:Evaluate(DifferentialGeometry &dg) { Vector dpdx, dpdy;p , p y;

Point P = mapping->Map(dg, &dpdx, &dpdy);

float windStrength = low frequency for local wind strength FBm(.1f * P, .1f * dpdx, .1f * dpdy, .5f, 3);

float waveHeight =

FBm(P dpdx dpdy 5f 6);

amplitude of wave independent of wind FBm(P, dpdx, dpdy, .5f, 6);

return fabsf(windStrength) * waveHeight;

} }

(92)

Windy waves

(93)

Marble

• Perturb texture coordinates before using another texture or lookup table

another texture or lookup table

(94)

Texture Generation using 3D Perlin Noise

Standard 3 dimensional Perlin noise

4 octaves, persistence 0.25 and 0.5

(95)

Texture Generation using 3D Perlin Noise

A marble texture can be made by using a Perlin function as an offset using a Perlin function as an offset to a cosine function.

texture = cosine( x + perlin(x,y,z) )

(96)

Texture Generation using 3D Perlin Noise

• Very nice wood textures can be defined.

• The grain is defined with a low

• The grain is defined with a low persistence function like this:

li ( ) * 20 g = perlin(x,y,z) * 20 grain = g - int(g)

• The very fine bumps you can see on the wood are high frequency noise that has g q y been stretched in one dimension.

bumps = perlin(x*50,y*50,z*20) bu ps pe ( 50,y 50, 0) if bumps < .5

then bumps = 0 else bumps = 1t else bumps = 1t

參考文獻

相關文件

Students in this Learning Unit should recognise the concepts of sample statistics and population parameters and their relationships:. Population Parameter

Simulation conditions are introduced first and various characteristics in three defect designs, such as single mode laser wavelength shift and laser mode change, are analyzed.

introduction to continuum and matrix model formulation of non-critical string theory.. They typically describe strings in 1+0 or 1+1 dimensions with a

Next, according to the bursts selected by a biologist through experience, we will generalize the characteristics and establish three screening conditions.. These three

we often use least squares to get model parameters in a fitting problem... 7 Least

* 1. List any 5 types of market segmentation. Briefly describe the characteristics and contents of a good research report.. Resources for the TEKLA curriculum at

The relationship between these extra type parameters, and the types to which they are associated, is established by parameteriz- ing the interfaces (Java generics, C#, and Eiffel)

A marble texture can be made by using a Perlin function as an offset using a Perlin function as an offset to a cosine function. texture = cosine( x +