如何在 XNA 的 3D 地形上画一个圆圈? [英] How to draw a circle on 3D terrain in XNA?

查看:25
本文介绍了如何在 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 个单位"的圆,然后在地形上绘制它,作为光标所在位置的指示器.(我能够在 3D 地形上获得光标位置.)

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

有谁知道如何做到这一点,是否需要为此使用着色器?对此事的任何帮助表示赞赏!

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,

诀窍是将顶点世界位置从顶点着色器传递给像素着色器,并且在像素着色器中,如果正在绘制的像素位于球体内部,则您只需为输出颜色着色.

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天全站免登陆