-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTextureMaterial.h
77 lines (65 loc) · 2.54 KB
/
TextureMaterial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma once
class TextureMaterial: public ObjectMaterial {
public:
TextureMaterial() = default;
TextureMaterial( const char* filename ) {
texture = new Surface( filename );
printf( "Registered texture %s\n", filename );
diffuse = 1.0f;
specular = 0.0f;
}
TextureMaterial( const char* filename, float diffuse ) {
texture = new Surface( filename );
printf( "Registered texture %s\n", filename );
this->diffuse = clamp( diffuse, 0.0f, 1.0f );
specular = 1.0f - this->diffuse;
}
virtual MaterialType getFlag() const override {
if ( diffuse < FLT_EPSILON ) {
return MaterialType::SPECULAR;
}
if ( specular < FLT_EPSILON ) {
return MaterialType::DIFFUSE;
}
return MaterialType::MIX;
}
virtual float3 GetColor( Ray& ray_in ) const override {
uint u = texture->width * ray_in.u;
uint v = texture->height * ray_in.v;
uint skyIdx = ( u & ( texture->width - 1 ) ) + ( v & ( texture->height - 1 ) ) * texture->width;
uint p = texture->pixels[skyIdx];
uint3 i3( ( p >> 16 ) & 255, ( p >> 8 ) & 255, p & 255 );
return float3( i3 ) * correction;
}
virtual bool scatter( Ray& ray_in, float3 I, float3 N, Ray& ray_out ) const override {
if ( diffuse < FLT_EPSILON ) {
// if diffuse is 0, do reflection
ray_out = Ray( I, normalize( reflect( ray_in.D, N ) ) );
return true;
} else if ( specular < FLT_EPSILON ) {
// if specular is 0, do diffuse reflection
ray_out = Ray( I, DiffuseReflection( N ) );
return false;
}
// if both are > 0 we pick one randomly
if ( RandomFloat() < specular ) {
ray_out = Ray( I, normalize( reflect( ray_in.D, N ) ) );
return true;
}
ray_out = Ray( I, DiffuseReflection( N ) );
return false;
}
virtual float* getColorModifier( Ray& ray_in, float3 N ) const {
uint u = texture->width * ray_in.u;
uint v = texture->height * ray_in.v;
uint skyIdx = ( u & ( texture->width - 1 ) ) + ( v & ( texture->height - 1 ) ) * texture->width;
uint p = texture->pixels[skyIdx];
uint3 i3( ( p >> 16 ) & 255, ( p >> 8 ) & 255, p & 255 );
float3 color = float3( i3 ) * SKYDOME_CORRECTION;
return new float[4] { color.x, color.y, color.z, diffuse };
}
Surface* texture;
float diffuse;
float specular;
const float correction = 1.0f / 255.0f;
};