Gamestudio Links
Zorro Links
Newest Posts
Blobsculptor tools and objects download here
by NeoDumont. 03/28/24 03:01
Issue with Multi-Core WFO Training
by aliswee. 03/24/24 20:20
Why Zorro supports up to 72 cores?
by Edgar_Herrera. 03/23/24 21:41
Zorro Trader GPT
by TipmyPip. 03/06/24 09:27
VSCode instead of SED
by 3run. 03/01/24 19:06
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
5 registered members (Quad, TipmyPip, degenerate_762, AndrewAMD, Nymphodora), 997 guests, and 5 spiders.
Key: Admin, Global Mod, Mod
Newest Members
sakolin, rajesh7827, juergen_wue, NITRO_FOREVER, jack0roses
19043 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 2 of 2 1 2
Re: vecLightViewPos question [Re: txesmi] #480023
05/13/20 18:52
05/13/20 18:52
Joined: May 2009
Posts: 5,370
Caucasus
3run Offline OP
Senior Expert
3run  Offline OP
Senior Expert

Joined: May 2009
Posts: 5,370
Caucasus
Originally Posted by txesmi
I am pretty absent-minded today.
I'm absent-minded always grin No inconvenience at all! Thank you for helping out, without you forum is completely dead (especially when it comes to shaders).

Last edited by 3run; 05/13/20 19:54.

Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung
Re: vecLightViewPos question [Re: 3run] #480025
05/13/20 19:54
05/13/20 19:54
Joined: May 2009
Posts: 5,370
Caucasus
3run Offline OP
Senior Expert
3run  Offline OP
Senior Expert

Joined: May 2009
Posts: 5,370
Caucasus
Ok, so after googling I found this awesome answer on stackoverflow
C++/OpenGL convert world coords to screen(2D) coords

It explains that you need to:
Quote
- transform into clip-space
- then transform from clip-space to normalized device coordinate space (NDC space)
- and then transform from this [-1, 1] (NDC) space to window-relative coordinates!

And from there I've got this code
Code
vec4 clipSpacePos = projectionMatrix * (viewMatrix * vec4(point3D, 1.0));
vec3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;
vec2 windowSpacePos = ((ndcSpacePos.xy + 1.0) / 2.0) * viewSize + viewOffset; // OpenGL bottom-left of the window
vec2 windowSpacePos = vec2(((ndcSpacePos.x + 1.0) / 2.0) * viewSize.x + viewOffset.x, ((1.0 - ndcSpacePos.y) / 2.0) * viewSize.y + viewOffset.y); // top-left
Which I've later on converted into hlsl
Code
float4 clipSpacePos = mul(float4(vecLightPos[i].xyz, 1.0f), matViewProj);
float3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;
float2 windowSpacePos = float2(((ndcSpacePos.x + 1.0) / 2.0) * vecViewPort.x, ((1.0 - ndcSpacePos.y) / 2.0) * vecViewPort.y);
And at the end it worked like a charm!
[Linked Image]


Thank you all for replies! Next step is getting fog of war/lights working! grin

Last edited by 3run; 05/13/20 21:26.

Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung
Re: vecLightViewPos question [Re: 3run] #480026
05/13/20 21:26
05/13/20 21:26
Joined: May 2009
Posts: 5,370
Caucasus
3run Offline OP
Senior Expert
3run  Offline OP
Senior Expert

Joined: May 2009
Posts: 5,370
Caucasus
So this is how I got it working so far (in motion it 'flickers')
[Linked Image]

.fx file (if anyone needs it):
Code
//source
//https://www.shadertoy.com/view/ttj3zd

float4x4 matViewProj;
const float4 vecTime;
const float4 vecViewPort;

float lightRangeFactor = 1.0;
float smoothObjectPadding = 0.33;
float lightSaturationFactor = 0.2;
float flickerSpeedFactor = 2;

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

texture TargetMap;

sampler postTex = sampler_state
{
	texture = <TargetMap>;
	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;  
	AddressU = Clamp;
	AddressV = Clamp;
};

float4 FP(float2 fragCoord: VPOS) : COLOR
{
	float2 uv = fragCoord.xy / vecViewPort.xy;
	float3 color = tex2D(postTex, uv).rgb;
	float3 blurColor = float3(0.0, 0.0, 0.0);
	
	float aspectRatio = vecViewPort.x / vecViewPort.y;
	
	float i = 0;
	for(i = 0; i < iLights; i += 1.0)
	{
		// pointlights only
		if(vecLightDir[i].x <= 0 && vecLightDir[i].y <= 0 && vecLightDir[i].z <= 0)
		{
			float4 clipSpacePos = mul(float4(vecLightPos[i].xyz, 1.0f), matViewProj);
			float3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;
			float2 windowSpacePos = float2(((ndcSpacePos.x + 1.0) / 2.0) * vecViewPort.x, ((1.0 - ndcSpacePos.y) / 2.0) * vecViewPort.y);
			
			float2 objectCenter = windowSpacePos.xy / vecViewPort.xy;
			
			float2 v = uv - objectCenter;
			v.x = v.x * aspectRatio;
			float flickerTime = sin(vecTime.w * flickerSpeedFactor);
			
			float min_size = (vecLightPos[i].w * lightRangeFactor / 2.0) / 100;
			float max_size = (vecLightPos[i].w * lightRangeFactor / 2.1) / 100;
			float size = lerp(min_size, max_size, flickerTime);
			
			float smoothSize = size * smoothObjectPadding;
			float circleMix = smoothstep(size, size - smoothSize, length(v));
			
			blurColor.rgb = lerp(blurColor.rgb, color.rgb + (vecLightColor[i].xyz * lightSaturationFactor), circleMix);
		}
	}
	
	float4 fragColor = float4(blurColor, 1.0);
	return fragColor;
}

technique
{
	pass one
	{
		PixelShader = compile ps_3_0 FP();
	}
}


The only thing left is, to change lightrange depending on the distance to the light source. If you guys have any ideas, please let me know.
Couldn't get this one to work properly...
Code
float2 normalizedProjectionCoordinatesXY = mul(float4(vecLightViewPos[i].xyz, 1.0f), matProj).xy;
float normalizedProjectionCoordinatesOfOuterPointOfLightSphereX = mul(float4(vecLightViewPos[i].xy, vecLightViewPos[i].z - vecLightViewPos[i].w, 1.0f), matProj).x ; // doing the same in world space would need far more computations
float projectedLightRadiusInScreenPixels = vecViewPort.x * (normalizedProjectionCoordinatesOfOuterPointOfLightSphereX - normalizedProjectionCoordinatesXY.x) / 2.0f;


Best regards!

Last edited by 3run; 05/13/20 21:53.

Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung
Re: vecLightViewPos question [Re: 3run] #480030
05/14/20 13:26
05/14/20 13:26
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Originally Posted by 3run
- transform into clip-space
- then transform from clip-space to normalized device coordinate space (NDC space)
- and then transform from this [-1, 1] (NDC) space to window-relative coordinates!

The very same I said wink

Originally Posted by 3run
does vecLightViewPos[i].w contain lightrange?


I thought yes but no and it should frown
I can only name it a bug because it is forcing to include full world space light vectors to get the light ranges while the W component of vecLightViewPos is empty. brff...

Here goes an example of the concepts I tryed to explain but with no bugs grin
Code
#include <acknex.h>
#include <default.c>

