Xna 自定义HLSL着色器在icosphere上创建奇怪图案
真的希望有人能在这里帮助我-我很少不能解决C#中的错误,因为我在这方面有相当多的经验,但我没有太多的HLSL可以继续 链接到下面的图片是同一个模型(运行时以编程方式生成)两次,第一次(白色)使用BasicFect,第二次使用我的自定义着色器,如下所示。它与BasicFect一起工作的事实让我认为,为模型生成法线或诸如此类的东西不是问题 为了更好地说明这个问题,我加入了不同层次的细分。值得一提的是,两种效果使用相同的照明方向 以下是我的着色器代码(请随意挑选,欢迎提供任何提示):Xna 自定义HLSL着色器在icosphere上创建奇怪图案,xna,shader,hlsl,lighting,Xna,Shader,Hlsl,Lighting,真的希望有人能在这里帮助我-我很少不能解决C#中的错误,因为我在这方面有相当多的经验,但我没有太多的HLSL可以继续 链接到下面的图片是同一个模型(运行时以编程方式生成)两次,第一次(白色)使用BasicFect,第二次使用我的自定义着色器,如下所示。它与BasicFect一起工作的事实让我认为,为模型生成法线或诸如此类的东西不是问题 为了更好地说明这个问题,我加入了不同层次的细分。值得一提的是,两种效果使用相同的照明方向 以下是我的着色器代码(请随意挑选,欢迎提供任何提示): float4x
float4x4世界视图项目;
float4x4法线旋转=float4x4(1,0,0,0,1,0,0,0,1,0,0,0,0,1);
float4 ModelColor=float4(1,1,1,1);
bool TextureEnabled=false;
纹理模型纹理;
采样器颜色文本采样器=采样器\状态
{
纹理=;
magfilter=线性;minfilter=线性;mipfilter=线性;
AddressU=镜像;AddressV=镜像;
};
float4-AmbientColor=float4(1,1,1,1);
浮动环境强度=0.1;
float3 DiffuseLightDirection=float3(1,0,0);
float4 DiffuseColor=float4(1,1,1,1);
浮子扩散强度=1.0;
结构VertexShaderInput
{
浮动4位置:位置0;
float4 Normal:NORMAL0;
float2纹理坐标:TEXCOORD0;
};
结构VertexShaderOutput
{
浮动4位置:位置0;
float4颜色:COLOR0;
float2纹理坐标:TEXCOORD0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput输入)
{
VertexShaderOutput输出=(VertexShaderOutput)0;
output.Position=mul(input.Position,WorldViewProj);
float4 normal=mul(input.normal,NormalRotation);
浮动光强度=点(法线、漫射光方向);
输出颜色=饱和(漫射颜色*漫射强度*光强度);
output.TextureCoordinates=input.TextureCoordinates;
返回输出;
}
float4 PixelShaderFunction(VertexShaderOutput输入):COLOR0
{
float4 pixBaseColor=ModelColor;
如果(TextureEnabled==true)
{
pixBaseColor=tex2D(彩色纹理采样器,输入纹理坐标);
}
float4照明=饱和((input.Color+AmbientColor*AmbientIntensity)*pixBaseColor);
返回照明;
}
技术最佳电流
{
通行证1
{
VertexShader=编译vs_2_0 VertexShaderFunction();
PixelShader=编译ps_2_0 PixelShaderFunction();
}
}
通常,在实施照明等式时,需要确保以下几点:
normal=正常化(normal)代码>
如果漫反射光方向尚未标准化,则应对其执行相同的操作。它已经是您的默认值,但如果您的应用程序更改了它,它可能不再正常化。因此,最好在应用程序代码中进行规范化,因为它只需要在更改时执行一次,而不是逐顶点执行
还请记住,如果将向量乘以包含比例的矩阵,则向量将不再规格化,因此需要重新规格化
(1,0,0)
。如果希望灯光指向+x方向,则必须在对法线执行点积之前对向量求反,使其与法线一样从曲面指向。如果你已经考虑到了这一点,那么这就不是问题NormalRotation
,我假设它只包含一个旋转,所以这可能不是问题有几件事需要尝试:1)在将法线用于点积之前,请确保法线已标准化。2) 法线和光线方向向量需要指向点积的同一方向(从曲面向外)。如果你对光的意图是+x方向,那么在做点积之前,你需要将它否定为-x方向。3) 可能不是问题,但请确保
输入的第四个分量。Normal
为0,或者Normal rotation
矩阵不包含平移。另外,在点状产品中使用之前,请确保灯光方向已规范化。第一句话通过规范化法线立即解决了我的问题。可能花了好几天的时间忽略了这一点!非常感谢您的快速回复。如果你把它作为答复寄过来,我会记下来的。
float4x4 WorldViewProj;
float4x4 NormalRotation = float4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
float4 ModelColor = float4(1, 1, 1, 1);
bool TextureEnabled = false;
Texture ModelTexture;
sampler ColoredTextureSampler = sampler_state
{
texture = <ModelTexture>;
magfilter = LINEAR; minfilter = LINEAR; mipfilter = LINEAR;
AddressU = mirror; AddressV = mirror;
};
float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;
float3 DiffuseLightDirection = float3(1, 0, 0);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 1.0;
struct VertexShaderInput
{
float4 Position : POSITION0;
float4 Normal : NORMAL0;
float2 TextureCoordinates : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TextureCoordinates : TEXCOORD0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output = (VertexShaderOutput)0;
output.Position = mul(input.Position, WorldViewProj);
float4 normal = mul(input.Normal, NormalRotation);
float lightIntensity = dot(normal, DiffuseLightDirection);
output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
output.TextureCoordinates = input.TextureCoordinates;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 pixBaseColor = ModelColor;
if (TextureEnabled == true)
{
pixBaseColor = tex2D(ColoredTextureSampler, input.TextureCoordinates);
}
float4 lighting = saturate((input.Color + AmbientColor * AmbientIntensity) * pixBaseColor);
return lighting;
}
technique BestCurrent
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}