简体   繁体   English

如何在XNA中在3D地形上绘制圆圈?

[英]How to draw a circle on 3D terrain in XNA?

So I've been looking across the web to find an answer to this question, but I seem to be missing something. 所以我一直在网上寻找这个问题的答案,但我似乎错过了一些东西。

I've got a little project going that dynamically creates 3D terrain in XNA 4.0, but I want be able to draw a circle (or any other shape for that matter, but let's first go with a circle) on the terrain. 我有一个小项目在XNA 4.0中动态创建3D地形,但我希望能够在地形上绘制一个圆(或任何其他形状,但让我们先用圆圈)。 Now I've read some things about 'projective texturing' but I'll admit I'm at a complete loss when it comes to shader-language. 现在我已经阅读了一些关于“投射纹理”的内容,但我承认,在涉及着色器语言时,我完全失去了。

The idea is that I can (dynamically) create a basic shape, say a circle with a 2 'units' diameter, then draw that on the terrain to function as an indicator where the cursor is. 我的想法是,我可以(动态地)创建一个基本形状,比如一个直径为2'单位的圆,然后在地形上绘制它作为光标所在的指示器。 (I am able to get the cursor position on the 3D terrain.) (我能够在3D地形上获得光标位置。)

Would anyone know how to do this, is it required to use shaders for this? 有谁知道如何做到这一点,是否需要使用着色器? Any help on the matter is apreciated! 任何关于此事的帮助都是吝啬的!

Thanks in advance! 提前致谢!

You can use a shader ... 你可以使用着色器......

you pass as parameter to the terrain shader, the 3D world position of your cursor, and a radius... to define a sphere, 您将参数传递给terrain地形着色器,光标的3D世界位置以及半径...以定义球体,

the trick is pass the vertex world position from the vertex shader to the pixel shader, and in the pixel shader you only have to tint the output color if the pixel is being drawed, is inside the sphere. 诀窍是将顶点世界位置从顶点着色器传递到像素着色器,并且在像素着色器中,如果要绘制像素,则只需在输出颜色上着色,就在球体内部。

EDIT: I have found an old shader done by myself... with two types of selection circle and box, here you are: 编辑:我发现了一个由我自己完成的旧着色器...有两种类型的选择圈和框,你在这里:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM