-
Notifications
You must be signed in to change notification settings - Fork 1
/
shader.h
179 lines (148 loc) · 4.53 KB
/
shader.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#pragma once
#include "tgaimage.h"
#include "renderbuffer.h"
#include "math.h"
#include "vector.h"
#include "matrix.h"
#include "color.h"
struct Material {
TGAImage* diffuse_map;
TGAImage* normal_map;
TGAImage* specular_map;
Color color;
Color specular;
float gloss;
float bump_scale;
};
struct ShaderData {
Material* matrial;
RenderBuffer* targetBuffer;
RenderBuffer* shadow_map;
bool enable_shadow;
Vector3f view_Pos;
Vector3f light_dir;
Color light_color;
Color ambient;
Matrix4f model_matrix;
Matrix4f model_matrix_I;
Matrix4f view_matrix;
Matrix4f projection_matrix;
Matrix4f light_vp_matrix;
Matrix4f camera_vp_matrix;
};
struct shader_struct_a2v {
Vector3f obj_pos;
Vector3f obj_normal;
Vector2f uv;
};
struct shader_struct_v2f {
Vector4f clip_pos;
Vector3f world_pos;
Vector3f world_normal;
Vector2f uv;
float intensity;
};
struct IShader {
ShaderData* shader_data;
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) = 0;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) = 0;
Vector4f ObjectToClipPos(Vector3f pos)
{
return shader_data->camera_vp_matrix * shader_data->model_matrix * embed<4>(pos);
}
Vector4f ObjectToViewPos(Vector3f pos)
{
return shader_data->light_vp_matrix * shader_data->model_matrix * embed<4>(pos);
}
Vector3f ObjectToWorldPos(Vector3f pos)
{
return proj<3>(shader_data->model_matrix * embed<4>(pos));
}
Vector3f ObjectToWorldDir(Vector3f dir)
{
return proj<3>(shader_data->model_matrix * embed<4>(dir, 0.f));
}
Vector3f ObjectToWorldNormal(Vector3f normal)
{
Matrix<1, 4, float> m_normal;
m_normal[0] = embed<4>(normal);
return proj<3>((m_normal * shader_data->model_matrix_I)[0]);
}
Vector3f WorldSpaceViewDir(Vector3f worldPos)
{
return shader_data->view_Pos - worldPos;
}
Vector3f WorldLightDir()
{
return shader_data->light_dir;
}
Color tex_diffuse(const Vector2f& uv)
{
TGAImage* tex = shader_data->matrial->diffuse_map;
Vector2i _uv(uv[0] * tex->get_width(), uv[1] * tex->get_height());
return (Color)(tex->get(_uv[0], _uv[1]));
}
Vector3f tex_normal(const Vector2f& uv)
{
TGAImage* tex = shader_data->matrial->normal_map;
Vector2i _uv(uv[0] * tex->get_width(), uv[1] * tex->get_height());
TGAColor c = tex->get(_uv[0], _uv[1]);
Vector3f res;
for (int i = 0; i < 3; i++)
res[2 - i] = (float)c[i] / 255.f * 2.f - 1.f;
return res;
}
float tex_specular(const Vector2f& uv)
{
TGAImage* tex = shader_data->matrial->specular_map;
Vector2i _uv(uv[0] * tex->get_width(), uv[1] * tex->get_height());
return tex->get(_uv[0], _uv[1])[0] / 1.f;
}
int is_in_shadow(Vector4f depth_pos, float n_dot_l)
{
if (shader_data->enable_shadow && shader_data->shadow_map)
{
float widht = shader_data->shadow_map->width;
float height = shader_data->shadow_map->height;
Vector3f ndc_coords;
ndc_coords = proj<3>(depth_pos / depth_pos[3]);
Vector3f pos = viewport_transform(widht, height, ndc_coords);
float depth_bias = 0.05f * (1 - n_dot_l);
if (depth_bias < 0.005f) depth_bias = 0.01f;
float current_depth = depth_pos[2] - depth_bias;
if (pos.x < 0 || pos.y < 0 || pos.x >= widht || pos.y >= height)
return 1;
float closest_depth = shader_data->shadow_map->get_color(pos.x, pos.y).r;
return current_depth < closest_depth;
}
return 1;
}
};
struct GroundShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};
struct ToonShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};
struct TextureShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};
struct TextureWithLightShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};
struct BlinnShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};
struct NormalMapShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};
struct ShadowShader : public IShader {
virtual shader_struct_v2f vertex(shader_struct_a2v* a2v) override;
virtual bool fragment(shader_struct_v2f* v2f, Color& color) override;
};