-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlight.cpp
More file actions
74 lines (63 loc) · 1.83 KB
/
light.cpp
File metadata and controls
74 lines (63 loc) · 1.83 KB
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
#include "light.h"
#define ran() ( double( rand() % 32768 ) / 32768 )
#define eps 1e-6
Light::Light()
{
sample = rand();
next = NULL;
}
void Light::Input( std::string var , std::stringstream& fin )
{
if ( var == "color=" ) color.Input( fin );
}
void PointLight::Input( std::string var , std::stringstream& fin )
{
if ( var == "O=" ) O.Input( fin );
Light::Input( var , fin );
}
double PointLight::CalnShade( Vector3 C , Object* object_head , int shade_quality )
{
Vector3 V = O - C;
double dist = V.Module();
for ( Object* now = object_head ; now != NULL ; now = now->GetNext() )
if ( now->Collide( C , V ) && ( now->crash.dist < dist ) ) return 0;
return 1;
}
void AreaLight::Input( std::string var , std::stringstream& fin )
{
if ( var == "O=" ) O.Input( fin );
if ( var == "Dx=" ) Dx.Input( fin );
if ( var == "Dy=" ) Dy.Input( fin );
Light::Input( var , fin );
}
bool AreaLight::Collide( Vector3 ray_O , Vector3 ray_V )
{
ray_V = ray_V.GetUnitVector();
Vector3 N = ( Dx * Dy ).GetUnitVector();
double d = N.Dot( ray_V );
if ( fabs( d ) < eps ) return false;
double l = ( N * O.Dot( N ) - ray_O ).Dot( N ) / d;
if ( l < eps ) return false;
Vector3 C = ( ray_O + ray_V * l ) - O;
if ( fabs( Dx.Dot( C ) ) > Dx.Dot( Dx ) ) return false;
if ( fabs( Dy.Dot( C ) ) > Dy.Dot( Dy ) ) return false;
crash_dist = l;
return true;
}
//软阴影的实现
//随机选取shade计算阴影系数
double AreaLight::CalnShade( Vector3 C , Object* object_head , int shade_quality )
{
int shade = 0;
for ( int k = 0 ; k < shade_quality ; k++ )
{
Vector3 V = O - C + Dx * ( ( ran() ) / 2 ) + Dy * ( ( ran() ) / 2 );
double dist = V.Module();
for ( Object* now = object_head ; now != NULL ; now = now->GetNext() )
if ( now->Collide( C , V ) && ( now->crash.dist < dist ) ) {
shade++;
break;
}
}
return 1 - ( double ) shade / ( shade_quality );
}