void main(void) {
vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex); vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal).: vec3. lightvec - normalizetLightPosition - ecPosition): vec3 reflectVec = reflect(-1ightvec. tnorm): vec3 viewVec = normalize(-ecPosition):
float spec = clampCdottreflectVec. viewVec). 0.0. 1.0):
10.3. Пример множественной текстуры
spec = port spec. 8.0):
Specular = vec3 (spec) * vec3 (1.0. 0.941. 0.898) * 0,3:
Diffuse ~ maxCdotCIightVec. tnorm). 0.0):
TexCoord = gl_MultiTexCoord0.st:
gl_Position = ftransformO;
}
10.3.3. Фрагментный шейдер
Фрагментный шейдер, который работает с множественными текстурами, приведен в листинге 10.4. Приложение загрузило «дневную» текстуру в текстурный модуль с именем EarthDay, «ночную» текстуру - в текстурный модуль EarthNight, а текстуру с облаками и отражением - в текстурный модуль EarthCloudGl oss. Вычисление освещения выполняется в вершинном шейдере, учитываются рассеянное и зеркальное отражения, и результат передается во фрагментный шейдер. Текстурные координаты, передаваемые приложениям, также передаются во фрагментный шейдер, и на основании этих координат происходит дальнейшая работа с текстурами.
Во фрагмеитном шейдере сначала нужно обратиться к текстуре облаков/отражения - эти значения пригодятся при дальнейших вычислениях. Потом считывается значение из «дневной» текстуры, умножается на коэффициент рассеянного освещения и добавляется к коэффициенту отраженного освещения, умноженному на значение из текстуры зеркального отражения. Если фрагмент не скрыт облаками, эти вычисления дают необходимый эффект рассеянного освещения по всей поверхности Земли и эффект зеркального отражения от водной поверхности. Это значение затем умножается на 1,0 минус коэффициент облачности. И наконец, эффект облака получается умножением коэффициента облачности назначение рассеянного 1 освещения, и результат добавляется к результату всех предыдущих вычислений.