Some problems with a Diffuse Lighting Tutorial (HLSL shader)

Hi there,
I did some basic tutorial and got some errors with it. Creating a Diffuse Lighting Shader - RB Whitaker's Wiki

some side notes:
1)The model didn’t work (old format), did my own normal map
2)setting a default value didn’t work as well. I added static.
3)at dot(normal, DiffuseLightDirection); he is using a float4 and a float3

after several testing I got a working version of the code:

float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 WorldIT;
Texture xTexture;
static float4 AmbientColor = float4(1, 1, 1, 1);
static float AmbientIntensity = 0.1;
static float3 DiffuseLightDirection = float3(0, 0, -1);
static float4 DiffuseColor = float4(1, 1, 1, 1);
static float DiffuseIntensity = 1.0;
sampler TextureSampler = sampler_state { texture = <xTexture> ; magfilter = POINT; minfilter = POINT; mipfilter=POINT; AddressU = mirror; AddressV = mirror;};
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float2 TexCoords    : TEXCOORD0;
};
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Color        : COLOR0;
    float2 TexCoords    : TEXCOORD0;
};
struct PixelToFrame
{
    float4 Color        : COLOR0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput inPos)
{
    VertexShaderOutput output ;
    float4 worldPosition = mul(inPos.Position, World);
    float4 viewPosition = mul(worldPosition, View);   
    output.Position  = mul(viewPosition, Projection);
    float3 nn = normalize(inPos.Normal.xyz);
    float4 normal = normalize(mul( float4(nn,0) , WorldIT)); // work (C)
    //float4 normal = mul( float4(nn,0) , WorldIT); //do not work (A)
    //float3 normal = normalize(mul( nn , (float3x3)WorldIT)); //do not work (B)
    float lightIntensity = dot(normal.xyz, normalize(DiffuseLightDirection));
    output.Color =  saturate(DiffuseColor*DiffuseIntensity*lightIntensity);
    output.TexCoords = inPos.TexCoords;
    return output;
}
PixelToFrame PixelShaderFunction(VertexShaderOutput input)
{
    PixelToFrame output = (PixelToFrame)0;    
    float4 objectColor = tex2D(TextureSampler, input.TexCoords);
    output.Color = saturate(objectColor+ input.Color);
    return output;
}
technique Diffuse
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

My question is related to the part:

    float3 nn = normalize(inPos.Normal);
    float4 normal = normalize(mul( float4(nn,0) , WorldIT)); // work (C)
    //float4 normal = mul( float4(nn,0) , WorldIT); //do not work  (A)
    //float3 normal = normalize(mul( nn , (float3x3)WorldIT)); //do not work (B)
    float lightIntensity = dot(normal.xyz, normalize(DiffuseLightDirection));

(A) Why I need to normalize after the multiplication with the WorldIT-matrix (inverse,transp.) (and can’t do it in dot function instead)?
(B) Why the (float3x3) cast dont work?

(C) If I want to take translation of the World into account →

float4 normal = normalize(mul( float4(nn,1) , WorldIT));

and after this get the first 3 cooridnates form it, how do I normalize it properly?

for (A) and (B) I get a System.ArgumentException:

System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

Dear mgan! I was wondering you managed to figure out what’s going on in the code and why won’t it either compile, or in case the variables are not set to static the screen just appears to be blank.

I would greatly appreciate your response :slightly_smiling:

Hi folks,

starting my “shaders conversion campaign”, I get this one to work, don’t know what and why man failed, I just update the VS/PS version + POSITION0 => SV_POSITION and the tricky COLOR0 => COLOR in the PixelShaderFunction header (taken from the default MG pipeline effect), and despite two warning with the ‘dot’ function (implicit truncation of vector type), it looks like to be ok, ie the picture I get is the same as the one displayed in the tutorial.

This is the shader code:
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;

float4x4 WorldInverseTranspose;

float3 DiffuseLightDirection = float3(1, 0, 0);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 1.0;

struct VertexShaderInput
{
    float4 Position : SV_POSITION;
    float4 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : SV_POSITION;
    float4 Color : COLOR0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    float4 normal = mul(input.Normal, WorldInverseTranspose);
    float lightIntensity = dot(normal, DiffuseLightDirection);
    output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);

    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR
{
    return saturate(input.Color + AmbientColor * AmbientIntensity);
}

technique Ambient
{
    pass Pass1
    {
        VertexShader = compile VS_SHADERMODEL VertexShaderFunction();
        PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
    }
}

EDIT: I found this, but it was written for MG 3.2. Unfortunately this link is not helpful, no updated shader code in the repository mostly, I don’t think it could help really.

1 Like