Спонсор: Microsoft
Санкт-Петербургский государственный политехнический университет
Опубликован: 09.12.2013 | Доступ: свободный | Студентов: 2048 / 28 | Длительность: 06:23:00
Специальности: Программист
Самостоятельная работа 8:

Шейдеры. Точечные источники света

< Самостоятельная работа 1 || Самостоятельная работа 8: 12

Реализация:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Primitives3D;

namespace Lab8
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        TeapotPrimitive teapot;
        Effect effect;

        SpherePrimitive pointLight;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            teapot = new TeapotPrimitive(GraphicsDevice);
            pointLight = new SpherePrimitive(GraphicsDevice, 0.1f, 20);
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            effect = Content.Load<Effect>("light");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Add your drawing code here
            Vector3 cameraPosition = new Vector3(0, 0, 8);
            Matrix world = Matrix.CreateRotationY((float)gameTime.TotalGameTime.TotalSeconds);
            Matrix view = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
            Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 0.1f, 20);


            Vector3 lightPos0 = new Vector3(0, -1, 1);
            Vector3 lightPos1 = new Vector3(1, 1, 1);
            Vector3 lightPos2 = new Vector3(-2, 0, 0);
            // Источники света

            pointLight.Draw(Matrix.CreateTranslation(lightPos0), view, proj, Color.Blue);
            pointLight.Draw(Matrix.CreateTranslation(lightPos1), view, proj, Color.Blue);
            pointLight.Draw(Matrix.CreateTranslation(lightPos2), view, proj, Color.Blue);


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

            effect.Parameters["LightPosition0"].SetValue(lightPos0);
            effect.Parameters["LightPosition1"].SetValue(lightPos1);
            effect.Parameters["LightPosition2"].SetValue(lightPos2);

            effect.Parameters["AmbientColor0"].SetValue(new Vector4(0.1f, 0.1f, 0.1f, 1));
            effect.Parameters["DiffuseColor0"].SetValue(new Vector4(0.5f, 0f, 0f, 1));
            effect.Parameters["SpecularColor0"].SetValue(new Vector4(1, 0, 0, 1));

            effect.Parameters["AmbientColor1"].SetValue(new Vector4(0.1f, 0.1f, 0.1f, 1));
            effect.Parameters["DiffuseColor1"].SetValue(new Vector4(0, 0.5f, 0.5f, 1));
            effect.Parameters["SpecularColor1"].SetValue(new Vector4(0, 1, 1, 1));

            effect.Parameters["AmbientColor2"].SetValue(new Vector4(0.1f, 0.1f, 0.1f, 1));
            effect.Parameters["DiffuseColor2"].SetValue(new Vector4(0.5f, 0.5f, 0.5f, 1));
            effect.Parameters["SpecularColor2"].SetValue(new Vector4(1, 1, 1, 1));

            effect.Parameters["Eye"].SetValue(cameraPosition);
            effect.Parameters["World"].SetValue(world);
            effect.Parameters["View"].SetValue(view);
            effect.Parameters["Projection"].SetValue(proj);

            effect.Parameters["Color"].SetValue(new Vector4(1, 1, 0, 1));

            teapot.Draw(effect);

            effect.Parameters["World"].SetValue(world * Matrix.CreateTranslation(0, 2, 0));
            teapot.Draw(effect);

            effect.Parameters["World"].SetValue(world * Matrix.CreateTranslation(-3, 0, 0));
            teapot.Draw(effect);

            base.Draw(gameTime);
        }
    }
}

Шейдер light.fx:

float4x4 World;
float4x4 View;
float4x4 Projection;

float ka = 1;
float kd = 0.5;
float ks = 1;
float SpecularPower = 4;

// Собственный цвет объекта
float4 Color = float4(1, 0, 0, 1);


float4 AmbientColor0 = float4(0.1, 0.1, 0.1, 1);
float4 DiffuseColor0 = float4(1,1,1,1);
float4 SpecularColor0 = float4(1,1,1,1);

