PS1 texturing bubbling ?

Posted By: 3run

PS1 texturing bubbling ? - 02/25/20 15:22

Hey!

I wonder if it's possible to get ps1 styled texture bubbling ? If I understood correctly from googling, it requires to have 'affine texture mapping' instead of default perspective correct texturing.
Here on this video, you can see what I mean:
Godot engine - Affine texture mapping (PS1-style)

Best regards!
Posted By: Quad

Re: PS1 texturing bubbling ? - 02/25/20 21:36

Code
const float4x4 matWorldViewProj;
const float4x4 matWorld; 
texture entSkin1; 

// Color map sampler
sampler ColorMapSampler = sampler_state 
{ 
   Texture = <entSkin1>; 

}; 
    
// Vertex Shader: 
void DiffuseVS( 
   in float4 InPos: POSITION, 
   in float3 InNormal: NORMAL, 
   in float2 InTex: TEXCOORD0, 
   out float4 OutPos: POSITION, 
   out float2 OutTex: TEXCOORD0, 
   out float3 OutNormal: TEXCOORD1) 
{ 
   OutPos = mul(InPos, matWorldViewProj); 
   OutPos /= OutPos.w;
   OutNormal = normalize(mul(InNormal, matWorld));
   OutTex = InTex; 
} 
    
// Pixel Shader: 
float4 DiffusePS( 
   in float2 InTex: TEXCOORD0, 
   in float3 InNormal: TEXCOORD1): COLOR 
{ 
   return tex2D(ColorMapSampler, InTex); 
} 
 
// Technique: 
technique AffineTechnique 
{ 
   pass P0 
   { 
      VertexShader = compile vs_2_0 DiffuseVS(); 
      PixelShader  = compile ps_2_0 DiffusePS(); 
   } 
} 


Just the most basic texture mapping, no lights, no sun, no ambient. Only difference is OutPos /= OutPos.w; line.

Explanation here: https://webglfundamentals.org/webgl/lessons/webgl-3d-perspective-correct-texturemapping.html
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/25/20 22:05

Salam aleykum, Quad!

Thank you very much for the working example and a link to the article! I guess acknex is pretty awesome for ps1 styled games since it provides outdated graphics out of the box grin

My best regards!
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/26/20 00:26

Wow, this get's messed up when I try to apply this material on the plane grin
[Linked Image]
[Linked Image]
What would you suggest guys? I love results on the first screen, but the second one is just a mess grin

It's awesome to see that it only takes one line of code to get this retro look but one line isn't probably enough to get it suitable for games?
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/26/20 08:18

After playing around I've got even more weird results, but now with fog and perpixel lightning grin
[Linked Image]
Any ideas on how to fix that mess on previous screens are welcome! It would be great to get something like this working for oldschool projects.
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/26/20 10:38

I've found this pxs_retroshader for Unity.

And there was this part in it:
Code
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

float distance = length(mul(UNITY_MATRIX_MV,v.vertex));

//Affine Texture Mapping
float4 affinePos = vertex;//vertex;				
o.uv_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv_MainTex *= distance + (vertex.w*(UNITY_LIGHTMODEL_AMBIENT.a * 8)) / distance / 2;
o.normal = distance + (vertex.w*(UNITY_LIGHTMODEL_AMBIENT.a * 8)) / distance / 2;
After googling around, I came up with this results:
Code
const float4x4 matWorldViewProj;
const float4x4 matWorld; 
texture entSkin1; 

// Color map sampler
sampler ColorMapSampler = sampler_state 
{ 
	Texture = <entSkin1>; 
}; 

// Vertex Shader: 
void DiffuseVS( 
in float4 InPos: POSITION, 
in float3 InNormal: NORMAL, 
in float2 InTex: TEXCOORD0, 
out float4 OutPos: POSITION, 
out float2 OutTex: TEXCOORD0, 
out float3 OutNormal: TEXCOORD1) 
{
	float distance = length(mul(InPos, matWorldViewProj));
	OutPos = mul(InPos, matWorldViewProj); 
	OutPos *= distance + (OutPos.w * (0.1)) / distance / 2;
	//OutNormal = distance + (OutPos.w * (0.1)) / distance / 2;
	OutNormal = normalize(mul(InNormal, matWorld));
	OutTex = InTex; 
} 

// Pixel Shader: 
float4 DiffusePS( 
in float2 InTex: TEXCOORD0, 
in float3 InNormal: TEXCOORD1): COLOR 
{ 
	return tex2D(ColorMapSampler, InTex); 
} 

