如何绘制XNA的3D地形一个圈? [英] How to draw a circle on 3D terrain in XNA?

查看:293
本文介绍了如何绘制XNA的3D地形一个圈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我一直在寻找在网络找到了这个问题的答案,但我似乎失去了一些东西。

So I've been looking across the web to find an answer to this question, but I seem to be missing something.

我有一个小项目将是动态的XNA 4.0创建的3D地形,但我希望能画一个圆(或任何其他形状的这个问题,但首先让我们一起去圆)地形。 现在,我读过一些关于投影纹理,但我承认我在一个完全丧失,当涉及到着色器语言。

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. 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.

我们的想法是,我可以(动态)创建一个基本形状,说有2'单位'直径的圆,然后绘制地形充当指示器光标所在。 (我能得到的三维地形光标位置。)

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. (I am able to get the cursor position on the 3D terrain.)

请问有谁知道如何做到这一点,是它需要使用着色器呢?对此事的任何帮助是preciated!

Would anyone know how to do this, is it required to use shaders for this? Any help on the matter is apreciated!

在此先感谢!

推荐答案

您可以使用着色器...

You can use a shader ...

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

you pass as parameter to the terrain shader, the 3D world position of your cursor, and a radius... to define a sphere,

关键是通过从顶点着色器像素着色顶点世界位置, 在像素着色器,你只需要着色输出颜色如果像素被drawed,是球内。

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.

编辑:我发现了一个古老的着色器由我自己完成的......有两种选择圈,框,在这里你是:

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

这篇关于如何绘制XNA的3D地形一个圈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