I'm pretty sure this is all happening due to my crooked hands...
Here you can see the whole .fx file (can compile):
Code
#include <acknex.h>
#include <default.c>

#define PRAGMA_PATH "%EXE_DIR%\samples";

MATERIAL* mtl_test =
{
	effect = "
	
	float4x4 matWorldViewProj;
	float4x4 matWorld;
	float4 vecViewPos;

	float iLights;
	float4 vecLightPos[8];
	float4 vecLightColor[8];
	float4 vecLightDir[8];

	float4 vecLight;
	float4 vecColor;
	float4 vecAmbient;
	float4 vecEmissive;
	
	float4 vecFog;
	float4 vecFogColor;

	texture entSkin1;

	sampler ColorSampler = sampler_state
	{
		Texture = <entSkin1>;
		Mipfilter = None;
		Minfilter = None;
		Magfilter = None;
	};

	struct vertexOut
	{
		float4 Pos : POSITION;
		float4 Color : COLOR0;
		float3 Normal : NORMAL;
		float4 Tex : TEXCOORD0;
		float4 WorldPos : TEXCOORD1;
	};

	vertexOut VS (
	in float4 inPos : POSITION, 
	in float3 inNormal : NORMAL,
	in float2 inTex1 : TEXCOORD0,
	in float2 inTex2 : TEXCOORD1
	)
	{
		inPos.w = 1.0f;	
		vertexOut Out;
		Out.Pos = mul(inPos, matWorldViewProj);
		Out.Normal = normalize (mul(inNormal, (float3x3)matWorld));
		Out.Tex.xy = inTex1.xy;
		Out.Tex.zw = inTex2.xy;
		Out.WorldPos = mul(inPos, matWorld);
		Out.Color = (vecAmbient * vecLight) + float4(vecEmissive.xyz * vecColor.xyz, vecLight.w);
		
		// multiple dynamic lights
		float light = 0;
		for(light = 0; light < iLights; light += 1.0)
		{
			// light ray
			float3 ray = Out.WorldPos - vecLightPos[light].xyz;
			
			// spotlight factor
			float depth = saturate(dot(vecLightDir[light].xyz, ray) / vecLightPos[light].w);
			float spot = 1.0 - saturate(length(cross(vecLightDir[light].xyz, ray)) / (vecLightPos[light].w * depth));
			
			// normalize the light ray
			float dist = length(ray);
			ray /= dist; 
			
			// attenuation
			float att = 1.0 - saturate(dist / vecLightPos[light].w);
			
			// final light factor
			float strength = vecLightDir[light].w ? spot * att : att;
			
			// diffuse term
			Out.Color.rgb += vecLightColor[light].rgb * saturate(-dot(ray, inNormal.xyz)) * strength;
		}
		
		Out.Color.rgb = saturate(Out.Color.rgb);
		
		return Out;
	}

	float4 PS(vertexOut In) : COLOR0
	{
		float4 textureColor = tex2D(ColorSampler, In.Tex.xy);
		In.Color.rgb *= textureColor.rgb;
		
		float fDepth = distance(vecViewPos.xyz, In.WorldPos.xyz);
		float Fog = saturate((fDepth - vecFog.x) * vecFog.z);
		In.Color.rgb = lerp(In.Color.rgb, vecFogColor, Fog);
		In.Color.a = 1;
		
		return In.Color;
	}

	technique model
	{
		pass one
		{		
			VertexShader = compile vs_3_0 VS(); 
			PixelShader  = compile ps_3_0 PS(); 
		}
	}
	
	";
	flags = PASS_SOLID | ENABLE_VIEW;
}

action act_test()
{
	my->material = mtl_test;
	
	while(my)
	{
		my->pan += 5 * time_step;
		wait(1);
	}
}

action act_pointlight()
{
	set(my, UNLIT | BRIGHT);
	my->ambient = 100;
	vec_fill(&my->scale_x, 0.25);
	my->lightrange = 128;
	vec_set(&my->blue, COLOR_WHITE);
	vec_set(&my->skill1, &my->x);
	
	while(my)
	{
		my->x = my->skill1 + fsin(total_ticks * 7, 64);
		my->y = my->skill2 + fcos(total_ticks * 7, 64);
		wait(1);
	}
}

void main()
{
	warn_level = 6;
	fps_max = 60;
	mouse_pointer = 0;
	
	video_mode = 10;
	
	level_load("");
	wait(3);
	
	camera->arc = 90;
	camera->clip_far = 1024;
	camera->clip_near = 0.1;
	
	camera->fog_start = 512;
	camera->fog_end = 1024;
	
	fog_color = 4;
	vec_set(&d3d_fogcolor4.blue, vector(128, 128, 128));
	vec_set(&sky_color.blue, &d3d_fogcolor4.blue);
	
	vec_set(&camera->x, vector(-56, 18, 38));
	vec_set(&camera->pan, vector(338, -30, 0));
	
	ent_create("blob.mdl", nullvector, act_test);
	ent_create(CUBE_MDL, nullvector, act_pointlight);
}
Also I just noticed, that the sun doesn't illuminate object correctly.. illuminated (by sun) side of an object rotates with it as if the sun was rotating (pan) around it.. and if I copy the whole light calculations into PS everything works fine.

Edit: also, I would like to ask, why do you use float instead of int for the 'for' loop where you cycle through all lights?

Edit2: it seems to work with default.fx DoLight (but damn.. it doesn't have spotlight support)
Code
// calculate the light attenuation factor
float DoLightFactor(float4 Light,float3 Pos)
{
	float fac = 0.f;
	if (Light.w > 0.f) {    
		float LD = length(Light.xyz-Pos)/Light.w;
		if (LD < 1.f)
		{
			fac = saturate(1.f - LD);
		}
	}
	return fac; // get the distance factor
}

float DoLightFactorN(float4 Light,float3 P,float3 N)
{
	float3 D = Light.xyz-P; // ray pointing from the light to the surface
	float NdotL = dot(N, normalize(D));   // angle between surface and light ray
	
	if (NdotL >= 0.f)
	{
		return 2 * NdotL * DoLightFactor(Light,P);
	}
	else
	{
		return 0.f;
	}
}

float4 DoPointLight(float3 P, float3 N, float4 Light, float4 LightColor)
{
	return LightColor * DoLightFactorN(Light,P,N);
}

float4 DoLight(float3 P, float3 N, int i)
{
	return DoPointLight(P, N, vecLightPos[i], float4(vecLightColor[i].x, vecLightColor[i].y, vecLightColor[i].z, 1)); 
}

Last edited by 3run; 03/01/20 21:35.

Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung