[1] 编码实现 Gouraud 明暗处理方法 [2] 编码实现 Phong 明暗处理方法
时间: 2024-01-06 22:04:22 浏览: 74
[1]
Gouraud 明暗处理方法是一种基于顶点颜色插值的渲染技术,可以实现较为逼真的光照效果。具体实现步骤如下:
1. 计算每个顶点的法向量和颜色值;
2. 对于每个光源,计算每个顶点的光照强度;
3. 对于每个像素,使用顶点颜色值的插值计算该像素的颜色值。
代码实现如下:
// 顶点结构体
struct Vertex {
vec3 position;
vec3 normal;
vec3 color;
};
// 光源结构体
struct Light {
vec3 position;
vec3 color;
};
// 计算顶点光照强度
float calculateIntensity(Vertex vertex, Light light) {
vec3 lightDirection = normalize(light.position - vertex.position);
float diffuse = max(dot(vertex.normal, lightDirection), 0.0);
return diffuse * length(light.color);
}
// Gouraud 明暗处理方法
void gouraudShading(Vertex vertex1, Vertex vertex2, Vertex vertex3, Light light) {
// 计算每个顶点的光照强度
float intensity1 = calculateIntensity(vertex1, light);
float intensity2 = calculateIntensity(vertex2, light);
float intensity3 = calculateIntensity(vertex3, light);
// 插值计算每个像素的颜色值
for (int i = 0; i < SCREEN_WIDTH; i++) {
for (int j = 0; j < SCREEN_HEIGHT; j++) {
vec2 pixel = vec2(i, j);
vec3 barycentric = calculateBarycentric(vertex1.position, vertex2.position, vertex3.position, pixel);
vec3 color = barycentric.x * vertex1.color + barycentric.y * vertex2.color + barycentric.z * vertex3.color;
float intensity = barycentric.x * intensity1 + barycentric.y * intensity2 + barycentric.z * intensity3;
setPixelColor(pixel, color * intensity);
}
}
}
[2]
Phong 明暗处理方法是一种基于像素法向量插值的渲染技术,可以实现更加真实的光照效果。具体实现步骤如下:
1. 计算每个顶点的法向量;
2. 对于每个像素,使用顶点法向量的插值计算该像素的法向量;
3. 对于每个光源,计算每个像素的光照强度;
4. 对于每个像素,使用插值后的法向量和光照强度计算该像素的颜色值。
代码实现如下:
// 计算像素法向量插值
vec3 calculateInterpolatedNormal(Vertex vertex1, Vertex vertex2, Vertex vertex3, vec2 pixel) {
vec3 barycentric = calculateBarycentric(vertex1.position, vertex2.position, vertex3.position, pixel);
vec3 normal1 = normalize(vertex1.normal);
vec3 normal2 = normalize(vertex2.normal);
vec3 normal3 = normalize(vertex3.normal);
return normalize(barycentric.x * normal1 + barycentric.y * normal2 + barycentric.z * normal3);
}
// 计算像素光照强度
float calculateIntensity(Vertex vertex, vec3 lightDirection, vec3 viewDirection, float specularPower) {
vec3 reflectDirection = reflect(-lightDirection, vertex.normal);
float diffuse = max(dot(vertex.normal, lightDirection), 0.0);
float specular = pow(max(dot(reflectDirection, viewDirection), 0.0), specularPower);
return diffuse + specular;
}
// Phong 明暗处理方法
void phongShading(Vertex vertex1, Vertex vertex2, Vertex vertex3, Light light, vec3 viewDirection, float specularPower) {
// 插值计算每个像素的法向量
for (int i = 0; i < SCREEN_WIDTH; i++) {
for (int j = 0; j < SCREEN_HEIGHT; j++) {
vec2 pixel = vec2(i, j);
vec3 normal = calculateInterpolatedNormal(vertex1, vertex2, vertex3, pixel);
// 计算每个像素的光照强度
vec3 lightDirection = normalize(light.position - pixel);
float intensity = calculateIntensity(vertex, lightDirection, viewDirection, specularPower);
// 计算每个像素的颜色值
vec3 color = vertex.color * intensity;
setPixelColor(pixel, color);
}
}
}
阅读全文