C# 如何在XNA中在3D地形上绘制圆?
所以我一直在网上寻找这个问题的答案,但我似乎遗漏了一些东西 我有一个小项目正在进行,它可以在XNA4.0中动态创建3D地形,但我希望能够为此绘制一个圆或任何其他形状,但我们先在地形上绘制一个圆。 现在我已经读了一些关于“投影纹理”的东西,但我承认当涉及到着色器语言时,我完全不知所措 我的想法是,我可以动态创建一个基本形状,比如一个直径为2个“单位”的圆,然后在地形上绘制它,作为光标所在位置的指示器。我能够在3D地形上获得光标位置 是否有人知道如何做到这一点,是否需要为此使用着色器?在这件事上的任何帮助都是非常感谢的C# 如何在XNA中在3D地形上绘制圆?,c#,3d,xna,textures,terrain,C#,3d,Xna,Textures,Terrain,所以我一直在网上寻找这个问题的答案,但我似乎遗漏了一些东西 我有一个小项目正在进行,它可以在XNA4.0中动态创建3D地形,但我希望能够为此绘制一个圆或任何其他形状,但我们先在地形上绘制一个圆。 现在我已经读了一些关于“投影纹理”的东西,但我承认当涉及到着色器语言时,我完全不知所措 我的想法是,我可以动态创建一个基本形状,比如一个直径为2个“单位”的圆,然后在地形上绘制它,作为光标所在位置的指示器。我能够在3D地形上获得光标位置 是否有人知道如何做到这一点,是否需要为此使用着色器?在这件事上的任
提前谢谢 您可以使用着色器 将作为参数传递给地形着色器、光标的3D世界位置和半径。。。要定义一个球体 技巧是将顶点世界位置从顶点着色器传递到像素着色器,然后 在“像素着色器”(pixel shader)中,如果正在绘制的像素位于球体内部,则只需对输出颜色着色 编辑:我发现了一个自己做的旧着色器。。。使用两种类型的选择圆和选择框,您可以看到:
uniform float4x4 xWorldViewProjection;
uniform float3 xCursorPos;
uniform float xCursorRadio;
uniform float4 xLightColor = float4(0.8, 0.8, 0.8,1);
uniform float4 xAmbientFactor = 0.4f;
uniform float3 xCamPos;
uniform int xCursorType=0; // 0: Circle 1: Box
void VS_Basico(
in float4 inPos : POSITION,
in float3 inNormal : NORMAL0,
in float4 inColor : COLOR0,
out float4 outPos: POSITION,
out float3 outNormal:TEXCOORD1,
out float3 outPos2 : TEXCOORD0,
out float4 outColor: COLOR0
)
{
outPos = mul (inPos, xWorldViewProjection);
outNormal = inNormal;
outPos2 = inPos.xyz;
outColor = inColor;
}
float4 PS_CursorPerPixelCircular ( in float4 inColor : COLOR, in float3 inPos:TEXCOORD0 ) : COLOR
{
float f = distance(inPos, xCursorPos);
float4 outColor = inColor;
if (f<xCursorRadio) {
outColor=lerp(float4(0,1,1,1), inColor, 0.4) ;
}
return outColor;
}
float4 PS_CursorPerPixelCuadrado ( in float4 inColor : COLOR, in float3 inPos:TEXCOORD0 ) : COLOR
{
float3 size = float3(xCursorRadio,xCursorRadio,xCursorRadio);
float3 minSize = xCursorPos - size;
float3 maxSize = xCursorPos + size;
float4 outColor = inColor;
if (inPos.x>=minSize.x && inPos.x<=maxSize.x && inPos.y>=minSize.y && inPos.y<=maxSize.y && inPos.z>=minSize.z && inPos.z<=maxSize.z )
{
outColor=lerp(float4(0,1,1,1), inColor, 0.4) ;
}
return outColor;
}
void PS_Basico(
in float4 inColor : COLOR0,
in float3 inPos:TEXCOORD0,
in float3 inNormal:TEXCOORD1,
out float4 outColor: COLOR0
)
{
float3 xLightPos = float3(40, 40, 0);
float3 LightDir = normalize(inPos - xLightPos);
float3 reflectionVector = reflect(LightDir, inNormal);
float3 eyeVector = inPos - xCamPos;
float specular = dot(normalize(reflectionVector), normalize(eyeVector));
specular = pow(specular, 256);
float difusse_factor = -dot(normalize(inNormal), LightDir);
if (difusse_factor<0) difusse_factor = 0;
float4 col = inColor * xAmbientFactor + inColor * difusse_factor * xLightColor;
if (xCursorType ==0)
{
col = PS_CursorPerPixelCircular(col, inPos);
} else {
col = PS_CursorPerPixelCuadrado(col, inPos);
}
col.a = 1;
col.rgb += specular;
/* col.xyz = col.xyz * (inPos.y+1) / 2;
col.y = 2*col.x;
col.z = 2*col.x;
*/
outColor = col;
//outColor = float4(inNormal, 1);
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
//--- TECNIQUES -----------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
technique ColoredWired
{
pass Pass0
{
VertexShader = compile vs_2_0 VS_Basico();
PixelShader = compile ps_2_0 PS_Basico();
FILLMODE = WIREFRAME;
}
}
technique ColoredSolid
{
pass Pass0
{
VertexShader = compile vs_2_0 VS_Basico();
PixelShader = compile ps_2_0 PS_Basico();
FILLMODE = SOLID;
}
}
您可以使用着色器 将作为参数传递给地形着色器、光标的3D世界位置和半径。。。要定义一个球体 技巧是将顶点世界位置从顶点着色器传递到像素着色器,然后 在“像素着色器”(pixel shader)中,如果正在绘制的像素位于球体内部,则只需对输出颜色着色 编辑:我发现了一个自己做的旧着色器。。。使用两种类型的选择圆和选择框,您可以看到:
uniform float4x4 xWorldViewProjection;
uniform float3 xCursorPos;
uniform float xCursorRadio;
uniform float4 xLightColor = float4(0.8, 0.8, 0.8,1);
uniform float4 xAmbientFactor = 0.4f;
uniform float3 xCamPos;
uniform int xCursorType=0; // 0: Circle 1: Box
void VS_Basico(
in float4 inPos : POSITION,
in float3 inNormal : NORMAL0,
in float4 inColor : COLOR0,
out float4 outPos: POSITION,
out float3 outNormal:TEXCOORD1,
out float3 outPos2 : TEXCOORD0,
out float4 outColor: COLOR0
)
{
outPos = mul (inPos, xWorldViewProjection);
outNormal = inNormal;
outPos2 = inPos.xyz;
outColor = inColor;
}
float4 PS_CursorPerPixelCircular ( in float4 inColor : COLOR, in float3 inPos:TEXCOORD0 ) : COLOR
{
float f = distance(inPos, xCursorPos);
float4 outColor = inColor;
if (f<xCursorRadio) {
outColor=lerp(float4(0,1,1,1), inColor, 0.4) ;
}
return outColor;
}
float4 PS_CursorPerPixelCuadrado ( in float4 inColor : COLOR, in float3 inPos:TEXCOORD0 ) : COLOR
{
float3 size = float3(xCursorRadio,xCursorRadio,xCursorRadio);
float3 minSize = xCursorPos - size;
float3 maxSize = xCursorPos + size;
float4 outColor = inColor;
if (inPos.x>=minSize.x && inPos.x<=maxSize.x && inPos.y>=minSize.y && inPos.y<=maxSize.y && inPos.z>=minSize.z && inPos.z<=maxSize.z )
{
outColor=lerp(float4(0,1,1,1), inColor, 0.4) ;
}
return outColor;
}
void PS_Basico(
in float4 inColor : COLOR0,
in float3 inPos:TEXCOORD0,
in float3 inNormal:TEXCOORD1,
out float4 outColor: COLOR0
)
{
float3 xLightPos = float3(40, 40, 0);
float3 LightDir = normalize(inPos - xLightPos);
float3 reflectionVector = reflect(LightDir, inNormal);
float3 eyeVector = inPos - xCamPos;
float specular = dot(normalize(reflectionVector), normalize(eyeVector));
specular = pow(specular, 256);
float difusse_factor = -dot(normalize(inNormal), LightDir);
if (difusse_factor<0) difusse_factor = 0;
float4 col = inColor * xAmbientFactor + inColor * difusse_factor * xLightColor;
if (xCursorType ==0)
{
col = PS_CursorPerPixelCircular(col, inPos);
} else {
col = PS_CursorPerPixelCuadrado(col, inPos);
}
col.a = 1;
col.rgb += specular;
/* col.xyz = col.xyz * (inPos.y+1) / 2;
col.y = 2*col.x;
col.z = 2*col.x;
*/
outColor = col;
//outColor = float4(inNormal, 1);
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
//--- TECNIQUES -----------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
technique ColoredWired
{
pass Pass0
{
VertexShader = compile vs_2_0 VS_Basico();
PixelShader = compile ps_2_0 PS_Basico();
FILLMODE = WIREFRAME;
}
}
technique ColoredSolid
{
pass Pass0
{
VertexShader = compile vs_2_0 VS_Basico();
PixelShader = compile ps_2_0 PS_Basico();
FILLMODE = SOLID;
}
}
那么我需要在着色器中将参数设置为光标的矢量3吗?或者是否有其他方法将其传递给着色器?您可以将其作为顶点的一部分传递,但没有意义,因为您只有一个光标,这将是一种浪费。我添加了一个我以前制作的着色器。这确实非常有帮助。我也没听说过HLSL中的距离和lerp函数,所以这让我很开心。那么我需要在着色器中为光标的矢量3设置一个参数吗?或者是否有其他方法将其传递给着色器?您可以将其作为顶点的一部分传递,但没有意义,因为您只有一个光标,这将是一种浪费。我添加了一个我以前制作的着色器。这确实非常有帮助。我也没听说过HLSL中的距离和lerp函数,所以这让我大开眼界。