Added bumpyenvironment2 shader for some reflective blood experiments

This commit is contained in:
Robert Beckebans 2024-11-30 00:15:27 +01:00
parent 78bebe99ee
commit 249397bcb8
10 changed files with 507 additions and 8 deletions

View file

@ -1918,6 +1918,10 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
{
ts->texgen = TG_REFLECT_CUBE;
}
else if( !token.Icmp( "reflect2" ) )
{
ts->texgen = TG_REFLECT_CUBE2;
}
else if( !token.Icmp( "skybox" ) )
{
ts->texgen = TG_SKYBOX_CUBE;
@ -2759,6 +2763,11 @@ void idMaterial::ParseMaterial( idLexer& src )
mikktspace = true;
continue;
}
else if( !token.Icmp( "unlit" ) )
{
SetMaterialFlag( MF_UNLIT );
continue;
}
// lightFallofImage <imageprogram>
// specifies the image to use for the third axis of projected
// light volumes

View file

@ -164,11 +164,12 @@ typedef enum
TG_EXPLICIT,
TG_DIFFUSE_CUBE,
TG_REFLECT_CUBE,
TG_REFLECT_CUBE2, // RB interpolates 3 octahedrons like for ambient lighting
TG_SKYBOX_CUBE,
TG_WOBBLESKY_CUBE,
TG_SCREEN, // screen aligned, for mirrorRenders and screen space temporaries
TG_SCREEN2,
TG_GLASSWARP
TG_GLASSWARP,
} texgen_t;
typedef struct
@ -361,9 +362,8 @@ typedef enum
MF_LOD3 = BIT( 9 ), // motorsep 11-24-2014; material flag for LOD3 iteration
MF_LOD4 = BIT( 10 ), // motorsep 11-24-2014; material flag for LOD4 iteration
MF_LOD_PERSISTENT = BIT( 11 ), // motorsep 11-24-2014; material flag for persistent LOD iteration
MF_GUITARGET = BIT( 12 ), // Admer: this GUI surface is used to compute a GUI render map, but a GUI should NOT be drawn on it
MF_AUTOGEN_TEMPLATE = BIT( 13 ), // Admer: this material is a template for auto-generated templates
MF_ORIGIN = BIT( 14 ), // Admer: for origin brushes
MF_ORIGIN = BIT( 12 ), // Admer: for origin brushes
MF_UNLIT = BIT( 13 ), // RB: receive no lighting
} materialFlags_t;
// contents flags, NOTE: make sure to keep the defines in doom_defs.script up to date with these!
@ -595,7 +595,7 @@ public:
// stages, and don't interact with lights at all
bool ReceivesLighting() const
{
return numAmbientStages != numStages;
return ( numAmbientStages != numStages ) && ( materialFlags & MF_UNLIT ) == 0;
}
// returns true if the material should generate interactions on sides facing away

View file