float4 AmbientColor1 = float4(0.1, 0.1, 0.1, 1);
float4 DiffuseColor1 = float4(1,1,1,1);
float4 SpecularColor1 = float4(1,1,1,1);

float4 AmbientColor2 = float4(0.1, 0.1, 0.1, 1);
float4 DiffuseColor2 = float4(1,1,1,1);
float4 SpecularColor2 = float4(1,1,1,1);

// Предполагается, что координаты источников света заданы в мировых координатах
float3 LightPosition0 = float3(0,0,2);
float3 LightPosition1 = float3(2,0,0);
float3 LightPosition2 = float3(-2,0,0);

float3 Eye;

// TODO: add effect parameters here.

struct VertexShaderInputPhong
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL;

    // TODO: add input channels such as texture
    // coordinates and vertex colors here.
};

struct VertexShaderOutputPhong
{
    float4 Position : POSITION0;
    float3 WorldPosition : TEXCOORD0;
    float3 Normal : TEXCOORD1;

    // TODO: add vertex shader outputs such as colors and texture
    // coordinates here. These values will automatically be interpolated
    // over the triangle, and provided as input to your pixel shader.
};

VertexShaderOutputPhong VertexShaderFunctionPhong(VertexShaderInputPhong input)
{
    VertexShaderOutputPhong output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    float3 worldNormal = normalize(mul(input.Normal, World));
    output.Position = mul(viewPosition, Projection);
    output.WorldPosition = worldPosition;
    output.Normal = worldNormal;
    
    // TODO: add your vertex shader code here.

    return output;
}


float4 PointLight(float3 LightPosition, float3 worldPosition, float3 worldNormal, float4 AmbientColor, float4 DiffuseColor, float4 SpecularColor)
{
    float4 Ambient = ka * AmbientColor;
    
    float3 lightDirection = normalize(LightPosition - worldPosition);
    float4 Diffuse = kd * max(0, dot(worldNormal, lightDirection)) * DiffuseColor;
    
    float3 eyeDirection = normalize(Eye - worldPosition);
    float3 reflectedLight = normalize(reflect(-lightDirection, worldNormal));
    float4 Specular = ks * pow(max(0, dot(eyeDirection, reflectedLight)), SpecularPower) * SpecularColor;

	// для упрощения коэффициент затухания равен 1/d^2
    return (Ambient + Diffuse + Specular) / pow(length(worldPosition-LightPosition), 2);

}

float4 PixelShaderFunctionPhong(VertexShaderOutputPhong input) : COLOR0
{
    // TODO: add your pixel shader code here.
    float3 worldPosition = input.WorldPosition;
    float3 worldNormal = normalize(input.Normal);
    
    float4 light0 = PointLight(LightPosition0, worldPosition, worldNormal, AmbientColor0, DiffuseColor0, SpecularColor0);
    float4 light1 = PointLight(LightPosition1, worldPosition, worldNormal, AmbientColor1, DiffuseColor1, SpecularColor1);
    float4 light2 = PointLight(LightPosition2, worldPosition, worldNormal, AmbientColor2, DiffuseColor2, SpecularColor2);
    
    return Color * (light0 + light1 + light2);
}

technique Phong
{
    pass Pass1
    {
        // TODO: set renderstates here.

        VertexShader = compile vs_1_1 VertexShaderFunctionPhong();
        PixelShader = compile ps_3_0 PixelShaderFunctionPhong();
    }
}
< Самостоятельная работа 1 || Самостоятельная работа 8: 12
Сергей Попов
Сергей Попов

Компелятор говорит что у StorageContainer нет свойства TotalStorage, как решить эту проблему ?

ost dem
ost dem

не работает 

        AudioEngine engine;
        WaveBank waveBank;
        SoundBank soundBank;

пишет

Ошибка    2    Не удалось найти имя типа или пространства имен "AudioEngine" (пропущена директива using или ссылка на сборку?)    

 

так же не работает

using Microsoft.Xna.Framework.Xact;

пишет 

Ошибка    1    Имя типа или пространства имен "Xact" отсутствует в пространстве имен "Microsoft.Xna.Framework" (пропущена ссылка на сборку?)   

как это исправить?