[896] | 1 | #pragma once
|
---|
| 2 | #include "material.hpp"
|
---|
| 3 |
|
---|
| 4 | /*!
|
---|
| 5 | \brief A procedural material.
|
---|
| 6 | */
|
---|
| 7 | class WoodMaterial :
|
---|
| 8 | public Material
|
---|
| 9 | {
|
---|
| 10 | Vector kinks[20];
|
---|
| 11 | public:
|
---|
| 12 |
|
---|
| 13 | WoodMaterial()
|
---|
| 14 | :Material(Vector(0.7f, 0.5f, 0.3f), Vector(0.2f, 0.2f, 0.2f), 4.0f)
|
---|
| 15 | {
|
---|
| 16 | for(int k=0; k<20; k++)
|
---|
| 17 | kinks[k] = Vector(20.0f - 40.0f * rand() / RAND_MAX, -15.5f - 4.0f * rand() / RAND_MAX, 15.0f - 20.0f * rand() / RAND_MAX);
|
---|
| 18 | }
|
---|
| 19 |
|
---|
| 20 | Vector getProceduralDiffuseBrdf(const Vector& atPoint) const |
---|
| 21 | { |
---|
| 22 | float x2 = atPoint.x * atPoint.x; |
---|
| 23 | float y2 = atPoint.y * atPoint.y; |
---|
| 24 | float d = sqrtf(x2 + y2) * 6.0f; |
---|
| 25 | for(int k=0; k < 20; k++) |
---|
| 26 | { |
---|
| 27 | Vector diff; diff.setDifference(kinks[k], atPoint); |
---|
| 28 | d *= 1.0f - (1.0f / (diff.norm2() + 1.0f)); |
---|
| 29 | } |
---|
| 30 | d *= 0.5f; |
---|
| 31 | float c = 1.0f - (1.0f + cosf(d)) / 2.0f; |
---|
| 32 | c *= c; //c *= c; |
---|
| 33 | c = 1.0f - c; |
---|
| 34 | c *= 0.25f; |
---|
| 35 | return Vector(0.35f + c, 0.15f + c, c); |
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | void proceduralScatteringProbability (const Vector& atPoint, const Vector& in, Vector& out, const Vector& normal, Vector& result) const
|
---|
| 39 | {
|
---|
| 40 | float nDotOut = normal * out;
|
---|
| 41 | float nDotIn = - (normal * in);
|
---|
| 42 | if ( nDotOut < 0) {
|
---|
| 43 | result = Vector::RGBBLACK;
|
---|
| 44 | return;
|
---|
| 45 | }
|
---|
| 46 | // add diffuse part
|
---|
| 47 | result = getProceduralDiffuseBrdf(atPoint);
|
---|
| 48 | // add specular using max Phong shading
|
---|
| 49 | Vector idealReflected;
|
---|
| 50 | idealReflected.setIdealReflectedDirection (in, normal);
|
---|
| 51 | float dotProduct = idealReflected* out;
|
---|
| 52 | if(dotProduct > 0)
|
---|
| 53 | {
|
---|
| 54 | float scale = (float)pow (dotProduct, ns) * (ns + 2.0f) * 0.5f / 3.14159265358979323846f ;
|
---|
| 55 | if(nDotOut > nDotIn)
|
---|
| 56 | scale /= nDotOut;
|
---|
| 57 | else
|
---|
| 58 | scale /= nDotIn;
|
---|
| 59 | result += ks * scale;
|
---|
| 60 | } |
---|
| 61 | result *= nDotOut;
|
---|
| 62 | }
|
---|
| 63 | };
|
---|