본문 바로가기
프로그래밍

커스텀쉐이더 이용하기

by 건우아빠유리남편 2009. 7. 14.
반응형

커스텀쉐이더를 이용하여 3D모델을 표시하는 프로그램을 만든다.

 

리소스 추가

이번 프로그램에서는 3D모델 하나와 텍스쳐 한 장과 효과 하나를 사용합니다.

모델과 텍스쳐는 XNA Creators Club 에서 가지고 왔습니다.

폴더구성은 다음과 같습니다.

 

효과파일 편집

TextureEffect.fx를 편집한다.

 

 

TextureEffect.fx

float4x4 worldViewProj : WORLDVIEWPROJECTION;

texture  cubeTexture;

 

struct VS_INPUT {

    float4 pos      : POSITION;

    float4 texcoord : TEXCOORD0;

};

 

struct VS_OUTPUT {

    float4 pos      : POSITION;

    float4 texcoord : TEXCOORD0;

};

 

sampler textureSampler = sampler_state {

    Texture  =<cubeTexture>;

    mipfilter=LINEAR;

};

 

VS_OUTPUT VS_TextureTech(VS_INPUT In) {

 

    VS_OUTPUT Out=(VS_OUTPUT)0;

 

    Out.pos     =mul(In.pos,worldViewProj);

    Out.texcoord=In.texcoord;

 

    return Out;

}

 

float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {

    return tex2D(textureSampler,Out.texcoord).rgba;

}

 

technique TextureTech {

    pass P0 {

        vertexShader=compile vs_2_0 VS_TextureTech();

        pixelShader =compile ps_2_0 PS_TextureTech();

    }

}

 

 

 

소스코드 편집

Game1.cs를 편집한다.

Game1.cs

using System;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using Microsoft.Xna.Framework.Audio;

 

//커스텀 쉐이더 이용하기

namespace CustomShaderEx {

    public class Game1 : Microsoft.Xna.Framework.Game {

        //그래픽스

        private GraphicsDeviceManager graphics; //그래픽스

        private ContentManager        content; //컨텐츠

 

        //모델

        private Model   model;                  //모델

        private Vector3 modelPos = Vector3.Zero; //모델 위치

        private float   modelRot = 0.0f;        //모델 회전

 

        //텍스쳐

        private Texture texture; //텍스쳐

 

        //이펙트

        private Effect          effect;            //이펙트

        private EffectParameter worldViewProjParam; //변환행렬

 

        //카메라

        private float   aspectRatio; //종횡도

        private Vector3 cameraPos;  //카메라위치

 

        //constructor

        public Game1() {

            //그래픽스

            graphics = new GraphicsDeviceManager(this);

            content  = new ContentManager(Services);

 

            //화면사이즈

            graphics.PreferredBackBufferWidth  = 853;

            graphics.PreferredBackBufferHeight = 480;

        }

 

        //초기화

        protected override void Initialize() {

            base.Initialize();

        }

 

        //그래픽스 컨텐츠의 로드

        protected override void LoadGraphicsContent(bool loadAllContent) {

            if (loadAllContent) {

                //모델 읽어오기

                model = content.Load<Model>(@"Content\Models\p1_wedge");

 

                //텍스쳐 읽어오기

                texture = content.Load<Texture2D>(@"Content\Textures\wedge_p1_diff_v1");

               

                //이펙트 불러오기

                effect = content.Load<Effect>(@"Content\Shaders\TextureEffect");

                effect.CurrentTechnique = effect.Techniques["TextureTeck"];           

                worldViewProjParam      = effect.Parameters["worldViewProj"];

 

                //텍스쳐에 이펙트 주기

                effect.Parameters["UserTexture"].SetValue(texture);              

 

                //모델에 이펙트 주기

                foreach (ModelMesh mesh in model.Meshes) {

                    for(int i = 0;i < mesh.MeshParts.Count;i++) {

                        mesh.MeshParts[i].Effect = effect;

                    }           

                }

            }

 

            //카메라 초기화

            aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /

                graphics.GraphicsDevice.Viewport.Height;  //종횡도

            cameraPos = new Vector3(0.0f, 50.0f, 5000.0f); //카메라

        }

 

        //그래픽스 컨텐츠 놓기

        protected override void UnloadGraphicsContent(bool unloadAllContent) {

            if (unloadAllContent) content.Unload();

        }

 

        //업뎃

        protected override void Update(GameTime gameTime) {

            //어플리케이션 종료

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) {

                this.Exit();

            }

 

            //모델 회전

            modelRot += (float)gameTime.ElapsedGameTime.TotalMilliseconds *

                MathHelper.ToRadians(0.1f);

 

            //베이스 업뎃

            base.Update(gameTime);

        }

 

        //그리기

        protected override void Draw(GameTime gameTime) {

            //배경 그리기

            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

 

            //월드 매트릭스

            Matrix world =

                Matrix.CreateRotationY(modelRot) *  //모델 회전

                Matrix.CreateTranslation(modelPos); //모델 위치

                   

            //뷰 매트릭스

            Matrix view = Matrix.CreateLookAt(

                cameraPos,   //카메라위치

                Vector3.Zero, //참조점

                Vector3.Up); //UP레벨

                   

            //사영 변환행렬

            Matrix projection = Matrix.CreatePerspectiveFieldOfView(

                MathHelper.ToRadians(45.0f), //시야각(라디안단위)

                aspectRatio,                //종횡도

                1.0f,                       //니어 클립면의 거리

                10000.0f);                  //파 클립면의 거리

              

 

            //효과 커밋 체인지

            effect.CommitChanges();

 

            //월드xx사영 매트릭스

            worldViewProjParam.SetValue(world * view * projection);

 

            //모델 그리기

            foreach (ModelMesh mesh in model.Meshes) {

                mesh.Draw();

            }

 

            //베이스 그리기

            base.Draw(gameTime);

        }

    }

}

 

반응형

'프로그래밍' 카테고리의 다른 글

ViewingPipeline  (0) 2009.07.14
3D프리미티브 표시하기  (0) 2009.07.14
3D모델 조작하기  (0) 2009.07.14
간단한 버튼이나 메뉴 키이벤트 처리 방법  (0) 2009.07.14
How To XNA : 2. 비어있는 게임 화면과 구조  (0) 2009.07.14

댓글