Sign in to follow this  

HLSL lighting

This topic is 3717 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Not just real sure where to put this as it seems like a poor fit anywhere, but here we are. I'm trying to learn enough HLSL to at get some of the basic shaders out there running along with the XNA framework. I have zero sharder experience before now BTW. So far I've been to every website I can find and after two days of banging my head against the monitor I'm finally starting to get a very fuzzy picture of how things fit together. I'm along way from where I want to be, and where I'm at is stuck trying to recreate the BasicEffect built into XNA. Where I want to be is combine the environment mapping and normal mapping effects that are on the XNA creators website. I've tried setting up a simple effect in XNA per MSDN. I then tried several example shaders from various websites on the subject. The same thing always happens. The loaded models always load fine. Vertex colors are fine and texture mapping is always fine. Lighting on the other hand I can not get to work to save my life. Which may be an issue seeing as how I'm about 1 hour from jumping out a window. One has to assume the shaders are fine and I'm failing to set up the shader some how, but I'm not really sure. I guess if I was I wouldn't be here right now. It all very annoying seeing as how there doesn't seem to be much to it but I can't figure it out. Anyway I will post the code for smarter people to look at. Its basically all spliced together from various places and its just one of may forms it has taken on. HLSL
 float4x4 worldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4x4 world :WORLD; //world matrix
float4 lightPos = float4(-10, 0, 4,1);

//application to vertex structure
struct a2v
{
    float4 position : POSITION0;
    float3 normal : NORMAL0;
    float2 texCoord : TEXCOORD0;
};

//vertex to pixel shader structure
struct v2p
{
    float4 position : POSITION0;
    float2 texCoord : TEXCOORD0;
    float4 color : COLOR0;
};

//VERTEX SHADER
void vs( in a2v IN, out v2p OUT)
{
    OUT.position = mul(IN.position, worldViewProj); //getting to position to object space
    float3 posWorld = mul(IN.position, world).xyz; //get the vertex to world space
    float3 normal = mul(IN.normal, world).xyz; //get the normal to world space
    float3 light = normalize(lightPos - posWorld); //calculating the light direction
    float lightIntensity = clamp(dot(normal, light), 0, 1); //calculate the light intensity and clamp it to a range
    float3 lightColor = float3(1.0f, 1.0f, 1.0f); //set the light color
    float4 color = float4(lightColor * lightIntensity, 1.0f); //calculate the color of the vertex
    color.rgb += 0.5f; //add an ambient color to the shader
    OUT.color = clamp(color, 0, 1); //set the color to the output color
    OUT.texCoord = IN.texCoord;
}

technique TransformTechnique
{
    pass p0
    {
        vertexshader = compile vs_1_1 vs();
    }
}


using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    ContentManager content;

    Model model;

    Matrix worldViewProjection;
    Effect effect;   

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        content = new ContentManager(Services);
    }

    protected override void Initialize()
    {
        base.Initialize();
    }


    private void InitializeTransform()
    {
        float tilt = (float)Math.PI / 8.0f;
        // Use the world matrix to tilt the cube along x and y axes.
        Matrix world = Matrix.CreateRotationX(tilt) *
            Matrix.CreateRotationY(tilt);

        Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero,
            Vector3.Up);

        Matrix projection = Matrix.CreatePerspectiveFieldOfView(
            (float)Math.PI / 4.0f,  // 2 PI Radians is 360 degrees, so this is 45 degrees.
            (float)graphics.GraphicsDevice.Viewport.Width /
            (float)graphics.GraphicsDevice.Viewport.Height,
            1.0f, 100.0f);

        worldViewProjection = world * view * projection;

    }

    private void InitializeEffect()
    {

        effect = content.Load<Effect>(".\\content\\basicshader");
        effect.Parameters["worldViewProj"].SetValue(worldViewProjection);
        effect.CurrentTechnique = effect.Techniques["TransformTechnique"];

    }

    protected override void LoadGraphicsContent(bool loadAllContent)
    {
        InitializeTransform();
        if (loadAllContent)
        {
            model = content.Load<Model>("Content/models/box");
            InitializeEffect();           
        }
    }

   

    protected override void UnloadGraphicsContent(bool unloadAllContent)
    {
        if (unloadAllContent == true)
        {
            content.Unload();
        }
    }

    protected override void Update(GameTime gameTime)
    {
        // Allows the default game to exit on Xbox 360 and Windows.
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        base.Update(gameTime);
    }

    
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice device = graphics.GraphicsDevice;

        device.Clear(Color.CornflowerBlue);

        // Calculate the camera matrices.
        Viewport viewport = device.Viewport;

        float aspectRatio = (float)viewport.Width / (float)viewport.Height;

        float time = (float)gameTime.TotalGameTime.TotalSeconds;
       

        Matrix rotation = Matrix.CreateRotationX(time * 0.3f) *
                          Matrix.CreateRotationY(time);

        Matrix view = Matrix.CreateLookAt(new Vector3(250, 0, 0),
                                          Vector3.Zero,
                                          Vector3.Up);

        Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                                                                aspectRatio,
                                                                10, 10000);        

        // Draw the model.
        Matrix[] transforms = new Matrix[model.Bones.Count];

        model.CopyAbsoluteBoneTransformsTo(transforms);

        foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (Effect effect in mesh.Effects)
            {                
                Matrix world = transforms[mesh.ParentBone.Index] * rotation;
                
                effect.Parameters["World"].SetValue(world);
                effect.Parameters["View"].SetValue(view);
                effect.Parameters["Projection"].SetValue(projection);                
            }

            mesh.Draw();
        }

        base.Draw(gameTime);
    }
}



