ker wrote:
The PolyVox::SurfaceExtractor (marching cubes) definitely puts out normals.
The question is, how do you create your ogre meshes (post code) and how does your shader process them (also post code).
Also it might be practical to show images so we can see what happens.
Hey thanks for the reply,
An image is worth millions of words so here it is:
Image 2 :
.material
Code:
//**************************************************************************************//
// //
// PERPIXEL LIGHTING //
// A + D + S //
// (NO TEXTURING ADDED) //
//**************************************************************************************//
vertex_program Simple_Perpixel_Vert cg
{
source ARNOLD2.cg
default_params
{
param_named_auto lightPosition0 light_position_object_space 0
// param_named_auto lightPosition1 light_position_object_space 1
// param_named_auto lightPosition2 light_position_object_space 2
param_named_auto worldviewproj worldviewproj_matrix
}
entry_point Simple_Perpixel_Vert
profiles vs_1_1 arbvp1
}
fragment_program Simple_PerPixel_Frag cg
{
source ARNOLD2.cg
default_params
{
param_named_auto eyePosition camera_position_object_space
param_named_auto lightDiffuse0 light_diffuse_colour 0
// param_named_auto lightDiffuse1 light_diffuse_colour 1
// param_named_auto lightDiffuse2 light_diffuse_colour 2
param_named_auto lightSpecular0 light_specular_colour 0
// param_named_auto lightSpecular1 light_specular_colour 1
// param_named_auto lightSpecular2 light_specular_colour 2
param_named exponent0 float 127
// param_named exponent1 float 127
// param_named exponent2 float 127
//If changed, needs adjusting in Fragshader's every lit!!!!!
param_named ambient float4 0.0 0.0 0.0 1.0
}
entry_point Simple_PerPixel_Frag
profiles ps_2_0 arbfp1
}
vertex_program PerPixel_Vert cg
{
source ARNOLD2.cg
default_params
{
param_named_auto lightPosition light_position_object_space 0
param_named_auto eyePosition camera_position_object_space
param_named_auto worldviewproj worldviewproj_matrix
}
entry_point PerPixel_Vert
profiles vs_1_1 arbvp1
}
fragment_program PerPixel_Frag cg
{
source ARNOLD2.cg
default_params
{
param_named_auto lightDiffuse light_diffuse_colour 0
param_named_auto lightSpecular light_specular_colour 0
param_named exponent float 127
}
entry_point PerPixel_Frag
profiles ps_2_0 arbfp1
}
vertex_program PerPixel_Lim3_Vert cg
{
source ARNOLD2.cg
default_params
{
param_named_auto lightPosition0 light_position_object_space 0
param_named_auto lightPosition1 light_position_object_space 1
param_named_auto lightPosition2 light_position_object_space 2
param_named_auto eyePosition camera_position_object_space
param_named_auto worldviewproj worldviewproj_matrix
}
entry_point PerPixel_Lim3_Vert
profiles vs_1_1 arbvp1
}
fragment_program PerPixel_Lim3_Frag cg
{
source ARNOLD2.cg
default_params
{
param_named_auto lightDiffuse0 light_diffuse_colour 0
param_named_auto lightDiffuse1 light_diffuse_colour 1
param_named_auto lightDiffuse2 light_diffuse_colour 2
param_named_auto lightSpecular0 light_specular_colour 0
param_named_auto lightSpecular1 light_specular_colour 1
param_named_auto lightSpecular2 light_specular_colour 2
param_named exponent0 float 127
// param_named exponent1 float 127
// param_named exponent2 float 127
//If changed, needs adjusting in Fragshader's every lit!!!!!
param_named ambient float4 0.0 0.0 0.0 1.0
}
entry_point PerPixel_Lim3_Frag
profiles ps_2_0 arbfp1
}
vertex_program StdPhong_vp cg
{
source ARNOLD2.cg
entry_point StdPhong_vp
profiles vs_1_1 arbvp1
default_params
{
param_named_auto EyePos camera_position_object_space
param_named_auto worldviewproj worldviewproj_matrix
param_named_auto LightPos light_position_object_space 0
param_named_auto UvTranslate texture_matrix 0
}
}
fragment_program StdPhong_fp cg
{
source ARNOLD2.cg
entry_point StdPhong_fp
profiles ps_2_0 arbfp1
default_params
{
param_named_auto LightData light_attenuation 0
param_named_auto LightDiffuse light_diffuse_colour 0
param_named exponent float 10
param_named parallax float 0.04
}
}
material Simple_Perpixel
{
technique
{
// Base ambient pass
pass
{
vertex_program_ref Ambient
{
}
}
pass
{
// do this for each light
iteration once_per_light
scene_blend add
vertex_program_ref Simple_Perpixel_Vert
{
}
fragment_program_ref Simple_PerPixel_Frag
{
}
}
}
}
material Perpixel
{
technique
{
// Base ambient pass
pass
{
vertex_program_ref Ambient
{
}
}
pass
{
// do this for each light
iteration once_per_light
scene_blend add
vertex_program_ref PerPixel_Vert
{
}
fragment_program_ref PerPixel_Frag
{
}
}
pass
{
iteration once_per_light
scene_blend add
vertex_program_ref StdPhong_vp
{
}
fragment_program_ref StdPhong_fp
{
}
}
}
}
//The limitation worth us ~20..100 FPS.It worth it.
material Perpixel_Limited_3
{
technique
{
pass
{
vertex_program_ref PerPixel_Lim3_Vert
{
}
fragment_program_ref PerPixel_Lim3_Frag
{
}
}
}
}
.cg
Code:
//**************************************************************************************//
// //
// PERPIXEL LIGHTING //
// A + D + S //
// //
//**************************************************************************************//
void Simple_Perpixel_Vert(
float4 position : POSITION,
float3 normal : NORMAL,
uniform float4 lightPosition0,
// uniform float4 lightPosition1,
// uniform float4 lightPosition2,
uniform float4x4 worldviewproj,
// uniform float3 eyePosition,
out float4 oClipPos : POSITION,
out float3 oNorm : TEXCOORD0,
out float4 oLightPos0 : TEXCOORD1,
// out float4 oLightPos1 : TEXCOORD2,
// out float4 oLightPos2 : TEXCOORD3,
out float4 oPos : TEXCOORD4,
out float3 EyeDir : TEXCOORD5
)
{
oClipPos = mul(worldviewproj, position);
oLightPos0 = lightPosition0;
// oLightPos1 = lightPosition1;
// oLightPos2 = lightPosition2;
oPos = position;
oNorm = normal;
}
void Simple_PerPixel_Frag(
float3 normal : TEXCOORD0,
float4 LightPos0 : TEXCOORD1,
// float4 LightPos1 : TEXCOORD2,
// float4 LightPos2 : TEXCOORD3,
float4 position : TEXCOORD4,
uniform float3 eyePosition,
uniform float4 lightDiffuse0,
// uniform float4 lightDiffuse1,
// uniform float4 lightDiffuse2,
uniform float4 lightSpecular0,
// uniform float4 lightSpecular1,
// uniform float4 lightSpecular2,
uniform float exponent0,
// uniform float exponent1,
// uniform float exponent2,
uniform float4 ambient,
out float4 oColor : COLOR
)
{
//could I do this, or whole halfangle calculus in vertex shader?
float3 N = normalize(normal);
float3 EyeDir = normalize(eyePosition - position.xyz);
float3 LightDir = normalize(LightPos0.xyz - (position * LightPos0.w));
float3 HalfAngle = normalize(LightDir + EyeDir);
float NdotL = dot(LightDir, N);
float NdotH = dot(HalfAngle, N);
float4 Lit = lit(NdotL,NdotH,exponent0);
oColor = lightDiffuse0 * Lit.y + lightSpecular0 * Lit.z + ambient;
// LightDir = normalize(LightPos1.xyz - (position * LightPos1.w));
// HalfAngle = normalize(LightDir + EyeDir);
// NdotL = dot(LightDir, N);
// NdotH = dot(HalfAngle, N);
// Lit = lit(NdotL,NdotH,exponent0);
// oColor += lightDiffuse1 * Lit.y + lightSpecular1 * Lit.z;
// LightDir = normalize(LightPos2.xyz - (position * LightPos2.w));
// HalfAngle = normalize(LightDir + EyeDir);
// NdotL = dot(LightDir, N);
// NdotH = dot(HalfAngle, N);
// Lit = lit(NdotL,NdotH,exponent0);
// oColor += lightDiffuse2 * Lit.y + lightSpecular2 * Lit.z + ambient;
//do I need to normalize here the normal?
}
void PerPixel_Vert ( float4 position : POSITION,
float3 normal : NORMAL,
uniform float4 lightPosition,
uniform float3 eyePosition,
uniform float4x4 worldviewproj,
out float4 oPos : POSITION,
out float3 oNorm: TEXCOORD0,
out float3 oLightDir: TEXCOORD1,
out float3 oHalfAngle: TEXCOORD2
)
{
oPos = mul(worldviewproj, position);
float3 EyeDir = normalize(eyePosition - position.xyz);
oLightDir = normalize(lightPosition.xyz - (position.xyz * lightPosition.w));
oHalfAngle = normalize(oLightDir + EyeDir);
oNorm = normal;
//what if I leave normalization of normal, and oHalfAngle to Fragshader?
}
void PerPixel_Frag ( float3 normal: TEXCOORD0,
float3 LightDir : TEXCOORD1,
float3 HalfAngle : TEXCOORD2,
uniform float4 lightDiffuse,
uniform float4 lightSpecular,
uniform float exponent,
out float4 oColor : COLOR
)
{
float3 N = normalize(normal);
float NdotL = dot(normalize(LightDir), N);
float NdotH = dot(normalize(HalfAngle), N);
float4 Lit = lit(NdotL,NdotH,exponent);
oColor = lightDiffuse * Lit.y + lightSpecular * Lit.z;
//do I need to normalize here the normal?
// oColor = float4(normal,1);
}
void PerPixel_Lim3_Vert(float4 position : POSITION,
float3 normal : NORMAL,
uniform float4 lightPosition0,
uniform float4 lightPosition1,
uniform float4 lightPosition2,
uniform float3 eyePosition,
uniform float4x4 worldviewproj,
out float4 oPos : POSITION,
out float3 oNorm: TEXCOORD0,
out float3 oLightDir0: TEXCOORD1,
out float3 oLightDir1: TEXCOORD2,
out float3 oLightDir2: TEXCOORD3,
out float3 oHalfAngle0: TEXCOORD4,
out float3 oHalfAngle1: TEXCOORD5,
out float3 oHalfAngle2: TEXCOORD6
)
{
oPos = mul(worldviewproj, position);
oLightDir0 = normalize(lightPosition0.xyz - (position * lightPosition0.w));
oLightDir1 = normalize(lightPosition1.xyz - (position * lightPosition1.w));
oLightDir2 = normalize(lightPosition2.xyz - (position * lightPosition2.w));
float3 EyeDir = normalize(eyePosition - position.xyz);
oHalfAngle0 = normalize(oLightDir0 + EyeDir);
oHalfAngle1 = normalize(oLightDir1 + EyeDir);
oHalfAngle2 = normalize(oLightDir2 + EyeDir);
oNorm = normal;
//what if I leave normalization of normal and oHalfAngle to Fragshader?
}
void PerPixel_Lim3_Frag(float3 normal: TEXCOORD0,
float3 LightDir0 : TEXCOORD1,
float3 LightDir1 : TEXCOORD2,
float3 LightDir2 : TEXCOORD3,
float3 HalfAngle0: TEXCOORD4,
float3 HalfAngle1: TEXCOORD5,
float3 HalfAngle2: TEXCOORD6,
uniform float4 lightDiffuse0,
uniform float4 lightDiffuse1,
uniform float4 lightDiffuse2,
uniform float4 lightSpecular0,
uniform float4 lightSpecular1,
uniform float4 lightSpecular2,
uniform float exponent0,
// uniform float exponent1,
// uniform float exponent2,
uniform float4 ambient,
out float4 oColor : COLOR
)
{
float3 N = normalize(normal);
float NdotL = dot(normalize(LightDir0), N);
float NdotH = dot(normalize(HalfAngle0), N);
float4 Lit = lit(NdotL,NdotH,exponent0);
oColor = lightDiffuse0 * Lit.y + lightSpecular0 * Lit.z;
NdotL = dot(normalize(LightDir1), N);
NdotH = dot(normalize(HalfAngle1), N);
Lit = lit(NdotL,NdotH,exponent0);
oColor += lightDiffuse1 * Lit.y + lightSpecular1 * Lit.z;
NdotL = dot(normalize(LightDir2), N);
NdotH = dot(normalize(HalfAngle2), N);
Lit = lit(NdotL,NdotH,exponent0);
oColor += lightDiffuse2 * Lit.y + lightSpecular2 * Lit.z + ambient;
//do I need to normalize here the normal?
}
float2 getParallaxUV(sampler2D N, float3 E, float2 uv, float parallax)
{
float B = tex2D(N, uv).a * parallax - parallax/2.0;
float Bnew = tex2D(N, uv + E.xy * B).a * parallax - parallax/2.0;
return uv + E.xy / (E.z/2 + 0.5) * (B+Bnew)/2;
}
float getPointAttenuation(float4 LightData, float lightDistance)
{
return saturate(1-lightDistance/LightData.r) /
(LightData.g + // Constant
LightData.b*lightDistance + // Linear
LightData.a*lightDistance*lightDistance); // Quadradic
}
float4 getLambertComponent(float3 L, float3 N, float4 LightDiffuse)
{
return max(0, dot(L, N)) * LightDiffuse;
}
float4 getSpecularComponent(float3 L, float3 N, float3 E, float exponent)
{
float3 R = -normalize(reflect(L, N));
return pow(max(0, dot(R, E)), exponent);
}
float4 StdPhong_fp(
sampler2D D : register(s0),
sampler2D S : register(s1),
sampler2D Nm : register(s2),
uniform float4 LightData,
uniform float4 LightDiffuse,
uniform float lightDistance,
uniform float exponent,
uniform float parallax,
float2 uv : TEXCOORD0,
float3 lightdir : TEXCOORD2,
float3 eyedir : TEXCOORD3,
float3 normal : TEXCOORD4
) : COLOR
{
lightDistance = length(lightdir);
float3 L = normalize(lightdir);
float3 E = normalize(eyedir);
float2 pUV = getParallaxUV(Nm, E, uv, parallax);
float3 N = (tex2D(Nm, pUV) * 2 - 1);
float4 diffuse = getLambertComponent(L, N, LightDiffuse) * tex2D(D, pUV);
float4 specular = getSpecularComponent(L, N, E, exponent) * tex2D(S, pUV);
return (diffuse + specular) * getPointAttenuation(LightData, lightDistance);
}
float3x3 getTangentSpace(float3 tangent, float3 normal)
{
float3 T = normalize(tangent);
float3 N = normalize(normal);
float3 B = normalize(cross(T, N));
return float3x3(T, B, N);
}
void StdPhong_vp(
float2 uv : TEXCOORD0,
float4 position : POSITION,
float3 normal : NORMAL,
float3 tangent : TANGENT,
uniform float3 EyePos,
uniform float4 LightPos,
uniform float4x4 worldviewproj,
uniform float4x4 UvTranslate,
out float4 oClipPos : POSITION,
out float2 oUv : TEXCOORD0,
out float3 oObjPos : TEXCOORD1,
out float3 oLightDir : TEXCOORD2,
out float3 oEyeDir : TEXCOORD3,
out float3 oNormal : TEXCOORD4
)
{
oUv = mul(UvTranslate, float4(uv,0,1)).xy;
oClipPos = mul(worldviewproj, position);
oObjPos = position.xyz;
oNormal = normal;
float3x3 rotation = getTangentSpace(tangent, normal);
oEyeDir = mul(rotation, (EyePos - position.xyz));
oLightDir = mul(rotation, (LightPos.xyz - position.xyz));
}
And yes I'm using the marching cubes, btw directional lighting works perfect with the per pixel shader, however point light and spotlight propagate the light in a blocky form as seen in the screenshot.
PS: When I move my camera away from the point light, the lighting simply disappears, by lighting I mean the light propagation of the point light.