2
\$\begingroup\$

I have a World with a 3D model of a head in it and that World rotates, like such:

protected override void Update(GameTime gameTime)
{
    //other stuff

    angle += 0.00005f;

    //more other stuff
}

protected override void Draw(GameTime gameTime)
{
    //other stuff
    Matrix rotation = Matrix.CreateRotationY(3 * angle);
    effect.Parameters["World"].SetValue(rotation * Matrix.CreateScale(10.0f));

    // other stuff
}

And then in my Effects file I create a spotlight:

float4 SimplePixelShader(VertexShaderOutput input) : COLOR0
{
    float4 lightDirection = { 1, 1, 1, 0 };
    float theta = 10.0f;
    float phi = 30.0f;
    float4 color;
    float4 lambert = DiffuseColor * 0.2 * max(0, dot(input.Normals, input.lambertLightDir));

    float angle = acos(dot(input.lightDir, normalize(lightDirection)));
    if(angle > radians(phi))
        color = AmbientColor * AmbientIntensity;
    else if(angle < radians(theta))
        color = lambert;
    else
        color = max(AmbientColor * AmbientIntensity, smoothstep(radians(phi), radians(theta), angle) * lambert);

    return color;
}

And naturally this spotlight also rotates with the world. However, I dont want it to rotate. I tried everything, multiplying, adding, subtracting the rotation matrix and/or the angle from the different lightdirections and angles and nothing works.

Now I could rotate just the model and not the world, that would even be a sensible thing to do, but I have no clue how :P So I'm either looking for a good way to rotate the model or a way to 'counter rotate' the spotlight so it seems to stand still.

Edit: my vertexshader:

VertexShaderOutput SimpleVertexShader(VertexShaderInput input)
{
//some other vertexshaderstuff

    float4 lightPoint = {-3, -2, -2, 0};

    output.lightDir = normalize(input.Position3D) - lightPoint;

    output.lambertLightDir = float4(30, 30, 20, 0);

    return output;
}
\$\endgroup\$
3
  • \$\begingroup\$ Are you using XNA? \$\endgroup\$
    – House
    Commented Aug 11, 2013 at 13:26
  • \$\begingroup\$ When adding code, use the Code Sample button (the curly braces {}) to format the code properly. \$\endgroup\$
    – House
    Commented Aug 11, 2013 at 16:08
  • \$\begingroup\$ @Byte56 updated my post using the code sample button :) I am indeed using xna \$\endgroup\$
    – Hasse Iona
    Commented Aug 11, 2013 at 16:57

2 Answers 2

1
\$\begingroup\$

If your "Input.position3D" and your "lightPoint" are not affected by the World Matrix in any way the resulting "lightDir" will allways be the same no matter which Rotation you use there, since you rotate your model for output it will rotate but still keep its constant lighting which will look like the light would rotate with the model.

output.lightDir = normalize(input.Position3D) - lightPoint;

this should be something like

output.lightDir = normalize(worldPos - lightPoint);

where worldPos is the Input.pos3D transformed with your world Matrix, the one you use for position output of the vertexshader.

\$\endgroup\$
1
\$\begingroup\$

By looking at your code it seems that you are already rotating your object. The world matrix is a term used to describe the total transformation that you are applying to whatever you draw after that assignment. In order to "rotate the world", you'd have to change the position of your camera to follow a circular path for example. But by setting a rotation matrix as the World matrix of an effect, you are applying it to whatever is rendered with that effect activated.

Edit You should not normalise your object's position (input.Position3D) as it is a point, not a vector. You should normalise the result, i.e.: normalize(input.Position3D - lightPoint);

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the reply :) Edited my first post to contain my vertexshader \$\endgroup\$
    – Hasse Iona
    Commented Aug 11, 2013 at 16:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .