PSX affine texture mapping

This commit is contained in:
Robert Beckebans 2024-08-17 18:37:50 +02:00
parent 25e2208f68
commit ab589eb5ef
18 changed files with 286 additions and 150 deletions

View file

@ -5595,7 +5595,7 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
parm[0] = r_psxVertexJitter.GetFloat() * w;
parm[1] = r_psxVertexJitter.GetFloat() * h;
parm[2] = 0;
parm[2] = r_psxAffineTextures.GetFloat();
parm[3] = 0;
}
else

View file

@ -1284,6 +1284,7 @@ extern idCVar r_renderMode;
extern idCVar image_pixelLook;
extern idCVar r_psxVertexJitter;
extern idCVar r_psxAffineTextures;
// RB end
/*

View file

@ -305,6 +305,7 @@ idCVar r_retroDitherScale( "r_retroDitherScale", "0.3", CVAR_RENDERER | CVAR_FLO
idCVar r_renderMode( "r_renderMode", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_NEW, "0 = Doom, 1 = Commodore 64, 2 = Commodore 64 Highres, 3 = Amstrad CPC 6128, 4 = Amstrad CPC 6128 Highres, 5 = Gameboy, 6 = Gameboy Highres, 7 = NES, 8 = NES Highres, 9 = Sega Genesis, 10 = Sega Genesis Highres, 11 = Sony PSX", 0, 11 );
idCVar r_psxVertexJitter( "r_psxVertexJitter", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "", 0.0f, 0.75f );
idCVar r_psxAffineTextures( "r_psxAffineTextures", "1", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );
// RB end
const char* fileExten[4] = { "tga", "png", "jpg", "exr" };

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2016 Robert Beckebans
Copyright (C) 2016-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -37,7 +37,7 @@ SamplerState s_Sampler : register( s0 VK_DESCRIPTOR_SET( 2 ) );
struct PS_IN
{
float4 position : SV_Position;
float2 texcoord0 : TEXCOORD0_centroid;
float3 texcoord0 : TEXCOORD0_centroid;
float3 texcoord1 : TEXCOORD1_centroid;
float3 texcoord2 : TEXCOORD2_centroid;
float3 texcoord3 : TEXCOORD3_centroid;
@ -53,33 +53,30 @@ struct PS_OUT
void main( PS_IN fragment, out PS_OUT result )
{
float4 bump = t_NormalMap.Sample( s_Sampler, fragment.texcoord0 ) * 2.0f - 1.0f;
float2 bumpUV = fragment.texcoord0.xy;
float2 specUV = fragment.texcoord1.xy;
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
bumpUV /= fragment.texcoord0.z;
specUV /= fragment.texcoord0.z;
}
float4 bump = t_NormalMap.Sample( s_Sampler, bumpUV ) * 2.0f - 1.0f;
// TODO sample roughness and put it into the alpha channel
// RB begin
float3 localNormal;
#if USE_NORMAL_FMT_RGB8
localNormal = float3( bump.rg, 0.0f );
#else
localNormal = float3( bump.wy, 0.0f );
#endif
// RB end
localNormal.z = sqrt( 1.0f - dot3( localNormal, localNormal ) );
float3 globalNormal;
#if 1
// rotate normal into view space
// rotate normal into world space
globalNormal.x = dot3( localNormal, fragment.texcoord2 );
globalNormal.y = dot3( localNormal, fragment.texcoord3 );
globalNormal.z = dot3( localNormal, fragment.texcoord4 );
#else
// only the normal in view space
globalNormal.x = fragment.texcoord2.z;
globalNormal.y = fragment.texcoord3.z;
globalNormal.z = fragment.texcoord4.z;
//globalNormal.z = fragment.texcoord4.z * -0.001; //sqrt( abs( dot( globalNormal.xy, globalNormal.xy ) - 0.25 ) );
globalNormal = normalize( globalNormal );
#endif
// RB: rpColor is white and only used to generate the _fa_ uniform array
result.color.rgb = ( globalNormal.xyz * 0.5 + 0.5 ) * fragment.color.rgb;// * rpColor;

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2016 Robert Beckebans
Copyright (C) 2016-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -47,7 +47,7 @@ struct VS_IN
struct VS_OUT
{
float4 position : SV_Position;
float2 texcoord0 : TEXCOORD0_centroid;
float3 texcoord0 : TEXCOORD0_centroid;
float3 texcoord1 : TEXCOORD1_centroid;
float3 texcoord2 : TEXCOORD2_centroid;
float3 texcoord3 : TEXCOORD3_centroid;
@ -136,6 +136,21 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord0.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );
result.texcoord0.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );
//# textures 1 takes the base coordinates by the texture matrix
result.texcoord1.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
result.texcoord1.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord0.z = warp;
result.texcoord0.xy *= warp;
result.texcoord1.xy *= warp;
}
//float4 toEye = rpLocalViewOrigin - modelPosition;
//result.texcoord1.x = dot3( toEye, rpModelMatrixX );
//result.texcoord1.y = dot3( toEye, rpModelMatrixY );

View file

@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "BRDF.inc.hlsl"
// *INDENT-OFF*
Texture2D t_Normal : register( t0 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_Specular : register( t1 VK_DESCRIPTOR_SET( 1 ) );
@ -47,23 +48,23 @@ SamplerState s_Material : register( s0 VK_DESCRIPTOR_SET( 3 ) ); // (Wrap) Ani
SamplerState s_LinearClamp : register( s1 VK_DESCRIPTOR_SET( 3 ) ); // (Clamp) Linear sampler: brdf lut sampler & ssao sampler
//SamplerState s_Light : register( s2 VK_DESCRIPTOR_SET( 3 )); // (Clamp) Anisotropic sampler: irradiance, radiance 1, 2 and 3.
struct PS_IN
struct PS_IN
{
half4 position : SV_Position;
half4 texcoord0 : TEXCOORD0_centroid;
half4 texcoord1 : TEXCOORD1_centroid;
half4 texcoord2 : TEXCOORD2_centroid;
half4 texcoord3 : TEXCOORD3_centroid;
half4 texcoord4 : TEXCOORD4_centroid;
half4 texcoord5 : TEXCOORD5_centroid;
half4 texcoord6 : TEXCOORD6_centroid;
half4 texcoord7 : TEXCOORD7_centroid;
half4 color : COLOR0;
float4 position : SV_Position;
float4 texcoord0 : TEXCOORD0_centroid;
float4 texcoord1 : TEXCOORD1_centroid;
float4 texcoord2 : TEXCOORD2_centroid;
float4 texcoord3 : TEXCOORD3_centroid;
float4 texcoord4 : TEXCOORD4_centroid;
float4 texcoord5 : TEXCOORD5_centroid;
float4 texcoord6 : TEXCOORD6_centroid;
float4 texcoord7 : TEXCOORD7_centroid;
float4 color : COLOR0;
};
struct PS_OUT
{
half4 color : SV_Target0;
float4 color : SV_Target0;
};
// *INDENT-ON*
@ -126,14 +127,26 @@ bool AABBRayIntersection( float3 b[2], float3 start, float3 dir, out float scale
void main( PS_IN fragment, out PS_OUT result )
{
half4 bumpMap = t_Normal.Sample( s_Material, fragment.texcoord0.xy );
half4 YCoCG = t_BaseColor.Sample( s_Material, fragment.texcoord1.xy );
half4 specMapSRGB = t_Specular.Sample( s_Material, fragment.texcoord2.xy );
half4 specMap = sRGBAToLinearRGBA( specMapSRGB );
float2 baseUV = fragment.texcoord1.xy;
float2 bumpUV = fragment.texcoord0.xy;
float2 specUV = fragment.texcoord2.xy;
half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
baseUV /= fragment.texcoord0.z;
bumpUV /= fragment.texcoord0.z;
specUV /= fragment.texcoord0.z;
}
half3 localNormal;
float4 bumpMap = t_Normal.Sample( s_Material, bumpUV );
float4 YCoCG = t_BaseColor.Sample( s_Material, baseUV );
float4 specMapSRGB = t_Specular.Sample( s_Material, specUV );
float4 specMap = sRGBAToLinearRGBA( specMapSRGB );
float3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
float3 localNormal;
#if defined(USE_NORMAL_FMT_RGB8)
localNormal.xy = bumpMap.rg - 0.5;
#else
@ -183,28 +196,28 @@ void main( PS_IN fragment, out PS_OUT result )
}
#endif
half vDotN = saturate( dot3( globalView, globalNormal ) );
float vDotN = saturate( dot3( globalView, globalNormal ) );
#if USE_PBR
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;
const float metallic = specMapSRGB.g;
const float roughness = specMapSRGB.r;
const float glossiness = 1.0 - roughness;
// the vast majority of real-world materials (anything not metal or gems) have F(0)
// values in a very narrow range (~0.02 - 0.08)
// approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)
const half3 dielectricColor = _half3( 0.04 );
const float3 dielectricColor = _float3( 0.04 );
// derive diffuse and specular from albedo(m) base color
const half3 baseColor = diffuseMap;
const float3 baseColor = diffuseMap;
half3 diffuseColor = baseColor * ( 1.0 - metallic );
half3 specularColor = lerp( dielectricColor, baseColor, metallic );
float3 diffuseColor = baseColor * ( 1.0 - metallic );
float3 specularColor = lerp( dielectricColor, baseColor, metallic );
#if defined( DEBUG_PBR )
diffuseColor = half3( 0.0, 0.0, 0.0 );
specularColor = half3( 0.0, 1.0, 0.0 );
diffuseColor = float3( 0.0, 0.0, 0.0 );
specularColor = float3( 0.0, 1.0, 0.0 );
#endif
float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );
@ -213,12 +226,12 @@ void main( PS_IN fragment, out PS_OUT result )
#else
const float roughness = EstimateLegacyRoughness( specMapSRGB.rgb );
half3 diffuseColor = diffuseMap;
half3 specularColor = specMap.rgb;
float3 diffuseColor = diffuseMap;
float3 specularColor = specMap.rgb;
#if defined( DEBUG_PBR )
diffuseColor = half3( 0.0, 0.0, 0.0 );
specularColor = half3( 1.0, 0.0, 0.0 );
diffuseColor = float3( 0.0, 0.0, 0.0 );
specularColor = float3( 1.0, 0.0, 0.0 );
#endif
float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );
@ -228,8 +241,8 @@ void main( PS_IN fragment, out PS_OUT result )
#endif
//diffuseColor = half3( 1.0, 1.0, 1.0 );
//diffuseColor = half3( 0.0, 0.0, 0.0 );
//diffuseColor = float3( 1.0, 1.0, 1.0 );
//diffuseColor = float3( 0.0, 0.0, 0.0 );
// calculate the screen texcoord in the 0.0 to 1.0 range
//float2 screenTexCoord = vposToScreenPosTexCoord( fragment.position.xy );
@ -424,8 +437,8 @@ void main( PS_IN fragment, out PS_OUT result )
//horiz = clamp( horiz, 0.0, 1.0 );
#endif
//half3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );
half3 lightColor = ( rpAmbientColor.rgb );
//float3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );
float3 lightColor = ( rpAmbientColor.rgb );
//result.color.rgb = diffuseLight;
//result.color.rgb = diffuseLight * lightColor;

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2015 Robert Beckebans
Copyright (C) 2021-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -29,13 +29,11 @@ If you have questions concerning this license or the applicable additional terms
#include "global_inc.hlsl"
// *INDENT-OFF*
#if USE_GPU_SKINNING
StructuredBuffer<float4> matrices: register(t11);
#endif
// *INDENT-OFF*
struct VS_IN
{
float4 position : POSITION;
@ -46,7 +44,7 @@ struct VS_IN
float4 color2 : COLOR1;
};
struct VS_OUT
struct VS_OUT
{
float4 position : SV_Position;
float4 texcoord0 : TEXCOORD0_centroid;
@ -157,6 +155,18 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord2.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
result.texcoord2.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord0.z = warp;
result.texcoord0.xy *= warp;
result.texcoord1.xy *= warp;
result.texcoord2.xy *= warp;
}
//# calculate normalized vector to viewer in R1
//result.texcoord3 = modelPosition;

View file

@ -48,23 +48,23 @@ SamplerState s_Material : register( s0 VK_DESCRIPTOR_SET( 3 ) ); // (Wrap) Ani
SamplerState s_LinearClamp : register( s1 VK_DESCRIPTOR_SET( 3 ) ); // (Clamp) Linear sampler: brdf lut sampler & ssao sampler
//SamplerState s_Light : register( s2 VK_DESCRIPTOR_SET( 3 )); // (Clamp) Anisotropic sampler: irradiance, radiance 1, 2 and 3.
struct PS_IN
struct PS_IN
{
half4 position : SV_Position;
half4 texcoord0 : TEXCOORD0_centroid;
half4 texcoord1 : TEXCOORD1_centroid;
half4 texcoord2 : TEXCOORD2_centroid;
half4 texcoord3 : TEXCOORD3_centroid;
half4 texcoord4 : TEXCOORD4_centroid;
half4 texcoord5 : TEXCOORD5_centroid;
half4 texcoord6 : TEXCOORD6_centroid;
half4 texcoord7 : TEXCOORD7_centroid;
half4 color : COLOR0;
float4 position : SV_Position;
float4 texcoord0 : TEXCOORD0_centroid;
float4 texcoord1 : TEXCOORD1_centroid;
float4 texcoord2 : TEXCOORD2_centroid;
float4 texcoord3 : TEXCOORD3_centroid;
float4 texcoord4 : TEXCOORD4_centroid;
float4 texcoord5 : TEXCOORD5_centroid;
float4 texcoord6 : TEXCOORD6_centroid;
float4 texcoord7 : TEXCOORD7_centroid;
float4 color : COLOR0;
};
struct PS_OUT
{
half4 color : SV_Target0;
float4 color : SV_Target0;
};
// *INDENT-ON*
@ -147,14 +147,26 @@ float2 OctTexCoord( float3 worldDir )
void main( PS_IN fragment, out PS_OUT result )
{
half4 bumpMap = t_Normal.Sample( s_Material, fragment.texcoord0.xy );
half4 YCoCG = t_BaseColor.Sample( s_Material, fragment.texcoord1.xy );
half4 specMapSRGB = t_Specular.Sample( s_Material, fragment.texcoord2.xy );
half4 specMap = sRGBAToLinearRGBA( specMapSRGB );
float2 baseUV = fragment.texcoord1.xy;
float2 bumpUV = fragment.texcoord0.xy;
float2 specUV = fragment.texcoord2.xy;
half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
baseUV /= fragment.texcoord0.z;
bumpUV /= fragment.texcoord0.z;
specUV /= fragment.texcoord0.z;
}
half3 localNormal;
float4 bumpMap = t_Normal.Sample( s_Material, bumpUV );
float4 YCoCG = t_BaseColor.Sample( s_Material, baseUV );
float4 specMapSRGB = t_Specular.Sample( s_Material, specUV );
float4 specMap = sRGBAToLinearRGBA( specMapSRGB );
float3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
float3 localNormal;
#if defined(USE_NORMAL_FMT_RGB8)
localNormal.xy = bumpMap.rg - 0.5;
#else
@ -204,28 +216,28 @@ void main( PS_IN fragment, out PS_OUT result )
}
#endif
half vDotN = saturate( dot3( globalView, globalNormal ) );
float vDotN = saturate( dot3( globalView, globalNormal ) );
#if USE_PBR
const half metallic = specMapSRGB.g;
const half roughness = specMapSRGB.r;
const half glossiness = 1.0 - roughness;
const float metallic = specMapSRGB.g;
const float roughness = specMapSRGB.r;
const float glossiness = 1.0 - roughness;
// the vast majority of real-world materials (anything not metal or gems) have F(0)
// values in a very narrow range (~0.02 - 0.08)
// approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)
const half3 dielectricColor = _half3( 0.04 );
const float3 dielectricColor = _float3( 0.04 );
// derive diffuse and specular from albedo(m) base color
const half3 baseColor = diffuseMap;
const float3 baseColor = diffuseMap;
half3 diffuseColor = baseColor * ( 1.0 - metallic );
half3 specularColor = lerp( dielectricColor, baseColor, metallic );
float3 diffuseColor = baseColor * ( 1.0 - metallic );
float3 specularColor = lerp( dielectricColor, baseColor, metallic );
#if defined( DEBUG_PBR )
diffuseColor = half3( 0.0, 0.0, 0.0 );
specularColor = half3( 0.0, 1.0, 0.0 );
diffuseColor = float3( 0.0, 0.0, 0.0 );
specularColor = float3( 0.0, 1.0, 0.0 );
#endif
float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );
@ -234,12 +246,12 @@ void main( PS_IN fragment, out PS_OUT result )
#else
const float roughness = EstimateLegacyRoughness( specMapSRGB.rgb );
half3 diffuseColor = diffuseMap;
half3 specularColor = specMap.rgb;
float3 diffuseColor = diffuseMap;
float3 specularColor = specMap.rgb;
#if defined( DEBUG_PBR )
diffuseColor = half3( 0.0, 0.0, 0.0 );
specularColor = half3( 1.0, 0.0, 0.0 );
diffuseColor = float3( 0.0, 0.0, 0.0 );
specularColor = float3( 1.0, 0.0, 0.0 );
#endif
float3 kS = Fresnel_SchlickRoughness( specularColor, vDotN, roughness );
@ -249,8 +261,8 @@ void main( PS_IN fragment, out PS_OUT result )
#endif
//diffuseColor = half3( 1.0, 1.0, 1.0 );
//diffuseColor = half3( 0.0, 0.0, 0.0 );
//diffuseColor = float3( 1.0, 1.0, 1.0 );
//diffuseColor = float3( 0.0, 0.0, 0.0 );
// calculate the screen texcoord in the 0.0 to 1.0 range
//float2 screenTexCoord = vposToScreenPosTexCoord( fragment.position.xy );
@ -303,8 +315,8 @@ void main( PS_IN fragment, out PS_OUT result )
//horiz = clamp( horiz, 0.0, 1.0 );
#endif
//half3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );
half3 lightColor = ( rpAmbientColor.rgb );
//float3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );
float3 lightColor = ( rpAmbientColor.rgb );
//result.color.rgb = diffuseLight;
//result.color.rgb = diffuseLight * lightColor;

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2015 Robert Beckebans
Copyright (C) 2021-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -29,7 +29,6 @@ If you have questions concerning this license or the applicable additional terms
#include "global_inc.hlsl"
// *INDENT-OFF*
#if USE_GPU_SKINNING
StructuredBuffer<float4> matrices: register(t11);
@ -62,7 +61,6 @@ struct VS_OUT
void main( VS_IN vertex, out VS_OUT result )
{
float4 vNormal = vertex.normal * 2.0 - 1.0;
float4 vTangent = vertex.tangent * 2.0 - 1.0;
float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
@ -161,6 +159,18 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord2.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
result.texcoord2.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord0.z = warp;
result.texcoord0.xy *= warp;
result.texcoord1.xy *= warp;
result.texcoord2.xy *= warp;
}
//# calculate normalized vector to viewer in R1
//result.texcoord3 = modelPosition;

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2021 Robert Beckebans
Copyright (C) 2013-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -57,17 +57,29 @@ struct PS_IN
struct PS_OUT
{
half4 color : SV_Target0;
float4 color : SV_Target0;
};
// *INDENT-ON*
void main( PS_IN fragment, out PS_OUT result )
{
float4 bumpMap = t_Normal.Sample( s_Material, fragment.texcoord1.xy );
float2 baseUV = fragment.texcoord4.xy;
float2 bumpUV = fragment.texcoord1.xy;
float2 specUV = fragment.texcoord5.xy;
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
baseUV /= fragment.texcoord1.z;
bumpUV /= fragment.texcoord1.z;
specUV /= fragment.texcoord1.z;
}
float4 bumpMap = t_Normal.Sample( s_Material, bumpUV );
float4 lightFalloff = idtex2Dproj( s_Lighting, t_LightFalloff, fragment.texcoord2 );
float4 lightProj = idtex2Dproj( s_Lighting, t_LightProjection, fragment.texcoord3 );
float4 YCoCG = t_BaseColor.Sample( s_Material, fragment.texcoord4.xy );
float4 specMapSRGB = t_Specular.Sample( s_Material, fragment.texcoord5.xy );
float4 YCoCG = t_BaseColor.Sample( s_Material, baseUV );
float4 specMapSRGB = t_Specular.Sample( s_Material, specUV );
float4 specMap = sRGBAToLinearRGBA( specMapSRGB );
float3 lightVector = normalize( fragment.texcoord0.xyz );
@ -76,7 +88,7 @@ void main( PS_IN fragment, out PS_OUT result )
float3 localNormal;
// RB begin
#if defined(USE_NORMAL_FMT_RGB8)
#if USE_NORMAL_FMT_RGB8
localNormal.xy = bumpMap.rg - 0.5;
#else
localNormal.xy = bumpMap.wy - 0.5;

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
Copyright (C) 2014-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -44,7 +44,7 @@ struct VS_IN
float4 color2 : COLOR1;
};
struct VS_OUT
struct VS_OUT
{
float4 position : SV_Position;
float4 texcoord0 : TEXCOORD0_centroid;
@ -56,7 +56,6 @@ struct VS_OUT
float4 texcoord6 : TEXCOORD6_centroid;
float4 color : COLOR0;
};
// *INDENT-ON*
void main( VS_IN vertex, out VS_OUT result )
@ -153,8 +152,6 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord1.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );
result.texcoord1.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );
//result.texcoord1.xy = psxAffineTexMapping( result.texcoord1.xy, )
//# texture 2 has one texgen
result.texcoord2 = defaultTexCoord;
result.texcoord2.x = dot4( modelPosition, rpLightFalloffS );
@ -175,6 +172,18 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord5.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
result.texcoord5.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord1.z = warp;
result.texcoord1.xy *= warp;
result.texcoord4.xy *= warp;
result.texcoord5.xy *= warp;
}
//# texture 6's texcoords will be the halfangle in texture space
//# calculate normalized vector to light in R0

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2020 Robert Beckebans
Copyright (C) 2013-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -62,11 +62,23 @@ struct PS_OUT
void main( PS_IN fragment, out PS_OUT result )
{
float4 bumpMap = t_Normal.Sample( s_Material, fragment.texcoord1.xy );
float2 baseUV = fragment.texcoord4.xy;
float2 bumpUV = fragment.texcoord1.xy;
float2 specUV = fragment.texcoord5.xy;
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
baseUV /= fragment.texcoord1.z;
bumpUV /= fragment.texcoord1.z;
specUV /= fragment.texcoord1.z;
}
float4 bumpMap = t_Normal.Sample( s_Material, bumpUV );
float4 lightFalloff = idtex2Dproj( s_Lighting, t_LightFalloff, fragment.texcoord2 );
float4 lightProj = idtex2Dproj( s_Lighting, t_LightProjection, fragment.texcoord3 );
float4 YCoCG = t_BaseColor.Sample( s_Material, fragment.texcoord4.xy );
float4 specMapSRGB = t_Specular.Sample( s_Material, fragment.texcoord5.xy );
float4 YCoCG = t_BaseColor.Sample( s_Material, baseUV );
float4 specMapSRGB = t_Specular.Sample( s_Material, specUV );
float4 specMap = sRGBAToLinearRGBA( specMapSRGB );
const float3 ambientLightVector = half3( 0.5f, 9.5f - 0.385f, 0.8925f );

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -164,6 +165,18 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord5.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
result.texcoord5.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord1.z = warp;
result.texcoord1.xy *= warp;
result.texcoord4.xy *= warp;
result.texcoord5.xy *= warp;
}
//# texture 6's texcoords will be the halfangle in texture space
//# calculate normalized vector to light in R0

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2021 Robert Beckebans
Copyright (C) 2013-2024 Robert Beckebans
Copyright (C) 2020 Panos Karabelas
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -102,11 +102,23 @@ float2 VogelDiskSample( float sampleIndex, float samplesCount, float phi )
void main( PS_IN fragment, out PS_OUT result )
{
float4 bumpMap = t_Normal.Sample( s_Material, fragment.texcoord1.xy );
float2 baseUV = fragment.texcoord4.xy;
float2 bumpUV = fragment.texcoord1.xy;
float2 specUV = fragment.texcoord5.xy;
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
baseUV /= fragment.texcoord1.z;
bumpUV /= fragment.texcoord1.z;
specUV /= fragment.texcoord1.z;
}
float4 bumpMap = t_Normal.Sample( s_Material, bumpUV );
float4 lightFalloff = idtex2Dproj( s_Lighting, t_LightFalloff, fragment.texcoord2 );
float4 lightProj = idtex2Dproj( s_Lighting, t_LightProjection, fragment.texcoord3 );
float4 YCoCG = t_BaseColor.Sample( s_Material, fragment.texcoord4.xy );
float4 specMapSRGB = t_Specular.Sample( s_Material, fragment.texcoord5.xy );
float4 YCoCG = t_BaseColor.Sample( s_Material, baseUV );
float4 specMapSRGB = t_Specular.Sample( s_Material, specUV );
float4 specMap = sRGBAToLinearRGBA( specMapSRGB );
float3 lightVector = normalize( fragment.texcoord0.xyz );

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
Copyright (C) 2014-2024 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -63,7 +63,6 @@ struct VS_OUT
void main( VS_IN vertex, out VS_OUT result )
{
float4 vNormal = vertex.normal * 2.0 - 1.0;
float4 vTangent = vertex.tangent * 2.0 - 1.0;
float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
@ -176,6 +175,18 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord5.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
result.texcoord5.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord1.z = warp;
result.texcoord1.xy *= warp;
result.texcoord4.xy *= warp;
result.texcoord5.xy *= warp;
}
//# texture 6's texcoords will be the halfangle in texture space
//# calculate normalized vector to light in R0

View file

@ -35,7 +35,7 @@ SamplerState s_Sampler : register( s0 VK_DESCRIPTOR_SET( 2 ) );
struct PS_IN {
float4 position : SV_POSITION;
float2 texcoord0 : TEXCOORD0_centroid;
float3 texcoord0 : TEXCOORD0_centroid;
float4 color : COLOR0;
};
@ -46,7 +46,15 @@ struct PS_OUT {
void main( in PS_IN fragment, out PS_OUT result )
{
float4 color = t_BaseColor.Sample( s_Sampler, fragment.texcoord0 ) * fragment.color;
float2 uv = fragment.texcoord0.xy;
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
uv /= fragment.texcoord0.z;
}
float4 color = t_BaseColor.Sample( s_Sampler, uv ) * fragment.color;
clip( color.a - rpAlphaTest.x );
result.color = sRGBAToLinearRGBA( color );
}

View file

@ -46,7 +46,7 @@ struct VS_IN
struct VS_OUT
{
float4 position : SV_Position;
float2 texcoord0 : TEXCOORD0_centroid;
float3 texcoord0 : TEXCOORD0_centroid;
float4 color : COLOR0;
};
// *INDENT-ON*
@ -91,13 +91,19 @@ void main( VS_IN vertex, out VS_OUT result )
modelPosition.z = dot4( matZ, vertex.position );
modelPosition.w = 1.0;
modelPosition.xyz = psxVertexJitter( modelPosition );
#else
float4 modelPosition = vertex.position;
#endif
result.position.x = dot4( modelPosition, rpMVPmatrixX );
result.position.y = dot4( modelPosition, rpMVPmatrixY );
result.position.z = dot4( modelPosition, rpMVPmatrixZ );
result.position.w = dot4( modelPosition, rpMVPmatrixW );
result.position.xyz = psxVertexJitter( result.position );
// compute oldschool texgen or multiply by texture matrix
BRANCH if( rpTexGen0Enabled.x > 0.0 )
{
@ -109,27 +115,16 @@ void main( VS_IN vertex, out VS_OUT result )
result.texcoord0.x = dot4( vertex.texcoord.xy, rpTextureMatrixS );
result.texcoord0.y = dot4( vertex.texcoord.xy, rpTextureMatrixT );
}
#else
result.position.x = dot4( vertex.position, rpMVPmatrixX );
result.position.y = dot4( vertex.position, rpMVPmatrixY );
result.position.z = dot4( vertex.position, rpMVPmatrixZ );
result.position.w = dot4( vertex.position, rpMVPmatrixW );
result.position.xyz = psxVertexJitter( result.position );
// Compute oldschool texgen or multiply by texture matrix
BRANCH if( rpTexGen0Enabled.x > 0.0 )
// PSX affine texture mapping
if( rpPSXDistortions.z > 0.0 )
{
result.texcoord0.x = dot4( vertex.position, rpTexGen0S );
result.texcoord0.y = dot4( vertex.position, rpTexGen0T );
float distance = length( rpLocalViewOrigin - modelPosition );
float warp = psxAffineWarp( distance );
result.texcoord0.z = warp;
result.texcoord0.xy *= warp;
}
else
{
result.texcoord0.x = dot4( vertex.texcoord.xy, rpTextureMatrixS );
result.texcoord0.y = dot4( vertex.texcoord.xy, rpTextureMatrixT );
}
#endif
float4 vertexColor = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;
result.color = vertexColor * rpColor;

View file

@ -492,18 +492,23 @@ static float2 vposToScreenPosTexCoord( float2 vpos )
return vpos.xy * rpWindowCoord.xy;
}
static float3 psxVertexJitter( float4 spos )
// a very useful resource with many examples about the PS1 look:
// https://www.david-colson.com/2021/11/30/ps1-style-renderer.html
// emulate rasterization with fixed point math
static float3 psxVertexJitter( float4 clipPos )
{
float jitterScale = rpPSXDistortions.x;
if( jitterScale > 0.0 )
{
// snap to vertex to a pixel position on a lower grid
float3 vertex = spos.xyz / spos.w;
float3 vertex = clipPos.xyz / clipPos.w;
//float2 resolution = float2( 320, 240 ) * ( 1.0 - jitterScale );
//float2 resolution = float2( 160, 120 );
float2 resolution = float2( rpPSXDistortions.x, rpPSXDistortions.y );
// depth independent snapping
float w = dot4( rpProjectionMatrixW, float4( vertex.xyz, 1.0 ) );
vertex.xy = round( vertex.xy / w * resolution ) / resolution * w;
@ -511,17 +516,17 @@ static float3 psxVertexJitter( float4 spos )
//vertex.xy = round( vertex.xy * resolution ) / resolution;
//vertex.xyz = round( vertex.xyz * resolution.x ) / resolution.x;
vertex *= spos.w;
vertex *= clipPos.w;
return vertex;
}
return spos.xyz;
return clipPos.xyz;
}
static float2 psxAffineTexMapping( float2 uv, float4 spos )
static float psxAffineWarp( float distance )
{
return uv;
return log10( distance ) / 2.0;
}
#define BRANCH