2013-02-26 1 views
2

Я рисую сцену текстуры, а затем рисую водную плоскость с этой текстурой, используя проекцию. Большинство образцов, которые я видел в Интернете, проходит в матрице просмотра/проекции на вершинном шейдер и преобразовать вершину, то в пиксельном шейдере они делают:HLSL проекционный шейдер

projection.x = input.projectionCoords.x/input.projectionCoords.w/2.0 + 0.5; 
projection.y = input.projectionCoords.y/input.projectionCoords.w/2.0 + 0.5; 

У меня есть шейдер, который выполняет следующий и он работает тоже, но я не знаю, где я нашел этот конкретный код или как он дает те же результаты с вышеуказанным кодом. Вот код, у меня есть

Vertex шейдер: (мир является identityMatrix, viewProj мои камеры в сочетании матричные viewProjection):

output.position3D = mul(float4(vsin.position,1.0), world).xyz; 
output.position = mul(float4(output.position3D,1.0), viewProj); 

output.reflectionTexCoord.x = 0.5 * (output.position.w + output.position.x); 
output.reflectionTexCoord.y = 0.5 * (output.position.w - output.position.y); 
output.reflectionTexCoord.z = output.position.w; 

Pixel Shader:

float2 projectedTexCoord = (input.reflectionTexCoord.xy/input.reflectionTexCoord.z); 

Что меня смущает это использование 0.5 * (output.position.w + output.position.x) и 0.5 * (output.position.w - output.position.y). Как это имеет тот же эффект и что здесь означает w-компонент?

ответ

2

Через некоторое время я понял, что он заканчивает тем, что то же самое:

0.5 * (output.position.w + output.position.x); 

0.5 * output.position.w + 0.5 * output.position.x 

Затем в пиксельный шейдер:

(0.5 * output.position.w + 0.5 * output.position.x)/output.position.w 

(0.5 * output.position.w)/output.position.w + (0.5 * output.position.x)/output.position.w 

Первая часть становится 0,5:

0.5 + 0.5 * (output.position.x/output.position.w) 

Это равно:

(output.position.x/output.position.w)/2 + 0.5 

Я считаю, что перенос этого вычисления в вершинный шейдер более эффективен, поэтому я просто оставлю его там.

Чтобы полностью переместить вычисление из шейдера матрица может быть вычислен на стороне клиента:

XMMATRIX v = XMLoadFloat4x4(&view); 
XMMATRIX p = XMLoadFloat4x4(&projection); 

XMMATRIX t(
    0.5f, 0.0f, 0.0f, 0.0f, 
    0.0f, -0.5f, 0.0f, 0.0f, 
    0.0f, 0.0f, 1.0f, 0.0f, 
    0.5f, 0.5f, 0.0f, 1.0f); 

XMMATRIX reflectionTransform = v * p * t; 
XMStoreFloat4x4(&_reflectionTransform, XMMatrixTranspose(reflectionTransform)); 

Тогда все вершинные шейдеры должны сделать, это:

output.reflectionTexCoord = mul(float4(output.position3D,1.0), reflectionProjectionMatrix);