// Technique: 
technique AffineTechnique 
{ 
	pass P0 
	{ 
		VertexShader = compile vs_2_0 DiffuseVS(); 
		PixelShader  = compile ps_2_0 DiffusePS(); 
	} 
}
But I'm not sure, if I've done it correctly grin
[Linked Image]
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/26/20 16:16

I came up with this code at the end (vertex lightning):
Code
#include <transform>
#include <fog>
#include <pos>
#include <normal>
#include <light>
#include <color>

#define DXLIGHTING
#define DXFOG

struct vertexOut
{
	float4 Pos : POSITION;
	float Fog : FOG;
	float4 Color : COLOR0;
	float2 Tex : TEXCOORD0;
	float2 LM : TEXCOORD1;
};

vertexOut solid_VS (
in float4 inPos : POSITION, 
in float3 inNormal : NORMAL,
in float2 inTex : TEXCOORD0,
in float2 inLM : TEXCOORD1
)
{
	vertexOut Out;
	Out.Pos = DoTransform(inPos);
	Out.Pos *= inPos.w / length(mul(inPos, matWorldViewProj));
	Out.Tex = inTex;
	Out.LM = inLM;
	Out.Fog = DoFog(inPos);
	float3 P = DoPos(inPos);
	float3 N = DoNormal(inNormal);

	float3 Color = 0; 
	for (int i = 0; i < 8; i++)  // add 8 dynamic lights
	{
		Color += DoLight(P, N, i);
	}

	Out.Color = 0.5 * DoAmbient() + 0.5 * float4(Color, 1) * vecDiffuse;

	return Out;		
}

technique solid
{
	pass one
	{		
		CullMode = None;
		ZWriteEnable = True;
		AlphaBlendEnable = False;
		AlphaTestEnable = False;
		
		VertexShader = compile vs_2_0 solid_VS();
	}
}

technique fallback { pass one { } }
However for unknown (for me) reasons, this line:
Code
Out.Pos *= inPos.w / length(mul(inPos, matWorldViewProj));
Removes the fog.. Also, I don't know how to add static lightmap to this lightning using default.fx grin
Code
		#ifdef DXFOG
			float DoFog(float4 Pos)
			{
				float3 P = mul(Pos,matWorldView).xyz; // convert vector to view space to get it's depth (.z)
				return saturate((vecFog.y-P.z) * vecFog.z); // apply the linear fog formula
			}
			#else // distance based fog
			float DoFog(float4 Pos)
			{
				float3 P = mul(Pos,matWorld).xyz;
				return 1 - (distance(P,vecViewPos.xyz)-vecFog.x) * vecFog.z;
			}
		#endif


[Linked Image]
Posted By: Quad

Re: PS1 texturing bubbling ? - 02/27/20 01:01

Hey that looks great, proper ps1 look except for the screen resoluıion.

Also as far as i know static lightmaps requires you use second skin or something, not sure.
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/27/20 08:17

Thank you!

Yes, screen resolution is too low, changed it to 640x480. Also, there are some other stuff needs to be added to get proper ps1 look, f.e.:
Quote
- vertex inaccuracy;
- screen-space dithering;

With all of them working together this could look really awesome! I think acknex is only suitable for oldschool styled games, compared to up-to-date game engines.

Take a look at this video showing PSXEffects in Unity engine:
PSXEffects - Retro PlayStation 1 Graphics in Unity

As for static lightmap, yes I know it's stored in the entSkin2 but I don't know how to use it properly... I wish there were original mtl_shaded and mtl_model .fx files, so I could modify them directly, instead of trying to write everything on my own (since I'm not good at shaders at all). I just couldn't find them.. They are defined as ENGINE_MATERIAL mtl_shaded in avars.h and that's all...

So far I got working:
Quote
-affine texture mapping
-vertex lightning + static lightmap (too dark, I'm probably using it incorrectly.. but at least I see lightmap)

Not working:
Quote
-fog
-spotlights


Any ideas on how to calculate vertex spotlight or how to fix fog are welcome! laugh The fog one is really strange, since I don't change inPos at all..

[Linked Image]

Best regards!
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/27/20 10:12

I guess I got fog working.. grin carried it out into PixelShader. Testing now.
[Linked Image]

The only thing left is spotlight calculations. Got to think how to make it work..

Edit:

I also found this on github
Code
//Vertex snapping
float4 snapToPixel = mul(UNITY_MATRIX_MVP,v.vertex);
float4 vertex = snapToPixel;
vertex.xyz = snapToPixel.xyz / snapToPixel.w;
vertex.x = floor(160 * vertex.x) / 160;
vertex.y = floor(120 * vertex.y) / 120;
vertex.xyz *= snapToPixel.w;
o.pos = vertex;
Would be awesome if I could get it to work too !

Edit2: damn.. I didn't think that it would be so easy to implement vertex snapping... man I love results I'm getting !

Edit3: added shader cut off on distance!
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/27/20 11:08

This is what I came up with so far

mtl_shaded.fx
Code
#include <pos>
#include <normal>
#include <lights>

float4x4 matWorldViewProj;
float4 vecViewPos;

float4 vecLightDir[8];

float4 vecFog;
float4 vecFogColor;
float4 vecSkill1;

Texture entSkin1;
Texture entSkin2;

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

sampler ShadowSampler = sampler_state
{
	Texture = <entSkin2>;
	Mipfilter = Linear;
	Minfilter = Linear;
	Magfilter = Linear;
};

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;
	
	// vertex snapping
	float4 snapToPixel = mul(inPos, matWorldViewProj);
	float4 vertex = snapToPixel;
	vertex.xyz = snapToPixel.xyz / snapToPixel.w;
	vertex.x = floor((vecSkill1.y + 40) * vertex.x) / (vecSkill1.y + 40); // default 160
	vertex.y = floor(vecSkill1.y * vertex.y) / vecSkill1.y; // default 120
	vertex.xyz *= snapToPixel.w;
	Out.Pos = vertex;
	
	// affine texture mapping
	Out.Pos *= inPos.w / length(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 = 0;
	
	float3 P = DoPos(inPos);
	float3 N = DoNormal(inNormal);
	
	for(int i = 0; i < 8; i++)
	{
		if(vecLightDir[i].w > 0 && vecLightDir[i].w <= 1000) // spotlight ?
		{
			
		}
		else // pointlight ?
		{
			Out.Color += DoLight(P,N,i);
		}
	}
	
	// cut out polygons
	float distance = length(mul(inPos, matWorldViewProj));
	
	if(vecSkill1.z == 0){ vecSkill1.z = 512; }
	
	if (distance > vecSkill1.z)
	{
		Out.Pos.w = 0;
	}
	
	return Out;
}

float4 PS(vertexOut In) : COLOR0
{
	float4 textureColor = tex2D(ColorSampler, In.Tex.xy);
	float4 color = tex2D(ShadowSampler, In.Tex.zw);
	float fDepth = distance(vecViewPos.xyz, In.WorldPos.xyz);
	
	color += In.Color; // add dynamic lights
	
	color.rgb = saturate(color.rgb);
	color.rgb = pow(color.rgb, vecSkill1.x);
	color.rgb *= textureColor.rgb;
	
	float Fog = saturate((fDepth - vecFog.x) * vecFog.z);
	color.rgb = lerp(color.rgb, vecFogColor, Fog);
	
	color.a = 1;
	
	return color;
}

technique mtl_shaded
{
	pass one
	{
		ZWriteEnable = True;
		AlphaBlendEnable = False;
		AlphaTestEnable = False;
		
		VertexShader = compile vs_3_0 VS();
		PixelShader = compile ps_3_0 PS();
	}
}

Thanks to txesmi, in the past he made perpixel lightning pipeline for me, it helped a lot!
[Linked Image]
Screenshot sadly can't show vertex snapping, but it looks awesome! Next thing to add is a spotlight, but I don't know yet how to do that.

Greets!
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/27/20 13:36

Multitexture terrain (up to 16 textures? grin ) and now sky supports FOG (thanks to txesmi! he made this awesome stuff for me back in the days)
[Linked Image]
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/28/20 21:28

I found a very nasty problem in my shaders. The way I handle dynamic (vertex) lights. I calculate everything in VS and then add results to the color in PS.. this results in a weird-looking bug when luminescence lag behind of an actual light source... crazy
Posted By: 3run

Re: PS1 texturing bubbling ? - 02/28/20 22:49

Lag seems to happen only in VS+PS 3.0 and in 2.0 it seems to work fine... This means that I won't be able to use spotlights -__- Or maybe I'll figure out how to get rid of this lag in 3.0 somehow. OR I'll need to switch to per pixel lighting...

Edit: nahh... it actually seems, that it's related to the way I add calculated lights in VS to the texture in PS. If light calculations are complex, it lags out. So the one with spotlight won't work for me, if I go with the current setup. If I use default.fx's DoLight function for light calculations (without spotlight) it works pretty normally. I guess I got to think of a better way to pass lights from VS to PS.
© 2024 lite-C Forums