Листинг 9.10 (продолжение)

diff = vec4 (0.0): spec = vec4 (0.0):

// Цикл по включенным источникам for (i =“ 0: i < NumEnabledLights: i++)

{

if (g1_LightSource[i].position.w == 0.0)

Di recti onalLightd, normal, amb, diff. spec): else if (gl__LightSource[i].spotCutoff = 180.0)

PoihtLightd. eye. ecPosition3, normal, amb. diff, spec); else

SpotLight(i. eye, ecPosition3, normal, smb. diff. spec):

}

Одна из дополнительных возможностей OpenGL 1.2 - функциональность для расчета цвета вершины за два этапа: сначала как обычно вычисляется первичный цвет, включая компоненты излучения, рассеяиия и отражения; затем вторичный цвет, который содержит только компонент зеркального отражения. Если этот режим не включен (по умолчанию), первичный цвет будет содержать все компоненты: излучения, рассеяния, отражения и зеркального отражения.

Вычисление зеркального отражения отдельно от остальных позволяет накладывать его после текстурирования. Значение зеркального отражения накладывается на вычисленный цвет после текстурирования для того, чтобы отраженный свет был окрашен в цвет источника освещения, а не в цвет поверхности. Вычисление цвета поверхности без компонента зеркального отображения показано в листинге 9.11.

Листинг9.11. Вычисление цвета поверхности без компонента зеркального отражения

color = gl_FrontLightModelProduct.sceneColor + amb * gl_FrontMaterial.ambient + diff * g!_FrontMaterial .diffuse; Язык шейдеров OpenGL предоставляет удобную встроенную переменную gl_ГrontLightModel Product. sceneColor, в которой содержится значение излучающего свойства материала для передних поверхностей и общее значение рассеянного освещения (то есть дЛ_FrontMaterial.emission + gl_FrontMaterial.ambient * gl _Li ghtHodel .ambi ent). Можно сложить его с интенсивностью отраженного света и интенсивностью рассеянного света. В дальнейшем нужно поступать в зависимости от того, указан ли режим отдельного наложения компонента зеркального отражения (листинг 9.12).

Листинг 9.12. Завершающие вычисления цвета поверхности

if (SeparateSpecular)

gl_FrontSecondaryColor = vec4 (spec *gl_FrontMaterlal.specular. 1.0); el se

color += spec * gl_FrontMaterial .specular; gl_FrontColor = color; Нет необходимости ограничивать значения (clamping) gl _FrontSecondaryColor и gl_FrontColor, так как это будет сделано автоматически.

А Двухстороннее освещение

Чтоб!»] в OpenGL имитировать двухстороннее освещение, нужно инвертировать нормаль поверхности и выполнить те же самые вычисления, что и в предыдущем разделе, но только со значениями задней поверхности материала. Возможно, при необходимости читатель выполнит такие вычисления более оптимально, а сама идея вычислений содержится в листинге 9.13.

Листинг 9.13. Вычисление двухстороннего освещения

normal = -normal:

11 Инициализация переменных для накопления интенсивности освещения amb = vec4 (0.0); diff - vec4 (0.0): spec - vec4 (0.0);

// Цикл no всем источникам, вычисление компонентов освещения от каждого for (1=0; i < NumEnabledLights: i++)

{

if (gl_LightSource[i].position.w == .0.0)


⇐ вернуться назад | | далее ⇒