3 registered members (NewbieZorro, TipmyPip, 1 invisible),
19,045
guests, and 8
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
"Lighting" Shader
#117213
03/13/07 17:15
03/13/07 17:15
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
here i have a normal specular shader (from the intro to shader programming), which i am trying to convert to use world lights and dynamic lights rather than the sun, i'll post the original and the modified: the original: Code:
/*********************************************************************************************** / Copyright 2006 by Taco Cohen. All rights reserved /***********************************************************************************************/
/*********************************************************************************************** / Global Variables: /***********************************************************************************************/ // Tweakables: static const float AmbientIntensity = 1.0f; // The intensity of the ambient light. static const float DiffuseIntensity = 1.0f; // The intensity of the diffuse light. static const float SpecularIntensity = 1.0f; // The intensity of the specular light. static const float SpecularPower = 0.3f; // The specular power. Used as 'glossyness' factor. static const float4 SunColor = {0.3f, 0.3f, 0.3f, 0.3f}; // Color vector of the sunlight.
// Application fed data: const float4x4 matWorldViewProj; // World*view*projection matrix. const float4x4 matWorld; // World matrix. const float4 vecAmbient; // Ambient color. const float4 vecSunDir; // The sun direction vector. const float4 vecViewPos; // View position.
texture entSkin1; // Color map. sampler ColorMapSampler = sampler_state // Color map sampler. { Texture = <entSkin1>; AddressU = Clamp; AddressV = Clamp; };
/*********************************************************************************************** / Vertex Shader: /***********************************************************************************************/ void SpecularVS(in float4 InPos : POSITION, in float3 InNormal : NORMAL, in float2 InTex : TEXCOORD0, out float4 OutPos : POSITION, out float2 OutTex : TEXCOORD0, out float3 OutNormal: TEXCOORD1, out float3 OutViewDir: TEXCOORD2) { // Transform the vertex from object space to clip space: OutPos = mul(InPos, matWorldViewProj); // Transform the normal from object space to world space: OutNormal = normalize(mul(InNormal,matWorld)); // Calculate a vector from the vertex to the view: OutViewDir = vecViewPos - mul(InPos, matWorld); // Pass the texture coordinate to the pixel shader: OutTex = InTex; }
/*********************************************************************************************** / Pixel Shader: /***********************************************************************************************/ float4 SpecularPS( in float2 InTex : TEXCOORD0, in float3 InNormal : TEXCOORD1, in float4 InViewDir : TEXCOORD2) : COLOR { // Calculate the ambient term: float4 Ambient = AmbientIntensity * vecAmbient; // Calculate the diffuse term: InNormal = normalize(InNormal); float4 Diffuse = DiffuseIntensity * saturate(dot(vecSunDir, InNormal)); Diffuse *= SunColor; // Fetch the pixel color from the color map: float4 Color = tex2D(ColorMapSampler, InTex); // Calculate the reflection vector: float3 R = normalize(2 * dot(InNormal, vecSunDir) * InNormal - vecSunDir); // Calculate the speculate component: InViewDir = normalize(InViewDir); float Specular = pow(saturate(dot(R, InViewDir)), SpecularPower) * SpecularIntensity; // Calculate final color: return (Ambient + Diffuse + Specular) * Color; }
/*********************************************************************************************** / Technique: /***********************************************************************************************/ technique SpecularTechnique { pass P0 { VertexShader = compile vs_2_0 SpecularVS(); PixelShader = compile ps_2_0 SpecularPS(); } }
and my modified version, which isn't modified much yet: Code:
/*********************************************************************************************** / Global Variables: /***********************************************************************************************/ // Tweakables: static const float SpecularIntensity = 1.0f; // The intensity of the specular light. static const float SpecularPower = 0.3f; // The specular power. Used as 'glossyness' factor. //static const float4 SunColor = {0.3f, 0.3f, 0.3f, 0.3f}; // Color vector of the sunlight.
// Application fed data: const float4x4 matWorldViewProj; // World view projection matrix. const float4x4 matWorld; // World matrix. const float4 vecAmbient; // Ambient color. const float4 vecLightPos; // The sun direction vector.
texture entSkin1; // Color map. sampler ColorMapSampler = sampler_state // Color map sampler. { Texture = <entSkin1>; AddressU = Clamp; AddressV = Clamp; };
void SpecularVS(in float4 InPos : POSITION, in float3 InNormal : NORMAL, in float2 InTex : TEXCOORD0, out float4 OutPos : POSITION, out float2 OutTex : TEXCOORD0, out float3 OutNormal: TEXCOORD1, out float3 OutViewDir: TEXCOORD2) { // Transform the vertex from object space to clip space: OutPos = mul(InPos, matWorldViewProj); // Transform the normal from object space to world space: OutNormal = normalize(mul(InNormal,matWorld)); // Calculate a vector from the vertex to the view: OutViewDir = mul(InPos, matWorld); // Pass the texture coordinate to the pixel shader: OutTex = InTex; }
/*********************************************************************************************** / Pixel Shader: /***********************************************************************************************/ float4 SpecularPS( in float2 InTex : TEXCOORD0, in float3 InNormal : TEXCOORD1, in float4 InViewDir : TEXCOORD2) : COLOR { // Calculate the ambient term: float4 Ambient = vecAmbient; // Calculate the diffuse term: InNormal = normalize(InNormal); float4 Diffuse = saturate(dot(vecLightPos, InNormal)); // Fetch the pixel color from the color map: float4 Color = tex2D(ColorMapSampler, InTex); // Calculate the reflection vector: float3 R = normalize(2 * dot(InNormal, vecLightPos) * InNormal - vecLightPos); // Calculate the speculate component: InViewDir = normalize(InViewDir); float Specular = pow(saturate(dot(R, InViewDir)), SpecularPower) * SpecularIntensity; // Calculate final color: return (Ambient + Diffuse + Specular) * Color; }
/*********************************************************************************************** / Technique: /***********************************************************************************************/ technique SpecularTechnique { pass P0 { VertexShader = compile vs_2_0 SpecularVS(); PixelShader = compile ps_2_0 SpecularPS(); } }
i want it to calculate with regular lights and dynamic rather than the sun as mentioned before, how can i get vecLightPos to calculate the light's position properly?
Last edited by Manslayer101; 03/13/07 19:23.
- aka Manslayer101
|
|
|
Re: Converting a "specular" shader
[Re: lostclimate]
#117215
03/13/07 18:25
03/13/07 18:25
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
i've got somewhat of a nice shader running, take a look and try it in a level, i'm going to play with the intesity and stuff to get it just right and it'll be great: Code:
/*
Code Created by Taco Cohen, and modified my Manga Page
*/
/*********************************************************************************************** / Global Variables: /***********************************************************************************************/ // Tweakables: float4 SpecularIntensity = {2.0f, 2.0f, 2.0f, 2.0f}; // The intensity of the specular light. float SpecularPower = 0.5f; // The specular power. Used as 'glossyness' factor. //static const float4 SunColor = {0.3f, 0.3f, 0.3f, 0.3f}; // Color vector of the sunlight.
// Application fed data: float4x4 matWorldViewProj; // World view projection matrix. float4x4 matWorld; // World matrix. float4x4 matWorldInv; float4 vecAmbient; // Ambient color. float4 vecLightPos; float4 vecLight; float vecLightColor;
texture entSkin1; // Color map. sampler ColorMapSampler = sampler_state // Color map sampler. { Texture = <entSkin1>; AddressU = Clamp; AddressV = Clamp; };
void SpecularVS(in float4 InPos : POSITION, in float3 InNormal : NORMAL, in float2 InTex : TEXCOORD0, out float4 OutPos : POSITION, out float2 OutTex : TEXCOORD0, out float3 OutNormal: TEXCOORD1, out float3 OutViewDir: TEXCOORD2) { // Transform the vertex from object space to clip space: OutPos = mul(InPos, matWorldViewProj); // Transform the normal from object space to world space: OutNormal = normalize(mul(InNormal,matWorldInv)); // Calculate a vector from the vertex to the view: OutViewDir = mul(vecLightPos, matWorld); // Pass the texture coordinate to the pixel shader: OutTex = InTex; }
/*********************************************************************************************** / Pixel Shader: /***********************************************************************************************/ float4 SpecularPS( in float2 InTex : TEXCOORD0, in float3 InNormal : TEXCOORD1, in float4 InViewDir : TEXCOORD2) : COLOR { //SpecularIntensity += vecLightColor; InNormal = normalize(InNormal); // Calculate the ambient term: float4 Ambient = vecLight; // Calculate the diffuse term: float4 Diffuse = saturate(dot(vecLightColor, InNormal)); // Fetch the pixel color from the color map: //float4 Color = tex2D(ColorMapSampler, InTex); float4 Color = tex2D(ColorMapSampler, InTex); // Calculate the reflection vector: float3 R = normalize(2 * dot(InNormal, vecLightColor + SpecularIntensity) * InNormal - SpecularIntensity); // Calculate the speculate component: //InViewDir = normalize(vecLight); InViewDir = vecLightColor + SpecularIntensity *vecLight; //float Specular = pow(saturate(dot(R, InViewDir)), SpecularPower) * SpecularIntensity; float Specular = saturate(dot(R, InViewDir)); // Calculate final color: return (Ambient + Diffuse + Specular) * Color; }
/*********************************************************************************************** / Technique: /***********************************************************************************************/ technique SpecularTechnique { pass P0 { VertexShader = compile vs_2_0 SpecularVS(); PixelShader = compile ps_2_0 SpecularPS(); } }
note that i have no shader knowlede, if someone can help me perfect this you're welcome to edit: code updated
Last edited by Manslayer101; 03/13/07 19:23.
- aka Manslayer101
|
|
|
Re: Converting a "specular" shader
[Re: mpdeveloper_B]
#117216
03/13/07 19:31
03/13/07 19:31
|
Joined: Jan 2004
Posts: 2,013 The Netherlands
Excessus
Expert
|
Expert
Joined: Jan 2004
Posts: 2,013
The Netherlands
|
To use point lights instead of the sun, use the vecLightPos effect variable (see manual for more details). I don't think it is possible to use static lights in a shader.
Just looking at the shader you posted, I can see you changed: OutViewDir = vecViewPos - mul(InPos, matWorld); to OutViewDir = mul(InPos, matWorld);
That's bad! Even if it doesn't look wrong right away, you must not change things without knowing what you are doing. Experimenting is good, but don't leave the changes in if you don't see a difference. In this case the calculation just doesn't make sense anymore. It's probably a good idea to read the section on vectors & matrices and read more about it online aswell.
BTW, I don't know why I put that big fat copyright notice there, but you're free to use that shader in any way you like.
|
|
|
Re: Converting a "specular" shader
[Re: Excessus]
#117217
03/13/07 20:16
03/13/07 20:16
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
thank you excessus, and i didn't know that, i'll change it back, however, can you tell me how to get the specular to come from the light rather than relative to the world and view
- aka Manslayer101
|
|
|
Re: Converting a "specular" shader
[Re: mpdeveloper_B]
#117218
03/13/07 23:55
03/13/07 23:55
|
Joined: Mar 2006
Posts: 2,503 SC, United States
xXxGuitar511
Expert
|
Expert
Joined: Mar 2006
Posts: 2,503
SC, United States
|
HLSL's still a lil confusing for me... The hardest thing is converting bewtween coordinates. Light positions are sent to the shader using world positions, and so are the verticies [using world positioning]. But you have to use the dot() product of the surface normal to get lighting direction. However, the normal isn't so easy to get, as I believe you have to combine the surface "normal and tangent to create a binormal". Matt should know more about this than I though 
xXxGuitar511 - Programmer
|
|
|
Re: Converting a "specular" shader
[Re: xXxGuitar511]
#117219
03/14/07 01:29
03/14/07 01:29
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
well then, the shader is sufficient for what i want to do with it in PreVa, so i'm ok with it, i may also contribute it (because i've changed it slightly)
edit: this works for both dynamic and static lights btw, i tested it on static and found out it worked with dynamic as well, which makes it better than the engine's default in my opinion. we may be posting a video of this with our models, the shader can be changed a bit to make good toon lighting as well
Last edited by Manslayer101; 03/14/07 01:31.
- aka Manslayer101
|
|
|
Re: Converting a "specular" shader
[Re: mpdeveloper_B]
#117220
03/14/07 02:30
03/14/07 02:30
|
Joined: Mar 2006
Posts: 2,503 SC, United States
xXxGuitar511
Expert
|
Expert
Joined: Mar 2006
Posts: 2,503
SC, United States
|
Static lights? are you sure?...
Static lighting positions/lightmaps are NOT passed to shaders. However, using c-script, and a few models, you could pass the positions of models to a shader using its skills, and place those models where the static lights are to "fake" static lighting...
xXxGuitar511 - Programmer
|
|
|
Re: Converting a "specular" shader
[Re: xXxGuitar511]
#117221
03/14/07 14:16
03/14/07 14:16
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
try it, attach that shader to a model using a material, put a model in a level and try static lighting on it, we'll probably be posting a video of it working in PreVa soon
- aka Manslayer101
|
|
|
Re: Converting a "specular" shader
[Re: mpdeveloper_B]
#117222
03/14/07 16:15
03/14/07 16:15
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
Oops i posted the wrong code, i'll post the correct one tomorrow
Last edited by Manslayer101; 03/14/07 17:43.
- aka Manslayer101
|
|
|
|