2011-11-03 120 views
1

所以我一直在寻找跨网络找到这个问题的答案,但我似乎失去了一些东西。如何在XNA的3D地形上绘制圆形?

我有一个小项目要动态地在XNA 4.0创建的3D地形,但我希望能画一个圆(或任何其他形状对于这个问题,但让我们先用一个圆圈走)对地形。 现在我已阅读了一些关于“投影纹理”的内容,但我承认在着色器语言方面我完全丧失了功能。

的想法是,我可以(动态地)创建一个基本的形状,说用2“单元”直径的圆,然后绘制该地形上以用作指示器光标所在。 (我能得到的3D地形光标位置。)

会有人知道如何做到这一点,是使用着色器这个需要它?任何关于此事的帮助都是有好处的!

在此先感谢!

回答

4

可以使用着色器...

你传递作为参数传递给地形渲染,你的光标的3D世界中的地位,以及半径...来定义一个球体,

的伎俩将顶点着色器的顶点世界位置传递给像素着色器,而像素着色器中的顶点世界位置仅在像素被绘制时着色输出颜色,则位于球体内。

编辑:我发现我自己做了一个旧的着色器......有两种选择圆形和框,在这里你是:

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;  
    } 
} 
+0

所以我会需要在着色器的设置参数光标的vector3?还是有其他方式将其传递给着色器? – Strike

+0

你可以将它作为顶点的一部分传递,但没有意义,因为你只有一个游标,这将是一种浪费。 – Blau

+0

我添加了一个我以前制作的着色器。 – Blau