MATERIAL *mtlProjectedLights =
{
	effect = "
		float4x4 matProj;
		const float4 vecViewPort;
		
		float iLights;
		float4 vecLightPos[8];
		float4 vecLightViewPos[8];
		float4 vecLightDir[8];
		float4 vecLightColor[8];
		
		texture TargetMap;
		
		sampler postTex = sampler_state
		{
			Texture = <TargetMap>;
			MinFilter = Point; // No need of linear interpolation on pixel to pixel pp effects. 
		};
		
		float4 PS (
			in float2 inTex : TEXCOORD0, 
			in float2 inPos : VPOS) : COLOR0
		{
			float4 color0 = float4(0, 0, 0, 1.0f);
			
			for(float i = 0; i < iLights; i += 1.0f)
			{
				if(vecLightDir[i].w > 0) // Avoid spotlights
					continue;
				
				float4 clipSpacePos = mul(float4(vecLightViewPos[i].xyz, 1.0f), matProj);
				float2 ndcSpacePos = clipSpacePos.xy / clipSpacePos.w;
				float2 windowSpacePos = float2(1.0f + ndcSpacePos.x, 1.0f - ndcSpacePos.y) * vecViewPort.xy * 0.5f;
				
				float4 clipSpaceOutterPoint = mul(float4(vecLightViewPos[i].x - vecLightPos[i].w, vecLightViewPos[i].yz, 1.0f), matProj);
				float ndcSpaceOutterPoint = clipSpaceOutterPoint.x / clipSpaceOutterPoint.w;
				
				float windowSpaceRadius = (ndcSpacePos.x - ndcSpaceOutterPoint) * vecViewPort.x * 0.5f;
				color0.rgb += vecLightColor[i].rgb * saturate((1.0f - length(inPos - windowSpacePos) / windowSpaceRadius));
			}
			
			float3 albedo = tex2D(postTex, inTex).rgb;
			color0.rgb = albedo * saturate(color0.rgb);
			
			return color0;
		}
		
		technique
		{
			pass one
			{
				ZWriteEnable = False;
				AlphaBlendEnable = False;
				PixelShader = compile ps_3_0 PS();
			}
		}	
	";
}

VIEW *camProjectedLights =
{
	material = mtlProjectedLights;
	flags = PROCESS_TARGET | CHILD | SHOW;
}

void main () {
	video_mode = 10;
	sun_light = 0;
	wait(3);
	level_load("level.wmb");
	camera->arc = 100;
	camera->stage = camProjectedLights;
	
	while(!key_esc)
		wait(1);
	
	sys_exit(NULL);
}

#define light_blue skill1
#define light_green skill2
#define light_red skill3
#define light_range skill4
//uses: light_blue, light_green, light_red, light_range
action actLight () {
	my->blue = my->light_blue;
	my->green = my->light_green;
	my->red = my->light_red;
	my->lightrange = my->light_range;
	
	vec_set(&my->skill20, &my->x);
	my->skill23 = random(360);
	
	my->flags |= UNLIT | LIGHT | BRIGHT;
	
	while(1)
	{
		my->lightrange = my->light_range + random(10); // flicker
		my->x = my->skill20 + fsin(my->skill23 + total_ticks * 4, 80);
		my->y = my->skill21 + fcos(my->skill23 + total_ticks * 4, 80);
		wait(1);
	}
}


Salud!

Re: vecLightViewPos question [Re: 3run] #480032
05/14/20 18:33
05/14/20 18:33
Joined: May 2009
Posts: 5,370
Caucasus
3run Offline OP
Senior Expert
3run  Offline OP
Senior Expert

Joined: May 2009
Posts: 5,370
Caucasus
Material works like a charm! laugh Thank you txesmi!

I've implemented some of your code into the one that I had yesterday and I'm pretty happy with results!

Here how it looks like
[Linked Image]

Here is standalone demo
Code
#include <acknex.h>
#include <default.c>

VIEW *pp_view = { layer = 2; flags = PROCESS_TARGET | CHILD; }

MATERIAL *mtl_2d_lights =
{
	effect = "
	//https://www.shadertoy.com/view/ttj3zd

	float4x4 matProj;
	const float4 vecTime;
	const float4 vecViewPort;

	float smoothObjectPadding = 0.33;
	float flickerSpeedFactor = 2;

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

	texture TargetMap;

	sampler postTex = sampler_state
	{
		texture = <TargetMap>;
		MinFilter = Point;
	};

	float4 FP(
	in float2 inTex : TEXCOORD0, 
	in float2 inPos : VPOS) : COLOR
	{
		float3 color = tex2D(postTex, inTex).rgb;
		float3 blurColor = float3(0.0, 0.0, 0.0);
		
		float i = 0;
		for(i = 0; i < iLights; i += 1.0)
		{
			// pointlights only
			// checking only .w doesn't help to skip the sun
			if(vecLightDir[i].x <= 0 && vecLightDir[i].y <= 0 && vecLightDir[i].z <= 0)
			{
				float4 clipSpacePos = mul(float4(vecLightViewPos[i].xyz, 1.0f), matProj);
				float2 ndcSpacePos = clipSpacePos.xy / clipSpacePos.w;
				float2 windowSpacePos = float2(1.0f + ndcSpacePos.x, 1.0f - ndcSpacePos.y) * vecViewPort.xy * 0.5f;
				float4 clipSpaceOutterPoint = mul(float4(vecLightViewPos[i].x - vecLightPos[i].w, vecLightViewPos[i].yz, 1.0f), matProj);
				float ndcSpaceOutterPoint = clipSpaceOutterPoint.x / clipSpaceOutterPoint.w;
				float windowSpaceRadius = (ndcSpacePos.x - ndcSpaceOutterPoint) * vecViewPort.x * 0.5f;
				
				float2 objectCenter = windowSpacePos.xy / vecViewPort.xy;
				float2 uv = length(inPos - windowSpacePos);
				float2 pos = uv - objectCenter;
				
				float flickerTime = sin(vecTime.w * flickerSpeedFactor);
				float min_size = windowSpaceRadius;
				float max_size = windowSpaceRadius + 8;
				float size = lerp(min_size, max_size, flickerTime);
				
				float smoothSize = size * smoothObjectPadding;
				float circleMix = smoothstep(size, size - smoothSize, length(pos));
				
				blurColor.rgb = lerp(blurColor.rgb, color.rgb * vecLightColor[i].rgb, circleMix);
			}
		}
		
		float4 fragColor = float4(blurColor, 1.0);
		return fragColor;
	}

	technique
	{
		pass one
		{
			ZWriteEnable = False;
			AlphaBlendEnable = False;
			PixelShader = compile ps_3_0 FP();
		}
	}	
	";
}

action act_light()
{
	set(my, PASSABLE);
	vec_set(&my->blue, vector(128 + random(128), 128 + random(128), 128 + random(128)));
	my->lightrange = 128;
}

void main()
{
	video_mode = 10;
	warn_level = 6;
	sun_light = 0;
	level_load("");
	
	random_seed(0);
	camera->arc = 90;
	
	vec_set(&camera->x, vector(0, 300, 300));
	vec_set(&camera->pan, vector(270, -45, 0));
	
	pp_view->material = mtl_2d_lights;	
	camera->stage = pp_view;	
	
	ENTITY *ent = ent_create(CUBE_MDL, nullvector, NULL);
	vec_set(&ent->scale_x, vector(64, 64, 0.01));
	c_setminmax(ent);
	
	int i = 0;
	for(i = 0; i < 3; i++)
	{
		ent_create(CUBE_MDL, vector(-128 + (128 * i), 0, 16), act_light);
	}
}

There is another thing I would like to implement, but yet have no idea how.
It would be cool to mix the light colors on the 'contact' edges.
Something like this
[Linked Image]


Greets


Looking for free stuff?? Take a look here: http://badcom.at.ua
Support me on: https://boosty.to/3rung
Re: vecLightViewPos question [Re: 3run] #480037
05/15/20 11:58
05/15/20 11:58
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Glad of been of help laugh

That color space is called CMY (cyan, magenta, yellow) and it is the inverse of RGB when normalized.
Code
RGB = 1 - CMY;
CMY = 1 - RGB;


They are both additive/sustractive color spaces so you can operate same. The only problem is that CMY does not work as a 0<->1 brightness factor as RGB does in color multiply because the components content is inverse to its brightness.

Page 2 of 2 1 2

Moderated by  Blink, Hummel, Superku 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1