Share this post


Link to post
Share on other sites
It seems as though you're trying to compute the the color of objects in the vertex shader, but you need the pixel shader to output color.

so for example you should set up your vertex and pixel shader like so:

//vertex to pixel shader structure
struct v2p
{
float4 posH : POSITION0;
float3 position : TEXCOORD0;
float3 normal : TEXCOORD1;
float2 texCoord : TEXCOORD2;
};

//VERTEX SHADER
void vs( in a2v IN, out v2p OUT)
{
OUT = (v2p)0;

OUT.posH = mul(IN.position, worldViewProj); //getting to position to object space
OUT.position = mul(IN.position, world).xyz; //get the vertex to world space
OUT.normal = mul(IN.normal, world).xyz; //get the normal to world space
OUT.texCoord = IN.texCoord;
}

float4 ps(in v2p IN) : color
{
float3 normal = normalize(IN.normal);

float3 light = normalize(lightPos - IN.position); //calculating the light direction
float lightIntensity = clamp(dot(normal, light), 0, 1); //calculate the light intensity and clamp it to a range
float3 lightColor = float3(1.0f, 1.0f, 1.0f); //set the light color
float4 color = float4(lightColor * lightIntensity, 1.0f); //calculate the color of the vertex
color.rgb += 0.5f; //add an ambient color to the shader
return clamp(color, 0, 1); //set the color to the output color
}

technique TransformTechnique
{
pass p0
{
vertexshader = compile vs_1_1 vs();
pixelshader = compile ps_2_0 ps();
}
}

Share this post


Link to post
Share on other sites
Quote:
Original post by glaeken
It seems as though you're trying to compute the the color of objects in the vertex shader, but you need the pixel shader to output color.

so for example you should set up your vertex and pixel shader like so:
*** Source Snippet Removed ***


No dice. I got the same thing. A solid color and texture only.

Share this post


Link to post
Share on other sites
Oh I forgot to mention that you need to make sure your model has valid normals also. I'm not sure if this is the problem as I haven't looked at your source, just the shader file.

Share this post


Link to post
Share on other sites
Quote:
Original post by glaeken
Oh I forgot to mention that you need to make sure your model has valid normals also. I'm not sure if this is the problem as I haven't looked at your source, just the shader file.


As far as I can tell they do. I've used several models. Some I have made plus ones included with the XNA starter kit. The "BasicEffect" default lighting works great for all the models. Just doesn't work when I try to do it.

I feel like I have a massive knowledge gap between the HLSL code and the actual application. You can't run a search without tripping all over shader files but I haven't seen much on integrating them with an application.

Share this post


Link to post
Share on other sites
I think I figured it out. I pasted your code into FxComposer and it wouldn't show anything. It seems you've used the wrong semantics:

float4x4 worldViewProj : ViewProjection; //our world view projection matrix
float4x4 world : World; //world matrix

This will perfectly draw every object in FxComposer with a nice Phong shading. However, when I look at your code, I'm not shure if it work with your's, since you seem to be setting the View and Projection matrix. But in your file, you have both combined. I've never worked with XNA, but I would guess you need to set effect.Parameters["ViewProjection"].SetValue( View * Projection ); or something like that.

And believe me: Working with shaders is a pain in the arse ;) I think its normal to get so frustrated that you want to bang your head onto the desktop, I feel that way everytime I work with shaders, however it seems to get better, a little ;)
You might want to look into FxComposer2.0 and specially shader mill. It's a great programm that lets you create your effects in no time with little experience and then exports your shader to hlsl.

Share this post


Link to post
Share on other sites
There are too many fallible links in the shader chain for you to assume that things will just work. Often, there problem is caused by several simultaneous faults. For this reason, glancing over the code to check everything is in order is not time well-spent.

You can get to the bottom of the problem by debugging the shaders. Use PIX to create frame capture, then find an appropriate draw call and step through the vertex shader. If everything is on order, proceed to the render pane and step through the pixel shader. From here, it will be very easy to diagnose the most common causes of problems: if a shader is not executing, receiving the wrong semantics, performing the wrong calculation or using an uninitialised parameter, it will be clear, and you'll know how to proceed.

Admiral

Share this post


Link to post
Share on other sites

This topic is 3717 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this