Как нарисовать круг на 3D местности в XNA? - PullRequest
1 голос
/ 03 ноября 2011

Итак, я искал ответ в Интернете, чтобы найти ответ на этот вопрос, но, похоже, что-то упустил.

У меня есть небольшой проект, который динамически создает трехмерную местность в XNA 4.0, но я хочу иметь возможность нарисовать круг (или любую другую фигуру, но давайте сначала с кругом) на местности. Теперь я прочитал кое-что о «проективном текстурировании», но признаюсь, что совершенно потерян, когда дело доходит до языка шейдеров.

Идея состоит в том, что я могу (динамически) создать базовую фигуру, скажем, круг с диаметром 2 единицы, а затем нарисовать ее на местности, чтобы функционировать в качестве индикатора, где находится курсор. (Я могу получить положение курсора на 3D-местности.)

Кто-нибудь знает, как это сделать, нужно ли для этого использовать шейдеры? Любая помощь по этому вопросу приветствуется!

Заранее спасибо!

1 Ответ

4 голосов
/ 03 ноября 2011

Вы можете использовать шейдер ...

, который вы передаете в качестве параметра для шейдера ландшафта, 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;       
    }
} 
...