Due to something I see when rendering specular reflections, I'm trying to determine if there is a difference in what or how values get interpolated across a polygon - i.e., what vertex shader outputs are interpolated when they're sent to the pixel shader. Specifically, I have noticed a difference in specular reflection rendering depending on whether the view direction from the world position to the eye position (camera position, view position) used to determine the specular contribution is calculated in the vertex shader vs. calculated in the pixel shader. The remainder of the shader process is the same between the two cases (constant buffers, SV_POSITION calc, etc.)
Can someone enlighten me, perhaps providing information and/or a link describing what or how output values from a vertex shader get interpolated for pixel shader input? It's a learning process and, when coding my shaders, I'd like to understand a bit better what I can expect as pixel shader input.
What I observed:
=============
For testing purposes, I calculate in the vertex shader both the vertex world position, and view direction between the vertex and the eye position. Both values are passed via the vertex shader "output" structure to the pixel shader as an "input" structure.
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;
float3 normal : NORMAL;
float3 viewDirection : TEXCOORD1;
float3 worldPosition : TEXCOORD2;
};
// vertex shader
PS_INPUT output = (PS_INPUT)0;
output.Pos = mul(input.Pos, ObjWorld); // per object
// for comparison, output both vertex world position and calculated view direction.
// both output.worldPosition and output.viewDirection are float3, TEXCOORD semantic
output.worldPosition = output.Pos.xyz; // capture world position
// ... output.Pos multiplied by view-projection as SV_POSITION output
output.viewDirection = normalize(eyePos.xyz - worldPosition); // float4 eyePos is in a per-frame constant buffer
// EDIT: above line later revised to the following. See later comments in this thread.
output.viewDirection = eyePos.xyz - worldPosition;
// pixel shader
float3 pLightDir = normalize(-lightDir.xyz); // true light direction is provided in a constant buffer
reflection = normalize(2 * lightIntensity * input.normal - pLightDir);
// Case 1 - use the view direction calc'd in the VS
specular = pow(saturate(dot(reflection, input.viewDirection)), Power) * SpecularColor;
// EDIT: the above line later revised to the following. See comments below in this thread.
specular = pow(saturate(dot(reflection, normalize(input.viewDirection))), Power) * SpecularColor;
// Case 2 - calculate the view direction in the PS
specular = pow(saturate(dot(reflection, normalize(eyePos.xyz - input.worldPosition))), Power) * SpecularColor;
The only difference between the results shown below is that the view direction in the specular calc is - Case 1: in the VS, Case 2: in the PS.
Case 1 - the rendered results of that specular calculation appear to exhibit artifacts related to vertex position.
[attachment=26259:vertex_specular.png][attachment=26260:vertex_specular_wireframe.png]
Case 2 - the rendered results appear to be smooth across the polygon.
[attachment=26261:pixel_specular.png]