12 февраля 2010 в 20:51
Уроки Direct3D - 2.7. Имитация отражения.
До сих пор мы использовали для наложения текстур координаты, непосредственно заданные в вертексах. Существуют и другие способы, при которых текстурные координаты рассчитываются непосредственно при растеризации. Один из наиболее распространенных подходов – расчет текстурных координат исходя из позиции вертекса и камеры и нормали вертекса, используемый для имитации отражений. Все расчеты производит DirectX, освобождая нас от изучения оптики.
Возьмем наш предыдущий проект, оставив в InitMesh генерацию чайника:
Private Sub InitMesh() Set Mesh = d3dx.CreateTeapot(d3dDevice, Nothing) End Sub
Так же уберем все, связанное с использованием света и материала. Добавим в модуль modMain текстуру Tex и процедуру Setting, где будем испытывать нововведения, не забываем вписать вызов Setting перед главным циклом. Текстуру загрузим из файла sky.jpg, находящегося в папке Pr17. Содержимое Setting сначала будет таким:
Private Sub Setting() d3dDevice.SetRenderState D3DRS_CULLMODE, D3DCULL_CCW d3dDevice.SetRenderState D3DRS_ZENABLE, D3DZB_TRUE Set Tex = d3dx.CreateTextureFromFile(d3dDevice, "sky.jpg") TexFilter 0, TexF_TriLinear d3dDevice.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 d3dDevice.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE d3dDevice.SetTexture 0, Tex End Sub
Пока все по старому, загрузили текстуру, настроили нулевую стадию текстурирования. Однако текстуры не видно, ведь мы не указали текстурные координаты, вся модель закрашена цветом, взятым из текстуры с координат 0, 0. Добавим в Setting такую строку:
d3dDevice.SetTextureStageState 0, D3DTSS_TEXCOORDINDEX, _ D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
Теперь чайник затекстурирован, но текстура не очень похожа на отражение. Описать работу этой команды, не вдаваясь в подробности, можно так – вычисляется направление нормали вертекса относительно направления на камеру. Если нормаль направлена на камеру – результирующие значения u и v текстурных координат равны нулю. Если нормаль направлена левее – значение u уменьшается, правее – увеличивается. Если нормаль направлена выше – значение v уменьшается, ниже – увеличивается. Изменения u и v лежат в диапазоне от -1 до 1, причем u и v не могут принять крайние значения диапазона одновременно, они лежат в пределах окружности с центром в начале координат и радиусом 1 на координатной плоскости. Но на нашей текстуре изображение отражения лежит на вчетверо меньшей (по площади) окружности с центром в точке 0.5, 0.5 и радиусом 0.5.
Познакомимся с четвертой трансформацией, помогающей исправить эту ситуацию. Это трансформация D3DTS_TEXTURE0, позволяющая с помощью матриц задавать изменения текстурных координат нулевой стадии текстурирования, аналогичные трансформации существуют для всех восьми стадий. Добавим в процедуру Setting такие строки:
D3DXMatrixTranslation Mtrx, 0.5, 0.5, 0 d3dDevice.SetTransform D3DTS_TEXTURE0, Mtrx D3DXMatrixScaling Mtrx, 0.5, 0.5, 1 d3dDevice.MultiplyTransform D3DTS_TEXTURE0, Mtrx
Необходимо там же объявить переменную Mtrx типа D3DMATRIX.
Запускаем программу, но картинка не поменялась, все потому, что использование этой трансформации по умолчанию запрещено. Такой строкой мы разрешаем ее использовать для изменения двух текстурных координат:
d3dDevice.SetTextureStageState 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2
Теперь изображение гораздо больше похоже на натуральное.
комментарии отсутствуют
авторизуйтесь