给出wierd结果的法线映射。(C#XNA)
好的,所以这个问题有点大,出于同样的原因,我宁愿发布尽可能少的代码,但更希望你能想到它可能是什么。我会把代码贴在我觉得有问题的地方。如果你想看到更多,请询问,我会提供 所以,我只是为我的游戏“偷”了一个着色器。我的意思是找到了一个我以前做过的教程,然后复制了最终结果。因此我知道着色器应该工作,因为我以前使用过它 我有一个自定义网格类,还有一个自定义顶点结构。我以前从未做过xertex结构,所以最初我认为这就是问题所在。 但我后来发现了一些反驳: 他们所有的变量似乎都是正确的,除了凹凸贴图之外,一切都正常。 更改切线和/或副法线似乎对着色没有任何影响。因此,我认为错误不在于如何计算它们,而在于如何使用它们 这是我得到的输出。请记住,这是一个体素引擎。如您所见,所有框都具有相同的wierd法线贴图阴影。但是,这是法线贴图: 正如你所看到的,它们根本不合适。在我看来,这可能是三件事之一:给出wierd结果的法线映射。(C#XNA),c#,xna,shader,C#,Xna,Shader,好的,所以这个问题有点大,出于同样的原因,我宁愿发布尽可能少的代码,但更希望你能想到它可能是什么。我会把代码贴在我觉得有问题的地方。如果你想看到更多,请询问,我会提供 所以,我只是为我的游戏“偷”了一个着色器。我的意思是找到了一个我以前做过的教程,然后复制了最终结果。因此我知道着色器应该工作,因为我以前使用过它 我有一个自定义网格类,还有一个自定义顶点结构。我以前从未做过xertex结构,所以最初我认为这就是问题所在。 但我后来发现了一些反驳: 他们所有的变量似乎都是正确的,除了凹凸贴图之外,一
// XNA 4.0 Shader Programming #4 - Normal Mapping
// Matrix
float4x4 World;
float4x4 View;
float4x4 Projection;
// Light related
float4 AmbientColor;
float AmbientIntensity;
float3 LightDirection;
float4 DiffuseColor;
float DiffuseIntensity;
float4 SpecularColor;
float3 EyePosition;
texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
Texture = <ColorMap>;
MinFilter = linear;
MagFilter = linear;
MipFilter = linear;
};
texture2D NormalMap;
sampler2D NormalMapSampler = sampler_state
{
Texture = <NormalMap>;
MinFilter = linear;
MagFilter = linear;
MipFilter = linear;
};
// The input for the VertexShader
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float3 Normal : NORMAL0;
float3 Binormal : BINORMAL0;
float3 Tangent : TANGENT0;
};
// The output from the vertex shader, used for later processing
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float3 View : TEXCOORD1;
float3x3 WorldToTangentSpace : TEXCOORD2;
};
// The VertexShader.
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.TexCoord = input.TexCoord;
output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);
output.View = normalize(float4(EyePosition,1.0) - worldPosition);
return output;
}
// The Pixel Shader
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 color = tex2D(ColorMapSampler, input.TexCoord);
float3 normalMap = 2.0 *(tex2D(NormalMapSampler, input.TexCoord)) - 1.0;
normalMap = normalize(mul(normalMap, input.WorldToTangentSpace));
float4 normal = float4(normalMap,1.0);
float4 diffuse = saturate(dot(-LightDirection,normal));
float4 reflect = normalize(2*diffuse*normal-float4(LightDirection,1.0));
float4 specular = pow(saturate(dot(reflect,input.View)),32);
return color * AmbientColor * AmbientIntensity +
color * DiffuseIntensity * DiffuseColor * diffuse +
color * SpecularColor * specular;
}
// Our Techinique
technique Technique1
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
//XNA 4.0着色器编程#4-法线映射
//母体
四驱世界;
浮动4x4视图;
浮动4x4投影;
//光相关
浮动4环境色;
漂浮环境强度;
漂浮方向;
4扩散色;
漂浮扩散强度;
浮动4镜面颜色;
3眼位;
纹理2D彩色地图;
sampler2D ColorMapSampler=采样器\状态
{
纹理=;
MinFilter=线性;
磁滤波器=线性;
MipFilter=线性;
};
纹理2D法线贴图;
sampler2D NormalMapSampler=采样器\状态
{
纹理=;
MinFilter=线性;
磁滤波器=线性;
MipFilter=线性;
};
//VertexShader的输入
结构VertexShaderInput
{
浮动4位置:位置0;
浮动2 TexCoord:TEXCOORD0;
float3 Normal:NORMAL0;
浮动3副法线:副法线0;
float3切线:切线0;
};
//顶点着色器的输出,用于以后的处理
结构VertexShaderOutput
{
浮动4位置:位置0;
浮动2 TexCoord:TEXCOORD0;
浮动3视图:TEXCOORD1;
float3x3 WorldToTangentSpace:TEXCOORD2;
};
//顶点着色器。
VertexShaderOutput VertexShaderFunction(VertexShaderInput输入)
{
VertexShaderOutput输出;
float4 worldPosition=mul(input.Position,World);
float4 viewPosition=mul(世界位置,视图);
输出位置=mul(视图位置、投影);
output.TexCoord=input.TexCoord;
output.WorldToTangentSpace[0]=mul(normalize(input.Tangent),World);
output.WorldToTangentSpace[1]=mul(normalize(input.Binormal),World);
output.WorldToTangentSpace[2]=mul(normalize(input.Normal),World);
output.View=normalize(float4(眼位,1.0)-worldPosition);
返回输出;
}
//像素着色器
float4 PixelShaderFunction(VertexShaderOutput输入):COLOR0
{
float4 color=tex2D(ColorMapSampler,input.TexCoord);
float3 normalMap=2.0*(tex2D(NormalMapSampler,input.TexCoord))-1.0;
normalMap=normalize(mul(normalMap,input.WorldToTangentSpace));
float4 normal=float4(normalMap,1.0);
float4漫反射=饱和(点(-LightDirection,normal));
float4 reflect=规格化(2*漫反射*法线-float4(光照方向,1.0));
float4镜面反射=pow(饱和(点(反射,输入.视图)),32);
返回颜色*环境颜色*环境强度+
颜色*漫反射强度*漫反射颜色*漫反射+
颜色*镜面反射颜色*镜面反射;
}
//我们的技术
技术1
{
通行证1
{
VertexShader=编译vs_2_0 VertexShaderFunction();
PixelShader=编译ps_2_0 PixelShaderFunction();
}
}
此操作的顺序不正确:
output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);
应该是这样的:
output.WorldToTangentSpace[0] = normalize(mul(input.Tangent), World);
output.WorldToTangentSpace[1] = normalize(mul(input.Binormal), World);
output.WorldToTangentSpace[2] = normalize(mul(input.Normal), World);
否则,法线将从世界空间变换中缩放,并将产生非常亮和非常暗的面片(这看起来像是您的问题)。顺便说一句,鉴于您对体素引擎的法线贴图感兴趣,请查看我制作的以下内容:
希望你得到启发,完成你的项目。你是说规范化(mul(input.Tangent,World))
(而不是规范化(mul(input.Tangent,World)
)?
output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);
output.WorldToTangentSpace[0] = normalize(mul(input.Tangent), World);
output.WorldToTangentSpace[1] = normalize(mul(input.Binormal), World);
output.WorldToTangentSpace[2] = normalize(mul(input.Normal), World);