Lighting with GLSL Phong Model

参考:

http://www.ozone3d.net/tutorials/glsl_lighting_phong.php#part_1

1 - Summary of the Phong Lighting Equation

The final color of the pixel displayed is given by the following equation:

If = Ia + Id + Is

where If is the intensity of the pixel final color, Ia is the intensity of the ambient color, Id is the intensity of the diffuse color and Is the intensity of the specular color. Ia, Id and Is are all four-dimensional RGBA vectors.

The Ia term is the ambient component. Ia is the result of the multiplication between the ambient component of the light and the ambient component of the material which composes the surface of the 3d object:

Ia = (Al * Am) + (As * Am)

where Al is the ambient component of the light and Am the ambient component of the material. Ia is generally a constant RGBA vector, and can even be pre-computed for the shader (this value is the same one independently from the pixel). A more advanced expression of this ambient term could be given by the Ambient Occlusion Lighting technique.

In OpenGL terms, As is defined as:

float As[4] = {0.1f, 0.1f, 0.1f, 1.0f };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, As );

With Demoniak3D, As is defined in the scene node:

<scene>
	<global_ambient_light r="0.1" g="0.1" b="0.1" a="1.0" />
</scene>

The Id term expresses the final diffuse component. This component is given by the following equation:

Id = Dl * Dm * LambertTerm

where Dl is the diffuse component of the light and Dm the diffuse component of the material. The LambertTerm factor is the keystone of the lighting equations. It is actually the value of this factor which will make it possible to create the self shadow of a 3d object (self-shadowing). This Lambert coefficient is calculated with the following dot product:

LambertTerm = dot(N, L)

where N is the normal vector to the considered pixel and L the light vector at the same pixel. This simple relation but so fundamental, tells us that the value of the Lambert coefficient will be maximum (i.e. equals to 1.0) if the angle between the two vectors (L and N) equals zero, i.e. if the pixel is directly in front of the light. For all the other cases, the Lambert coefficient will vary between 0.0 and 1.0 what will generate the self shadow.

The Is term expresses the final specular component. This component is obtained by:

Is = Sm x Sl x pow( max(R dot E, 0.0), f )

The Is term is from far the most complicated to calculate but it is responsible of these famous specular reflexions on the surface of the objects. Sl is the specular component of the light and Sm the specular component of the material. E the view vector or camera vector and R is the reflected light vector. R is obtained with:

R = reflect(-L, N)

where N is the normal vector to the pixel considered, and L the light vector (the same than Lambert coefficient) and reflect() a function (available in GLSL) which makes it possible to calculate the reflexion vector of L in relation to N. One implementation of reflect() could be:

R = 2 * ( N dot L) * N - L

The pow() function is the power function which makes it possible to raise a number n to the power of p: pow(n, p). f is the specular exponential factor (the famous shininess in OpenGL) which represents the hardness and the precision of the specular reflexion.

At the OpenGL level, the light's ambient, diffuse and specular terms are defined by:

float Al[4] = {0.0f, 0.0f, 0.0f, 1.0f };
glLightfv( GL_LIGHT0, GL_AMBIENT, Al );	

float Dl[4] = {1.0f, 1.0f, 1.0f, 1.0f };
glLightfv( GL_LIGHT0, GL_DIFFUSE, Dl );	

float Sl[4] = {1.0f, 1.0f, 1.0f, 1.0f };
glLightfv( GL_LIGHT0, GL_SPECULAR, Sl );	

And in Demoniak3D terms:

<light name="Light_01">
	<ambient r="0.0" g="0.0" b="0.0" a="1.0" />
	<diffuse r="1.0" g="1.0" b="1.0" a="1.0" />
	<specular r="1.0" g="1.0" b="1.0" a="1.0" />
</light>

At the OpenGL level, the material's ambient, diffuse and specular terms are defined by:

float Am[4] = {0.3f, 0.3f, 0.3f, 1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Am );

float Dm[4] = {0.9f, 0.5f, 0.5f, 1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Dm );

float Sm[4] = {0.6f, 0.6f, 0.6f, 1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Sm );

float f = 60.0f;
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, f );

And for Demoniak3D:

<material name="mat_torus" >
	<ambient r="0.3" g="0.3" b="0.3" a="1.0" />
	<diffuse r="0.9" g="0.5" b="0.5" a="1.0" />
	<specular r="0.6" g="0.6" b="0.6" a="1.0" exp="60.0" />
</material>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值