@ -1787,6 +1787,96 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
}
}
}
else if( type == BINDING_LAYOUT_OCTAHEDRON_CUBE || type == BINDING_LAYOUT_OCTAHEDRON_CUBE_SKINNED )
{
if( type == BINDING_LAYOUT_OCTAHEDRON_CUBE_SKINNED )
{
if( desc[0].bindings.empty() )
{
desc[0].bindings =
{
nvrhi::BindingSetItem::ConstantBuffer( 0, paramCb, range ),
nvrhi::BindingSetItem::StructuredBuffer_SRV( 11, currentJointBuffer, nvrhi::Format::UNKNOWN, nvrhi::BufferRange( currentJointOffset, sizeof( idVec4 ) * numBoneMatrices ) )
};
}
else
{
auto& bindings = desc[0].bindings;
bindings[0].resourceHandle = paramCb;
bindings[0].range = range;
bindings[1].resourceHandle = currentJointBuffer;
bindings[1].range = nvrhi::BufferRange{ currentJointOffset, sizeof( idVec4 )* numBoneMatrices };
}
}
else
{
if( desc[0].bindings.empty() )
{
desc[0].bindings =
{
nvrhi::BindingSetItem::ConstantBuffer( 0, paramCb, range ),
};
}
else
{
desc[0].bindings[0].resourceHandle = paramCb;
desc[0].bindings[0].range = range;
}
}
if( desc[1].bindings.empty() )
{
desc[1].bindings =
{
nvrhi::BindingSetItem::Texture_SRV( 0, ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 1, ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 2, ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID() ),
nvrhi::BindingSetItem::Texture_SRV( 3, ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID() )
};
}
else
{
auto& bindings = desc[1].bindings;
bindings[0].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID();
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID();
bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID();
}
if( R_UsePixelatedLook() )
{
if( desc[2].bindings.empty() )
{
desc[2].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_PointWrapSampler;
desc[2].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
}
}
else
{
if( desc[2].bindings.empty() )
{
desc[2].bindings =
{
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_AnisotropicWrapSampler ),
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearBorderSampler )
};
}
else
{
desc[2].bindings[0].resourceHandle = commonPasses.m_AnisotropicWrapSampler;
desc[2].bindings[1].resourceHandle = commonPasses.m_LinearBorderSampler;
}
}
}
else if( type == BINDING_LAYOUT_BINK_VIDEO )
{
if( desc[0].bindings.empty() )

View file

@ -336,7 +336,14 @@ void idRenderBackend::BindVariableStageImage( const textureStage_t* texture, con
{
if( texture->image != NULL )
{
texture->image->Bind();
if( texture->image->IsLoaded() && !texture->image->IsDefaulted() )
{
texture->image->Bind();
}
else
{
globalImages->defaultImage->Bind();
}
}
}
}
@ -356,7 +363,6 @@ void idRenderBackend::PrepareStageTexturing( const shaderStage_t* pStage, const
// texgens
if( pStage->texture.texgen == TG_REFLECT_CUBE )
{
// see if there is also a bump map specified
const shaderStage_t* bumpStage = surf->material->GetBumpStage();
if( bumpStage != NULL )
@ -387,7 +393,59 @@ void idRenderBackend::PrepareStageTexturing( const shaderStage_t* pStage, const
renderProgManager.BindShader_Environment();
}
}
}
else if( pStage->texture.texgen == TG_REFLECT_CUBE2 )
{
idVec4 probeMins, probeMaxs, probeCenter;
probeMins[0] = viewDef->globalProbeBounds[0][0];
probeMins[1] = viewDef->globalProbeBounds[0][1];
probeMins[2] = viewDef->globalProbeBounds[0][2];
probeMins[3] = viewDef->globalProbeBounds.IsCleared() ? 0.0f : 1.0f;
probeMaxs[0] = viewDef->globalProbeBounds[1][0];
probeMaxs[1] = viewDef->globalProbeBounds[1][1];
probeMaxs[2] = viewDef->globalProbeBounds[1][2];
probeMaxs[3] = 0.0f;
idVec3 center = viewDef->globalProbeBounds.GetCenter();
probeCenter.Set( center.x, center.y, center.z, 1.0f );
SetVertexParm( RENDERPARM_WOBBLESKY_X, probeMins.ToFloatPtr() );
SetVertexParm( RENDERPARM_WOBBLESKY_Y, probeMaxs.ToFloatPtr() );
SetVertexParm( RENDERPARM_WOBBLESKY_Z, probeCenter.ToFloatPtr() );
// specular cubemap blend weights
renderProgManager.SetUniformValue( RENDERPARM_LOCALLIGHTORIGIN, viewDef->radianceImageBlends.ToFloatPtr() );
// see if there is also a bump map specified
const shaderStage_t* bumpStage = surf->material->GetBumpStage();
if( bumpStage != NULL )
{
// per-pixel reflection mapping with bump mapping
GL_SelectTexture( 0 );
bumpStage->texture.image->Bind();
GL_SelectTexture( 1 );
viewDef->radianceImages[0]->Bind();
GL_SelectTexture( 2 );
viewDef->radianceImages[1]->Bind();
GL_SelectTexture( 3 );
viewDef->radianceImages[2]->Bind();
GL_SelectTexture( 0 );
if( surf->jointCache )
{
renderProgManager.BindShader_BumpyEnvironment2Skinned();
}
else
{
renderProgManager.BindShader_BumpyEnvironment2();
}
}
}
else if( pStage->texture.texgen == TG_SKYBOX_CUBE )
{
@ -518,7 +576,7 @@ void idRenderBackend::FinishStageTexturing( const shaderStage_t* pStage, const d
GL_SelectTexture( 0 );
}
if( pStage->texture.texgen == TG_REFLECT_CUBE )
if( pStage->texture.texgen == TG_REFLECT_CUBE || pStage->texture.texgen == TG_REFLECT_CUBE2 )
{
// see if there is also a bump map specified
const shaderStage_t* bumpStage = surf->material->GetBumpStage();
@ -531,6 +589,7 @@ void idRenderBackend::FinishStageTexturing( const shaderStage_t* pStage, const d
{
// per-pixel reflection mapping without bump mapping
}
renderProgManager.Unbind();
}
}

View file

@ -823,6 +823,9 @@ enum bindingLayoutType_t
BINDING_LAYOUT_NORMAL_CUBE,
BINDING_LAYOUT_NORMAL_CUBE_SKINNED,
BINDING_LAYOUT_OCTAHEDRON_CUBE,
BINDING_LAYOUT_OCTAHEDRON_CUBE_SKINNED,
// NO GPU SKINNING ANYMORE
BINDING_LAYOUT_POST_PROCESS_INGAME,
BINDING_LAYOUT_POST_PROCESS_FINAL,

View file

@ -368,6 +368,24 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
skinningLayout, normalCubeBindingLayout, samplerOneBindingLayout
};
auto octahedronCubeBindingLayoutDesc = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::Pixel )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal map
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // radiance cube map 1
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // radiance cube map 2
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ); // radiance cube map 3
auto octahedronCubeBindingLayout = device->createBindingLayout( octahedronCubeBindingLayoutDesc );
bindingLayouts[BINDING_LAYOUT_OCTAHEDRON_CUBE] =
{
uniformsLayout, octahedronCubeBindingLayout, samplerTwoBindingLayout
};
bindingLayouts[BINDING_LAYOUT_OCTAHEDRON_CUBE_SKINNED] =
{
skinningLayout, octahedronCubeBindingLayout, samplerTwoBindingLayout
};
auto binkVideoBindingLayout = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( renderParmLayoutItem )
@ -538,6 +556,8 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
{ BUILTIN_ENVIRONMENT_SKINNED, "builtin/legacy/environment", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true , SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT_SKINNED },
{ BUILTIN_BUMPY_ENVIRONMENT, "builtin/legacy/bumpyenvironment", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_NORMAL_CUBE },
{ BUILTIN_BUMPY_ENVIRONMENT_SKINNED, "builtin/legacy/bumpyenvironment", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_NORMAL_CUBE_SKINNED },
{ BUILTIN_BUMPY_ENVIRONMENT2, "builtin/legacy/bumpyenvironment2", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_OCTAHEDRON_CUBE },
{ BUILTIN_BUMPY_ENVIRONMENT2_SKINNED, "builtin/legacy/bumpyenvironment2", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_OCTAHEDRON_CUBE_SKINNED },
{ BUILTIN_DEPTH, "builtin/depth", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_CONSTANT_BUFFER_ONLY },
{ BUILTIN_DEPTH_SKINNED, "builtin/depth", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_CONSTANT_BUFFER_ONLY_SKINNED },

