Sal's RuneScape Forum • entries
244
2,657
• views
15,361

# Specular Lighting Formula

It turned out that my specular lighting formula was off, and since I still needed to look further into it, I decided to come up with my own.

So, here's the result:

((L•R)*(C•O))1/S

Now, to add diffuse lighting to that, one must do:

'c = c * ((N•L)+((L•R)*(C•O))1/S)

Where c is a material color, N is the surface normal vector, L is the light vector, C is the eye view vector, O is the vector from the eye to the point, R is O reflected on N and S is the shininess of the material.

Now, after all this mathematical gibberish, here's how it's applied in HLSL:

```float4x4 matWorldViewProj : WORLDVIEWPROJECTION;
float4 pointLights;
float4 cameraPos, cameraLookAt;
int pointLightCount;

struct VS_Out {
float4 position: POSITION;
float4 normal: NORMAL;
float4 color: COLOR0;
};
struct VS_In {
float4 position: POSITION;
float4 normal: NORMAL;
float4 color: COLOR0;
};
struct PS_In {
float4 color: COLOR0;
float4 normal: NORMAL;
float4 pos: TEXCOORD0;
};

void VS( in VS_In In, out VS_Out Out ) {
Out.position = mul(In.position, matWorldViewProj);
Out.pos = In.position;
Out.normal = In.normal;
}

void PS(in PS_In In, out float4 outColor: COLOR0 ) {
float4 N = normalize(In.normal);
float4 L, R, C, O, curLight;
float4 specular, diffuse;
float S = 2;
outColor = 0;
for(int i=0; i<pointLightCount; i++) {
L = normalize(pointLights[i]-In.pos);
C = normalize(cameraLookAt-cameraPos);
O = normalize(In.pos-cameraPos);
R = reflect(O,N);

diffuse = saturate(dot(N,L));
specular = pow(saturate(dot(L,R))*saturate(dot(C,O)),1/S);

outColor += (diffuse+specular);
}
}

technique Gamma
{
pass P0
{
}
}```

So far, it seems to be working really good. I made this all up myself, so I'm really glad that it works. Pictures will come soon. you made it all yourself you made it all yourself Yup, took a lot of time, but I did. :D