|
1317 | 1317 | Those checker odd/even parameters can point to a constant texture or to some other procedural
|
1318 | 1318 | texture. This is in the spirit of shader networks introduced by Pat Hanrahan back in the 1980s.
|
1319 | 1319 |
|
| 1320 | +<div class='together'> |
| 1321 | +To support procedural textures, we'll extend the `lambertian` class to work with textures instead of |
| 1322 | +colors: |
| 1323 | + |
| 1324 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1325 | + #include "texture.h" |
| 1326 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1327 | + |
| 1328 | + ... |
| 1329 | + class lambertian : public material { |
| 1330 | + public: |
| 1331 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1332 | + lambertian(const color& a) : albedo(make_shared<solid_color>(a)) {} |
| 1333 | + lambertian(shared_ptr<texture> a) : albedo(a) {} |
| 1334 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1335 | + |
| 1336 | + bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) |
| 1337 | + const override { |
| 1338 | + auto scatter_direction = rec.normal + random_unit_vector(); |
| 1339 | + |
| 1340 | + // Catch degenerate scatter direction |
| 1341 | + if (scatter_direction.near_zero()) |
| 1342 | + scatter_direction = rec.normal; |
| 1343 | + |
| 1344 | + scattered = ray(rec.p, scatter_direction, r_in.time()); |
| 1345 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1346 | + attenuation = albedo->value(rec.u, rec.v, rec.p); |
| 1347 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1348 | + return true; |
| 1349 | + } |
| 1350 | + |
| 1351 | + private: |
| 1352 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1353 | + shared_ptr<texture> albedo; |
| 1354 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1355 | + }; |
| 1356 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1357 | + [Listing [lambertian-textured]: <kbd>[material.h]</kbd> Lambertian material with texture] |
| 1358 | + |
| 1359 | +</div> |
| 1360 | + |
1320 | 1361 | <div class='together'>
|
1321 | 1362 | If we add this to our `random_scene()` function’s base sphere:
|
1322 | 1363 |
|
|
1346 | 1387 | </div>
|
1347 | 1388 |
|
1348 | 1389 | <div class='together'>
|
1349 |
| -We get: |
| 1390 | +we get: |
1350 | 1391 |
|
1351 | 1392 | 
|
|
1579 | 1620 |
|
1580 | 1621 | </div>
|
1581 | 1622 |
|
1582 |
| -<div class='together'> |
1583 |
| -Now we can make textured materials by replacing the `const color& a` with a texture pointer: |
1584 |
| - |
1585 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1586 |
| - #include "texture.h" |
1587 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1588 |
| - |
1589 |
| - ... |
1590 |
| - class lambertian : public material { |
1591 |
| - public: |
1592 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1593 |
| - lambertian(const color& a) : albedo(make_shared<solid_color>(a)) {} |
1594 |
| - lambertian(shared_ptr<texture> a) : albedo(a) {} |
1595 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1596 |
| - |
1597 |
| - bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) |
1598 |
| - const override { |
1599 |
| - auto scatter_direction = rec.normal + random_unit_vector(); |
1600 |
| - |
1601 |
| - // Catch degenerate scatter direction |
1602 |
| - if (scatter_direction.near_zero()) |
1603 |
| - scatter_direction = rec.normal; |
1604 |
| - |
1605 |
| - scattered = ray(rec.p, scatter_direction, r_in.time()); |
1606 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1607 |
| - attenuation = albedo->value(rec.u, rec.v, rec.p); |
1608 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1609 |
| - return true; |
1610 |
| - } |
1611 |
| - |
1612 |
| - private: |
1613 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1614 |
| - shared_ptr<texture> albedo; |
1615 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1616 |
| - }; |
1617 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1618 |
| - [Listing [lambertian-textured]: <kbd>[material.h]</kbd> Lambertian material with texture] |
1619 |
| - |
1620 |
| -</div> |
1621 |
| - |
1622 | 1623 | From the hitpoint $\mathbf{P}$, we compute the surface coordinates $(u,v)$. We then use these to
|
1623 | 1624 | index into our procedural solid texture (like marble). We can also read in an image and use the 2D
|
1624 | 1625 | $(u,v)$ texture coordinate to index into the image.
|
|
0 commit comments