View file

@ -353,10 +353,13 @@ enum
BUILTIN_DEBUG_OCTAHEDRON,
BUILTIN_DEBUG_OCTAHEDRON_SKINNED,
// RB end
BUILTIN_ENVIRONMENT,
BUILTIN_ENVIRONMENT_SKINNED,
BUILTIN_BUMPY_ENVIRONMENT,
BUILTIN_BUMPY_ENVIRONMENT_SKINNED,
BUILTIN_BUMPY_ENVIRONMENT2, // RB
BUILTIN_BUMPY_ENVIRONMENT2_SKINNED, // RB
BUILTIN_DEPTH,
BUILTIN_DEPTH_SKINNED,
@ -774,6 +777,16 @@ public:
BindShader_Builtin( BUILTIN_BUMPY_ENVIRONMENT_SKINNED );
}
void BindShader_BumpyEnvironment2()
{
BindShader_Builtin( BUILTIN_BUMPY_ENVIRONMENT2 );
}
void BindShader_BumpyEnvironment2Skinned()
{
BindShader_Builtin( BUILTIN_BUMPY_ENVIRONMENT2_SKINNED );
}
void BindShader_Depth()
{
BindShader_Builtin( BUILTIN_DEPTH );

View file

@ -0,0 +1,124 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "global_inc.hlsl"
// *INDENT-OFF*
Texture2D t_NormalMap : register( t0 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap1 : register( t1 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap2 : register( t2 VK_DESCRIPTOR_SET( 1 ) );
Texture2D t_RadianceCubeMap3 : register( t3 VK_DESCRIPTOR_SET( 1 ) );
SamplerState s_Material : register( s0 VK_DESCRIPTOR_SET( 2 ) );
SamplerState s_LinearClamp : register( s1 VK_DESCRIPTOR_SET( 2 ) );
struct PS_IN
{
float4 position : SV_Position;
float2 texcoord0 : TEXCOORD0_centroid;
float3 texcoord1 : TEXCOORD1_centroid;
float3 texcoord2 : TEXCOORD2_centroid;
float3 texcoord3 : TEXCOORD3_centroid;
float3 texcoord4 : TEXCOORD4_centroid;
float4 color : COLOR0;
};
struct PS_OUT
{
float4 color : SV_Target0;
};
// *INDENT-ON*
void main( PS_IN fragment, out PS_OUT result )
{
float4 bump = t_NormalMap.Sample( s_Material, fragment.texcoord0 ) * 2.0f - 1.0f;
// RB begin
float3 localNormal;
#if defined(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;
globalNormal.x = dot3( localNormal, fragment.texcoord2 );
globalNormal.y = dot3( localNormal, fragment.texcoord3 );
globalNormal.z = dot3( localNormal, fragment.texcoord4 );
float3 globalEye = normalize( fragment.texcoord1 );
float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );
reflectionVector = ( reflectionVector * 2.0f ) - globalEye;
#if 0
// parallax box correction using portal area bounds
float hitScale = 0.0;
float3 bounds[2];
bounds[0].x = rpWobbleSkyX.x;
bounds[0].y = rpWobbleSkyX.y;
bounds[0].z = rpWobbleSkyX.z;
bounds[1].x = rpWobbleSkyY.x;
bounds[1].y = rpWobbleSkyY.y;
bounds[1].z = rpWobbleSkyY.z;
// global fragment position
float3 rayStart = fragment.texcoord7.xyz;
// we can't start inside the box so move this outside and use the reverse path
rayStart += reflectionVector * 10000.0;
// only do a box <-> ray intersection test if we use a local cubemap
if( ( rpWobbleSkyX.w > 0.0 ) && AABBRayIntersection( bounds, rayStart, -reflectionVector, hitScale ) )
{
float3 hitPoint = rayStart - reflectionVector * hitScale;
// rpWobbleSkyZ is cubemap center
reflectionVector = hitPoint - rpWobbleSkyZ.xyz;
}
#endif
//float4 envMap = t_CubeMap.Sample( samp0, reflectionVector );
float2 normalizedOctCoord = octEncode( reflectionVector );
float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + _float2( 1.0 ) ) * 0.5;
const float mip = 0;
float3 radiance = t_RadianceCubeMap1.SampleLevel( s_LinearClamp, normalizedOctCoordZeroOne, mip ).rgb * rpLocalLightOrigin.x;
radiance += t_RadianceCubeMap2.SampleLevel( s_LinearClamp, normalizedOctCoordZeroOne, mip ).rgb * rpLocalLightOrigin.y;
radiance += t_RadianceCubeMap3.SampleLevel( s_LinearClamp, normalizedOctCoordZeroOne, mip ).rgb * rpLocalLightOrigin.z;
result.color = float4( sRGBToLinearRGB( radiance.xyz ), 1.0f ) * fragment.color;
}

View file

@ -0,0 +1,179 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "global_inc.hlsl"
// *INDENT-OFF*
#if USE_GPU_SKINNING
StructuredBuffer<float4> matrices : register(t11);
#endif
struct VS_IN
{
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float4 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR0;
float4 color2 : COLOR1;
};
struct VS_OUT
{
float4 position : SV_Position;
float2 texcoord0 : TEXCOORD0_centroid;
float3 texcoord1 : TEXCOORD1_centroid;
float3 texcoord2 : TEXCOORD2_centroid;
float3 texcoord3 : TEXCOORD3_centroid;
float3 texcoord4 : TEXCOORD4_centroid;
float4 color : COLOR0;
};
// *INDENT-ON*
void main( VS_IN vertex, out VS_OUT result )
{
#if USE_GPU_SKINNING
float4 vNormal = vertex.normal * 2.0 - 1.0;
float4 vTangent = vertex.tangent * 2.0 - 1.0;
float3 vBinormal = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
//--------------------------------------------------------------
// GPU transformation of the normal / binormal / bitangent
//
// multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )
//--------------------------------------------------------------
const float w0 = vertex.color2.x;
const float w1 = vertex.color2.y;
const float w2 = vertex.color2.z;
const float w3 = vertex.color2.w;
float4 matX, matY, matZ; // must be float4 for vec4
int joint = int( vertex.color.x * 255.1 * 3.0 );
matX = matrices[int( joint + 0 )] * w0;
matY = matrices[int( joint + 1 )] * w0;
matZ = matrices[int( joint + 2 )] * w0;
joint = int( vertex.color.y * 255.1 * 3.0 );
matX += matrices[int( joint + 0 )] * w1;
matY += matrices[int( joint + 1 )] * w1;
matZ += matrices[int( joint + 2 )] * w1;
joint = int( vertex.color.z * 255.1 * 3.0 );
matX += matrices[int( joint + 0 )] * w2;
matY += matrices[int( joint + 1 )] * w2;
matZ += matrices[int( joint + 2 )] * w2;
joint = int( vertex.color.w * 255.1 * 3.0 );
matX += matrices[int( joint + 0 )] * w3;
matY += matrices[int( joint + 1 )] * w3;
matZ += matrices[int( joint + 2 )] * w3;
float3 normal;
normal.x = dot3( matX, vNormal );
normal.y = dot3( matY, vNormal );
normal.z = dot3( matZ, vNormal );
normal = normalize( normal );
float3 tangent;
tangent.x = dot3( matX, vTangent );
tangent.y = dot3( matY, vTangent );
tangent.z = dot3( matZ, vTangent );
tangent = normalize( tangent );
float3 binormal;
binormal.x = dot3( matX, vBinormal );
binormal.y = dot3( matY, vBinormal );
binormal.z = dot3( matZ, vBinormal );
binormal = normalize( binormal );
float4 modelPosition;
modelPosition.x = dot4( matX, vertex.position );
modelPosition.y = dot4( matY, vertex.position );
modelPosition.z = dot4( matZ, vertex.position );
modelPosition.w = 1.0;
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.texcoord0 = vertex.texcoord.xy;
float4 toEye = rpLocalViewOrigin - modelPosition;
result.texcoord1.x = dot3( toEye, rpModelMatrixX );
result.texcoord1.y = dot3( toEye, rpModelMatrixY );
result.texcoord1.z = dot3( toEye, rpModelMatrixZ );
result.texcoord2.x = dot3( tangent, rpModelMatrixX );
result.texcoord3.x = dot3( tangent, rpModelMatrixY );
result.texcoord4.x = dot3( tangent, rpModelMatrixZ );
result.texcoord2.y = dot3( binormal, rpModelMatrixX );
result.texcoord3.y = dot3( binormal, rpModelMatrixY );
result.texcoord4.y = dot3( binormal, rpModelMatrixZ );
result.texcoord2.z = dot3( normal, rpModelMatrixX );
result.texcoord3.z = dot3( normal, rpModelMatrixY );
result.texcoord4.z = dot3( normal, rpModelMatrixZ );
#else
float4 normal = vertex.normal * 2.0 - 1.0;
float4 tangent = vertex.tangent * 2.0 - 1.0;
float3 binormal = cross( normal.xyz, tangent.xyz ) * tangent.w;
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.texcoord0 = vertex.texcoord.xy;
float4 toEye = rpLocalViewOrigin - vertex.position;
result.texcoord1.x = dot3( toEye, rpModelMatrixX );
result.texcoord1.y = dot3( toEye, rpModelMatrixY );
result.texcoord1.z = dot3( toEye, rpModelMatrixZ );
result.texcoord2.x = dot3( tangent, rpModelMatrixX );
result.texcoord3.x = dot3( tangent, rpModelMatrixY );
result.texcoord4.x = dot3( tangent, rpModelMatrixZ );
result.texcoord2.y = dot3( binormal, rpModelMatrixX );
result.texcoord3.y = dot3( binormal, rpModelMatrixY );
result.texcoord4.y = dot3( binormal, rpModelMatrixZ );
result.texcoord2.z = dot3( normal, rpModelMatrixX );
result.texcoord3.z = dot3( normal, rpModelMatrixY );
result.texcoord4.z = dot3( normal, rpModelMatrixZ );
#endif
result.position.xyz = psxVertexJitter( result.position );
result.color = rpColor;
}

View file

@ -34,6 +34,8 @@ builtin/legacy/environment.vs.hlsl -T vs -D USE_GPU_SKINNING={0,1}
builtin/legacy/environment.ps.hlsl -T ps -D USE_GPU_SKINNING={0,1}
builtin/legacy/bumpyenvironment.vs.hlsl -T vs -D USE_GPU_SKINNING={0,1}
builtin/legacy/bumpyenvironment.ps.hlsl -T ps -D USE_GPU_SKINNING={0,1}
builtin/legacy/bumpyenvironment2.vs.hlsl -T vs -D USE_GPU_SKINNING={0,1}
builtin/legacy/bumpyenvironment2.ps.hlsl -T ps -D USE_GPU_SKINNING={0,1}
builtin/legacy/skybox.vs.hlsl -T vs
builtin/legacy/skybox.ps.hlsl -T ps
builtin/legacy/wobblesky.vs.hlsl -T vs