SkyDome

模型:

生成一个弧形的顶

//===========================================================================
    //      
    //          x = r * cos(phi) * sin(theta)
    //          y = r * sin(phi) * sin(theta)
    //          z = r * cos(theta)
    //
    //          这里phi的范围是0 < phi <= 2Pi,theta范围是0 < theta < Pi
    //          半球的theta范围是[0, Pi/2]
    //          因为使用单位向量r=1,所以上述公式简化为:
    //
    //          x = cos(phi) * sin(theta)
    //          y = sin(phi) * sin(theta)
    //          z = cos(theta)
    //
    //------------------------------------------------------------------------------            
    //
    //        1) 我们必须注意顶点是以逆时针顺序绘制的,因为我们是从天空球内部向外看的。
    //
    //        2) uv坐标必须正确计算。
    //
    //
    //          最终我们获得以下公式:
    //
    //          x =  cos(phi) * sin(theta)
    //          y =  cos(theta)
    //          z =  sin(phi) * sin(theta)
    //
    //===========================================================================
	int cylinders = 100; // 水平面数
	int slices = 100; // 垂直面数
	mVertexCount = (slices + 1) * (cylinders + 1);
	mIndexCount  = (3 * slices * (cylinders + 1)) * 2;
	float verticalRadians = PI;
	
	vertices = new VertexBuffer[mVertexCount];
	indices = new unsigned long[mIndexCount];

	float stackAngle = verticalRadians / (float)slices;
    float sliceAngle = (float)(PI * 2.0) / (float)cylinders;
    int wVertexIndex = 0;

	int vertcount = 0;
    int Indexcount = 0;

	for (int stack = 0; stack < (slices + 1); stack++)
    {
        float r = sin((float)stack * stackAngle);
        float y = cos((float)stack * stackAngle);
 
        for (int slice = 0; slice < (cylinders + 1); slice++)
        {
            float z = r * sin((float)slice * sliceAngle); //* -1;
            float x = r * cos((float)slice * sliceAngle);
 
            vertices[vertcount].position = Vector3(x, y, z);
            //vertices[vertcount].texture = Vector2(1.0f - (float)slice / (float)cylinders, (float)stack / (float)slices);
            vertcount++;
            if (!(stack == (slices - 1)))
            {
                indices[Indexcount] = wVertexIndex + (cylinders + 1);
                Indexcount++;
                indices[Indexcount] = wVertexIndex + 1;
                Indexcount++;
                indices[Indexcount] = wVertexIndex;
                Indexcount++;
                indices[Indexcount] = wVertexIndex + (cylinders);
                Indexcount++;
                indices[Indexcount] = wVertexIndex + (cylinders + 1);
                Indexcount++;
                indices[Indexcount] = wVertexIndex;
                Indexcount++;
                wVertexIndex++;
            }
        }
    }

 

hlsl:这里需要注意的是:output.tex = input.position 纹理坐标是模型的相对坐标,而建模的时候球心要为相对坐标的(0,0,0)位置。

TextureCube mCubeTexture;
SamplerState mSamplerState;

/
// GLOBALS //
/
cbuffer MatrixBuffer
{
    matrix world;
	matrix transform;
};

//
// TYPEDEFS //
//
struct VertexInputType
{
    float4 position : POSITION;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
	float3 tex :TEXCOORD;
};


// Vertex Shader

PixelInputType PortVertexShader(VertexInputType input)
{
    PixelInputType output;

    input.position.w = 1.0f;

    output.position = normalize(mul(input.position, transform));

    output.tex = input.position; //用local坐标做为cubemap查询向量.

    return output;
}


// Pixel Shader

float4 PortPixelShader(PixelInputType input) : SV_TARGET
{
    float4 color = mCubeTexture.Sample(mSamplerState, input.tex);
    return color;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值