【问题标题】:How to draw a circle on 3D terrain in XNA?如何在 XNA 中的 3D 地形上画一个圆?
【发布时间】:2011-11-03 18:37:44
【问题描述】:

所以我一直在网上寻找这个问题的答案,但我似乎遗漏了一些东西。

我有一个在 XNA 4.0 中动态创建 3D 地形的小项目,但我希望能够在地形上绘制一个圆形(或任何其他形状,但让我们首先使用一个圆形)。 现在我已经阅读了一些关于“投影纹理”的内容,但我承认在着色器语言方面我完全不知所措。

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

有人知道怎么做吗,是否需要为此使用着色器?感谢您对此事的任何帮助!

提前致谢!

【问题讨论】:

    标签: c# 3d xna textures terrain


    【解决方案1】:

    你可以使用着色器...

    您将作为参数传递给地形着色器、光标的 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;       
        }
    } 
    

    【讨论】:

    • 那么我需要在着色器中为光标的vector3设置一个参数吗?还是有其他方法可以将其传递给着色器?
    • 您可以将其作为顶点的一部分传递,但没有任何意义,因为您只有一个光标,这将是一种浪费。
    • 我添加了一个我之前做的着色器。
    • 这确实很有帮助。我也没有听说过 HLSL 中的 distance 和 lerp 函数,所以这很开放。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多