【Blinn-Phong】Phong和Blinn-Phong反射模型

Phong and Blinn-Phong Reflection Model

2023-6-20 21:46:42

The Phong reflection model was proposed by Bui Tuong Phong in 1975, which was used to simulate the reflection attenuation phenomenon on the object’s surface. Well the Blinn-Phong model was a modified version of Phong model by Jim Blinn. In this note, I will firstly introduce the theory of Phong model, and then the Blinn-Phong model, together with its improvement.

Phong Reflection Model

In Phong model, there are several material parameters:

i s i_s is which is the specular intensity;

i d i_d id which is the diffuse intensity;

i a i_a ia which is the ambient intensity;

k s k_s ks which is the specular reflection constant, the ratio of specular reflection of incoming light;

k d k_d kd which is the diffuse reflection constant, the ratio of diffuse reflection of incoming light;

k a k_a ka which is the ambient reflection constant, the ratio of reflection of ambient of all the points in the rendered scene;

α \alpha α is the roughness constant.

In the scene, we have those vectors in the figure:

在这里插入图片描述

in which,

L m ^ \hat{L_m} Lm^ is the direction vector from the point on the surface to the light source;

N ^ \hat{N} N^ is the surface normal;

R m ^ \hat{R_m} Rm^ is the specular reflection vector;

V ^ \hat{V} V^ is the viewer direction vector.

The subscript m m m presents the m t h m_{th} mth light source. Therefore, for each of light sources, the illumination of each point on the surface I P I_P IP can be calculated from:
I P = k a i a + ∑ m ∈ l i g h t s ( k d ( L m ^ ⋅ N ^ ) i m , d + k s ( R m ^ ⋅ V ^ ) α i m , s ) \begin {align*} & I_P = k_ai_a + \sum_{m\in lights}(k_d(\hat{L_m} \cdot \hat{N})i_{m,d}+k_s(\hat{R_m} \cdot \hat{V})^\alpha i_{m,s}) \end {align*} IP=kaia+mlights(kd(Lm^N^)im,d+ks(Rm^V^)αim,s)
The specular highlight of each point on the surface is actually decided by the viewing direction and specular reflection direction. The specular direction vector R m ^ \hat{R_m} Rm^ is calculated as the reflection of L m ^ \hat{L_m} Lm^ on the surface characterized by the surface normal N ^ \hat{N} N^ :

在这里插入图片描述

R m ^ = 2 ( L m ^ ⋅ N ^ ) N ^ − L m ^ \begin {align*} & \hat{R_m} = 2(\hat{L_m} \cdot \hat{N})\hat{N}-\hat{L_m} \end {align*} Rm^=2(Lm^N^)N^Lm^

Blinn-Phong Reflection Model

Remind that in the Phong reflection model, the specular the surface will disappear when the angle between R m ^ \hat{R_m} Rm^ and V ^ \hat{V} V^ is larger than 9 0 ∘ 90^\circ 90 since the dot product of them is negative, which is usually set as zero.

在这里插入图片描述

which results in the effect of cutoff of specular edge of light reflection, as shown in the figure.

在这里插入图片描述

Therefore, a new vector named halfway was introduced to eliminate the negative dot product. The halfway vector is defined as:

在这里插入图片描述

H m ^ = L m ^ + V ^ ∥ L m ^ + V ^ ∥ \begin {align*} & \hat{H_m} = \frac{\hat{L_m}+\hat{V}}{\left \| \hat{L_m}+\hat{V} \right \| } \end {align*} Hm^= Lm^+V^ Lm^+V^
Now just replace the specular term of Phong model:
I B P = k a i a + ∑ m ∈ l i g h t s ( k d ( L m ^ ⋅ N ^ ) i m , d + k s ( N ^ ⋅ H m ^ ) α ′ i m , s ) \begin {align*} & I_{BP} = k_ai_a + \sum_{m\in lights}(k_d(\hat{L_m} \cdot \hat{N})i_{m,d}+k_s(\hat{N} \cdot \hat{H_m})^{\alpha'} i_{m,s}) \end {align*} IBP=kaia+mlights(kd(Lm^N^)im,d+ks(N^Hm^)αim,s)
Because the halfway vector and the surface normal is likely to be smaller than the angle between R m ^ \hat{R_m} Rm^ and V ^ \hat{V} V^ used in Phong’s model (unless the surface is viewed from a very steep angle for which it is likely to be larger), the exponent α ′ \alpha' α can be set α ′ > α \alpha' > \alpha α>α to close the Phong model. The rendering result of Blinn-Phong can be seen in the figure:

在这里插入图片描述

Reference

Phong Reflection Model

Blinn-Phong Reflection Model

OpenGL Tutorial 23 - Blinn-Phong Lighting)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用OpenGL实现Blinn-Phong光照模型的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <GL/glut.h> // 材质参数 GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; // 光源参数 GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; // 窗口大小 int window_width = 800; int window_height = 600; void init(void) { // 初始化材质参数 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // 初始化光源参数 glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); // 启用光照和深度测试 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); } void display(void) { // 清除颜色缓冲区和深度缓冲区 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 绘制一个立方体 glutSolidCube(2.0); // 交换前后缓冲区 glutSwapBuffers(); } void reshape(int width, int height) { // 设置视口大小 glViewport(0, 0, (GLsizei)width, (GLsizei)height); // 设置投影矩阵 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // 设置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // 更新窗口大小变量 window_width = width; window_height = height; } int main(int argc, char** argv) { // 初始化GLUT库 glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(window_width, window_height); glutInitWindowPosition(100, 100); glutCreateWindow("Blinn-Phong Lighting Model"); // 调用初始化函数 init(); // 注册回调函数 glutDisplayFunc(display); glutReshapeFunc(reshape); // 进入主循环 glutMainLoop(); return 0; } ``` 此代码实现了一个简单的立方体和Blinn-Phong光照模型。其中,材质参数和光源参数可以根据需要进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值