Здавалка
Главная | Обратная связь

Приложения для установки источников освещения



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

ID3D11Buffer* g_pConstantBuffer = NULL;

Далее мы создадим структуру ConstantBuffer. Эта структура будут хранить вместе с остальными константами шейдера, нужные нам массивы координат и цветов для нескольких источников освещения:

struct ConstantBuffer { ... XMFLOAT4 vLightColor[5]; XMFLOAT4 vLightPos[5]; };

Теперь всё готово, чтобы при каждом вызове функции Render устанавливать наши источники освещения. Сначала заполним их значениями. В качестве координат источников света используем динамически меняющиеся орбитальные координаты:

XMFLOAT4 LightPos[5]; XMFLOAT4 LightColor[5]; LightPos[0]=XMFLOAT4(sin(orbit*f0)*r,cos(orbit*f0)*r,cos(orbit*f0)*r,0); LightPos[1]=XMFLOAT4(sin(orbit*f1)*r,-sin(orbit*f1)*r,-cos(orbit*f1)*r,0); LightPos[2]=XMFLOAT4(cos(orbit*f2)*r,sin(orbit*f2)*r,sin(orbit*f2)*r,0); LightColor[0]=XMFLOAT4(1,1,0,1); LightColor[1]=XMFLOAT4(0,0,1,1); LightColor[2]=XMFLOAT4(0,1,1,1);

Всего установим три источника освещения. Координаты рассчитаны, теперь осталось предать значения координат в шейдер:

// Установка констант шейдера ConstantBuffer cb; ... memcpy(&cb.vLightColor,&LightColor,sizeof(LightColor)); memcpy(&cb.vLightPos,&LightPos,sizeof(LightPos)); g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb, 0, 0 );

Теперь перейдем от нашего приложения к коду шейдера. Рассмотрим вершинныйшейдер для нашего приложения.

//------------------------------------------------------------------------------------ // Constant Buffer Variables //------------------------------------------------------------------------------------ cbuffer ConstantBuffer : register( b0 ) { matrix World; matrix View; matrix Projection; float4 vLightColor[5]; float4 vLightPos[5]; } //------------------------------------------------------------------------------------ // Vertex Shader //------------------------------------------------------------------------------------ VS_OUTPUT VS( float4 Pos : POSITION, float4 Normal: NORMAL, float2 Tex: TEXCOORD ) { VS_OUTPUT output = (VS_OUTPUT)0; output.Pos = mul( Pos, World ); output.Pos = mul( output.Pos, View ); output.Pos = mul( output.Pos, Projection ); output.Color=float4(0.0f,0.0f,0.0f,0.0f); for (int i=0; i<3; i++) output.Color+=dot(normalize(Normal),normalize((float3)vLightPos[i]-(float3)Pos) )*vLightColor[i]; return output; }

Обратите внимание на строку, в которой в цикле рассчитывается переменная output.Color. Данная строка полностью соответствует формуле, рассмотренной ранее в данном уроке:

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

Обзор приложения

Теперь можно скомпилировать и запустить наше приложение. Исходный код данного приложения, а также само приложение вы можете скачать тут. В приложении используется три источника освещения. Вообще количество источников неограниченно. В шейдере приложения используется формула из этого урока для расчета интенсивности освещения объекта.

В качестве освещаемого объекта используется тор, так как эта геометрическая фигура, ввиду сложного расположения нормалей, не может быть освещена корректно, если метод и расчет освещения неверен. Но наша формула замечательно функционирует, и, таким образом, из этого урока мы точно узнали, где находится Кольцо и кто на самом деле является его Властелином; сегодня это шейдеры.







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.