Difference between revisions of "Parallax Corrected Cubemaps:fr"

From Valve Developer Community
Jump to: navigation, search
(Ajout et correction de liens)
(Moved to rootpage/fr)
(Tag: Replaced)
 
Line 1: Line 1:
{{lang|Parallax Corrected Cubemaps|title=Cubemaps Corrigés en Fonction de la Parallaxe}}
+
{{Delete|reason=moved}}
 
 
== Qu'est-ce Que C'est ? ==
 
 
 
Par défaut, Les cubemaps du [[Source|moteur Source]] {{en}} sont naïvement reflétés sur le terrain et ne suivent pas la perspective du joueur. Cela provoque une réflexion irréaliste pour la plupart des surfaces. Une solution possible est de corriger la parallaxe des cubemaps en fonction de la position de la caméra du joueur, en utilisant un shader personnalisé et un trigger boîtes de délimitation pour un cubemap. Ce tutoriel, basé directement sur le travail de [https://www.youtube.com/@BMCha1 Brian Charles {{en}}], vous montrera comment faire exactement cela.
 
 
 
La vidéo de Brian Charles qui présente l’avant et l’après de ce tutoriel se trouve ici : [https://www.youtube.com/watch?v=ZH6s1hbwoQQ Parallax Corrected Cubemaps in the Source Engine {{en}}]
 
 
 
== Le Code ==
 
 
 
Avant de démarrer, nous aurons besoin de ce fichier :
 
* [[Parallax Corrected Cubemaps/matrixinvert.h|matrixinvert.h]]
 
 
 
 
 
Que vous mettrez dans '''<[https://github.com/ValveSoftware/source-sdk-2013 répertoire du code src]>/src/utils/vbsp/'''
 
 
 
 
 
Maintenant allons-y, d’accord ?
 
 
 
Aller dans votre '''everything.sln''' solution et ouvert '''cubemap.cpp'''
 
 
 
=== cubemap.cpp ===
 
 
 
Maintenant, ajoutez ceci sous (pas à l’intérieur) la fonction<code>SideHasCubemapAndWasntManuallyReferenced( int iSide )</code> :
 
<source lang="cpp">
 
char *g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES];
 
</source>
 
 
 
Ensuite, juste en dessous, changez la fonction<code>CubeMap_InsertSample( ... )</code>pour ressembler à ceci :
 
<source lang="cpp">
 
void Cubemap_InsertSample( const Vector &origin, int size, char *pParallaxObbStr = "" )
 
</source>
 
 
 
Et à l’intérieur de cette fonction, en haut, ajoutez ceci :
 
<source lang="cpp">
 
g_pParallaxObbStrs[g_nCubemapSamples] = pParallaxObbStr;
 
</source>
 
 
 
Maintenant descendre à la fonction<code>PatchEnvmapForMaterialAndDependents( ... )</code>et le changer pour ressembler à ceci :
 
<source lang="cpp">
 
static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture, const char *pParallaxObbMatrix = "" )
 
</source>
 
 
 
Dans la même fonction, faites défiler légèrement vers le bas jusqu’à la condition<code>if ( pDependentMaterial )</code>et changer la ligne en ceci :
 
<source lang="cpp">
 
bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture, pParallaxObbMatrix );
 
</source>
 
 
 
Faites défiler un peu vers le bas jusqu’à trouver cette ligne :
 
<source lang="cpp">
 
MaterialPatchInfo_t pPatchInfo[2];
 
</source>
 
 
 
Puis changez 2 en 6, comme ça :
 
<source lang="cpp">
 
MaterialPatchInfo_t pPatchInfo[6];
 
</source>
 
 
 
Faites un autre petit défilement vers le bas, et au-dessus de cette ligne :
 
<source lang="cpp">
 
char pDependentPatchedMaterialName[1024];
 
</source>
 
 
 
Ajouter :
 
<source lang="cpp">
 
// Parallax cubemap matrix
 
CUtlVector<char *> matRowList;
 
if ( pParallaxObbMatrix[0] != '\0' )
 
{
 
V_SplitString( pParallaxObbMatrix, ";", matRowList );
 
 
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB1";
 
pPatchInfo[nPatchCount].m_pValue = matRowList[0];
 
++nPatchCount;
 
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB2";
 
pPatchInfo[nPatchCount].m_pValue = matRowList[1];
 
++nPatchCount;
 
pPatchInfo[nPatchCount].m_pKey = "$envMapParallaxOBB3";
 
pPatchInfo[nPatchCount].m_pValue = matRowList[2];
 
++nPatchCount;
 
pPatchInfo[nPatchCount].m_pKey = "$envMapOrigin";
 
pPatchInfo[nPatchCount].m_pValue = matRowList[3];
 
++nPatchCount;
 
}
 
</source>
 
 
 
Au bas de la fonction, vous trouverez cette ligne :
 
<source lang="cpp">
 
CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_REPLACE );
 
</source>
 
 
 
Changez-le en ceci :
 
<source lang="cpp">
 
CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_INSERT );
 
</source>
 
 
 
Puis ci-dessous qui ajoutent ceci :
 
<source lang="cpp">
 
// Clean up parallax stuff
 
matRowList.PurgeAndDeleteElements();
 
</source>
 
 
 
Faire défiler jusqu’à la fonction<code>Cubemap_CreateTexInfo( ... )</code>et le changer en ceci :
 
<source lang="cpp">
 
static int Cubemap_CreateTexInfo( int originalTexInfo, int origin[3], int cubemapIndex )
 
</source>
 
 
 
Faites défiler un peu vers le bas dans cette fonction et trouvez cette ligne :
 
<source lang="cpp">
 
GeneratePatchedName( "c", info, false, pTextureName, 1024 );
 
</source>
 
 
 
Maintenant en dessous de cette ligne ajouter ceci :
 
<source lang="cpp">
 
// Append origin info if this cubemap has a parallax OBB
 
char originAppendedString[1024] = "";
 
if ( g_pParallaxObbStrs[cubemapIndex][0] != '\0' )
 
{
 
Q_snprintf( originAppendedString, 1024, "%s;[%d %d %d]", g_pParallaxObbStrs[cubemapIndex], origin[0], origin[1], origin[2] );
 
}
 
</source>
 
 
 
Un peu plus bas, tu verras c'est condition ''si'' :
 
<source lang="cpp">
 
if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName ) )
 
</source>
 
 
 
Remplacez-le par :
 
<source lang="cpp">
 
if ( !PatchEnvmapForMaterialAndDependents( pMaterialName, info, pTextureName, originAppendedString ) )
 
</source>
 
 
 
Faites défiler la page jusqu’à trouver la fonction<code>Cubemap_FixupBrushSidesMaterials( void )</code>, et à l’intérieur de lui trouver cette ligne :
 
<source lang="cpp">
 
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin );
 
</source>
 
 
 
Changez-le en ceci :
 
<source lang="cpp">
 
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[cubemapID].origin, cubemapID );
 
</source>
 
 
 
Faire défiler jusqu’à la fonction<code>Cubemap_AttachDefaultCubemapToSpecularSides( void )</code>, et à l’intérieur de lui trouver cette ligne :
 
<source lang="cpp">
 
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin );
 
</source>
 
 
 
Changez-le en ceci :
 
<source lang="cpp">
 
pSide->texinfo = Cubemap_CreateTexInfo( pSide->texinfo, g_CubemapSamples[iCubemap].origin, iCubemap );
 
</source>
 
 
 
Maintenant, nous en avons fini avec '''cubemap.cpp''', nous pouvons maintenant passer à '''vbsp.h'''
 
 
 
=== vbsp.h ===
 
 
 
Maintenant trouver cette ligne :
 
<source lang="cpp">
 
void Cubemap_InsertSample( const Vector& origin, int size );
 
</source>
 
 
 
Et change ça en ceci :
 
<source lang="cpp">
 
void Cubemap_InsertSample( const Vector &origin, int size, char *pParallaxObbStr );
 
</source>
 
 
 
Et au-dessus de cela ajouter ceci :
 
<source lang="cpp">
 
extern char *g_pParallaxObbStrs[MAX_MAP_CUBEMAPSAMPLES];
 
</source>
 
 
 
Nous en avons terminé avec '''vbsp.h''', Passons maintenant à '''map.cpp'''
 
 
 
=== map.cpp ===
 
 
 
Tout en haut, ajoutez ce qui suit :
 
<source lang="cpp">
 
#include "matrixinvert.h"
 
</source>
 
 
 
puis faites défiler vers le bas jusqu'à la function<code>LoadEntityCallback( ... )</code>, puis à l’intérieur trouver cette ligne :
 
<source lang="cpp">
 
const char *pSideListStr = ValueForKey( mapent, "sides" );
 
</source>
 
 
 
Maintenant en dessous de cette ligne, ajouter :
 
<source lang="cpp">
 
char *pParallaxObbStr = ValueForKey( mapent, "parallaxobb" );
 
</source>
 
 
 
Puis un tout petit peu plus bas trouver cette ligne :
 
<source lang="cpp">
 
Cubemap_InsertSample( mapent->origin, size );
 
</source>
 
 
 
Et change ça en ceci :
 
<source lang="cpp">
 
Cubemap_InsertSample( mapent->origin, size, pParallaxObbStr );
 
</source>
 
 
 
Maintenant sous le parent de la condition if où on est, ajoutez ça :
 
<source lang="cpp">
 
//
 
// parallax_obb brushes are removed after the transformation matrix is found and saved into
 
// the entity's data (ent will be removed after data transferred to patched materials)
 
//
 
if ( !strcmp( "parallax_obb", pClassName ) )
 
{
 
matrix3x4_t obbMatrix, invObbMatrix;
 
SetIdentityMatrix( obbMatrix );
 
SetIdentityMatrix( invObbMatrix );
 
 
 
// Get corner and its 3 edges (scaled, local x, y, and z axes)
 
mapbrush_t *brush = &mapbrushes[mapent->firstbrush];
 
Vector corner, x, y, z;
 
 
 
// Find first valid winding (with these whiles, if not enough valid windings then identity matrix is passed through to VMTs)
 
int i = 0;
 
while ( i < brush->numsides )
 
{
 
winding_t *wind = brush->original_sides[i].winding;
 
if ( !wind )
 
{
 
i++;
 
continue;
 
}
 
 
 
corner = wind->p[0];
 
y = wind->p[1] - corner;
 
z = wind->p[3] - corner;
 
x = CrossProduct( y, z ).Normalized();
 
 
 
i++;
 
break;
 
}
 
 
 
// Skip second valid winding (opposite face from first, unusable for finding Z's length)
 
while ( i < brush->numsides )
 
{
 
winding_t *wind = brush->original_sides[i].winding;
 
if ( !wind )
 
{
 
i++;
 
continue;
 
}
 
i++;
 
break;
 
}
 
 
 
// Find third valid winding
 
while ( i < brush->numsides )
 
{
 
winding_t *wind = brush->original_sides[i].winding;
 
if ( !wind )
 
{
 
i++;
 
continue;
 
}
 
 
 
// Find length of X
 
// Start with diagonal, then scale X by the projection of diag onto X
 
Vector diag = wind->p[0] - wind->p[2];
 
x *= abs( DotProduct( diag, x ) );
 
 
 
// Build transformation matrix (what is needed to turn a [0,0,0] - [1,1,1] cube into this brush)
 
MatrixSetColumn( x, 0, obbMatrix );
 
MatrixSetColumn( y, 1, obbMatrix );
 
MatrixSetColumn( z, 2, obbMatrix );
 
MatrixSetColumn( corner, 3, obbMatrix );
 
 
 
// Find inverse (we need the world to local matrix, "transformationmatrix" is kind of a misnomer)
 
MatrixInversion( obbMatrix, invObbMatrix );
 
break;
 
}
 
 
char szMatrix[1024];
 
Q_snprintf( szMatrix, 1024, "[%f %f %f %f];[%f %f %f %f];[%f %f %f %f]", invObbMatrix[0][0], invObbMatrix[0][1], invObbMatrix[0][2], invObbMatrix[0][3], invObbMatrix[1][0], invObbMatrix[1][1], invObbMatrix[1][2], invObbMatrix[1][3], invObbMatrix[2][0], invObbMatrix[2][1], invObbMatrix[2][2], invObbMatrix[2][3] );
 
SetKeyValue( mapent, "transformationmatrix", szMatrix );
 
 
 
return ( ChunkFile_Ok );
 
}
 
</source>
 
 
 
Faites maintenant défiler jusqu’à la fonction<code>LoadMapFile( ... )</code>, à l’intérieur, défilez vers le bas jusqu’à ce que vous trouviez cette ligne :
 
<source lang="cpp">
 
if ((eResult == ChunkFile_Ok) || (eResult == ChunkFile_EOF))
 
</source>
 
 
 
Maintenant au-dessus de cette ligne, ajoutez ceci :
 
<source lang="cpp">
 
// Fill out parallax obb matrix array
 
for ( int i = 0; i < g_nCubemapSamples; i++ )
 
{
 
if ( g_pParallaxObbStrs[i][0] != '\0' )
 
{
 
entity_t *obbEnt = EntityByName( g_pParallaxObbStrs[i] );
 
g_pParallaxObbStrs[i] = ValueForKey( obbEnt, "transformationmatrix" );
 
}
 
}
 
 
 
// Remove parallax_obb entities (in a nice slow linear search)
 
for ( int i = 0; i < g_MainMap->num_entities; i++ )
 
{
 
entity_t *mapent = &g_MainMap->entities[i];
 
const char *pClassName = ValueForKey( mapent, "classname" );
 
if ( !strcmp( "parallax_obb", pClassName ) )
 
{
 
mapent->numbrushes = 0;
 
mapent->epairs = NULL;
 
}
 
}
 
</source>
 
 
 
Et ça devrait être bon ! Essayez de compiler le projet VBSP, il devrait compiler sans aucune erreur.
 
 
 
Maintenant tout ce qui reste est de déplacer le fraîchement compilé fichier '''vbsp.exe''' à votre répertoire '''bin/''' de votre jeu.
 
 
 
== Les Shaders ==
 
 
 
Maintenant, le truc '''fun''' : l'édition de shader! Les Cubemaps corrigés en fonction de la parallaxe qui seront désormais intégrés dans vos matériaux ont besoin d'un shader [[LightmappedGeneric]] {{en}} personnalisé pour qu’ils soient correctement affichés.
 
 
 
Commençons simplement. Pour éditer les shaders, vous devrez ouvrir votre fichier '''everything.sln'''. Points bonus si vous l’aviez déjà ouvert !
 
 
 
{{warning:fr|Cette section est la plus longue et la plus fastidieuse, juste en raison de la nécessité de compiler un '''LightmappedGeneric''' shader personnalisé, qui peut prendre jusqu’à 30 minutes par compilation, même sur des ordinateurs costauds!}}
 
 
 
{{note:fr|Il est recommandé de suivre le tutoriel [[Shader Authoring]] {{en}} pour se configurer avec le merveilleux DirectX 2008 SDK, et une sensation de compilation de shaders. Ce tutoriel suppose que vous êtes à l’aise avec cela.}}
 
 
 
{{warning:fr|Valve n’aime pas quand vous surchargez les ombres par défaut dans le projet SDK 2013. Par conséquent, nous allons créer des shaders identiques à celui de '''LightmappedGeneric''', juste avec le préfixe '''SDK_'''. prefix.}}
 
 
 
=== Fichiers Shader C++ ===
 
 
 
Tout d’abord, faisons en sorte que le shader '''LightmappedGeneric''' soit familier avec les Boîtes de délimitation pour la parallaxe corrigées que vous avez stocké dans le matériel.
 
 
 
==== lightmappedgeneric_dx9_helper.h ====
 
 
 
Ajouter les lignes suivantes à la fin de la structure<code>LightmappedGeneric_DX9_Vars_t</code>(après le membre<code>int m_nOutlineEnd1;</code>) :
 
<source lang="cpp">
 
// Parallax cubemaps
 
int m_nEnvmapParallaxObb1;
 
int m_nEnvmapParallaxObb2;
 
int m_nEnvmapParallaxObb3;
 
int m_nEnvmapOrigin;
 
</source>
 
 
 
==== lightmappedgeneric_dx9.cpp ====
 
 
 
Comme nous l’avons déjà dit, nous devons transformer cela en un shader SDK, puisque compiler un shader par défaut '''LightmappedGeneric''' fonctionne, mais vous ne pouvez pas l’utiliser dans le jeu. Modifier la ligne :
 
<source lang="cpp">
 
BEGIN_VS_SHADER( LightmappedGeneric,
 
"Help for LightmappedGeneric" )
 
</source>
 
 
 
en ça :
 
<source lang="cpp">
 
BEGIN_VS_SHADER( SDK_LightmappedGeneric, "Help for SDK_LightmappedGeneric" )
 
</source>
 
 
 
Maintenant, nous avons besoin du fichier d’implémentation pour remplir ces paramètres shader. Ajouter les lignes suivantes à l’intérieur du bloc
 
<source lang="cpp">
 
BEGIN_SHADER_PARAMS
 
</source>
 
 
 
en haut de ce fichier, après cette line:
 
<source lang="cpp">
 
SHADER_PARAM( OUTLINEEND1, SHADER_PARAM_TYPE_FLOAT, "0.0", "outer end value for outline")
 
</source>
 
 
 
''Ajouter ça :''
 
<source lang="cpp">
 
// Parallax cubemaps
 
SHADER_PARAM( ENVMAPPARALLAXOBB1, SHADER_PARAM_TYPE_VEC4, "[1 0 0 0]", "The first line of the parallax correction OBB matrix" )
 
SHADER_PARAM( ENVMAPPARALLAXOBB2, SHADER_PARAM_TYPE_VEC4, "[0 1 0 0]", "The second line of the parallax correction OBB matrix" )
 
SHADER_PARAM( ENVMAPPARALLAXOBB3, SHADER_PARAM_TYPE_VEC4, "[0 0 1 0]", "The third line of the parallax correction OBB matrix" )
 
SHADER_PARAM( ENVMAPORIGIN, SHADER_PARAM_TYPE_VEC3, "[0 0 0]", "The world space position of the env_cubemap being corrected" )
 
</source>
 
 
 
Si vous avez fait vos devoirs dans la section [[Shader Authoring]] {{en}}, vous saurez qu’il s’agit de définir les paramètres shader à l’intérieur du fichier matériel. Maintenant, attribuons-les aux nouveaux membres de la structure. Dans le même fichier, à l’intérieur de la fonction
 
<source lang="cpp">
 
void SetupVars( LightmappedGeneric_DX9_Vars_t& info )
 
</source>
 
 
 
, ajouter les lignes suivantes à sa fin (après la ligne<code>info.m_nOutlineEnd1 = OUTLINEEND1;</code>):
 
<source lang="cpp">
 
// Parallax cubemaps
 
info.m_nEnvmapParallaxObb1 = ENVMAPPARALLAXOBB1;
 
info.m_nEnvmapParallaxObb2 = ENVMAPPARALLAXOBB2;
 
info.m_nEnvmapParallaxObb3 = ENVMAPPARALLAXOBB3;
 
info.m_nEnvmapOrigin = ENVMAPORIGIN;
 
</source>
 
 
 
Super, maintenant notre code du shader connait nos paramètres patchés. Mais nous devons encore faire des trucs avec eux !
 
 
 
==== lightmappedgeneric_dx9_helper.cpp ====
 
 
 
Comme je l’ai déjà mentionné, nous devons modifier certains préfixes. Pour vos inclusions, changez les lignes :
 
<source lang="cpp">
 
#include "lightmappedgeneric_ps20.inc"
 
#include "lightmappedgeneric_vs20.inc"
 
#include "lightmappedgeneric_ps20b.inc"
 
</source>
 
 
 
en ça :
 
<source lang="cpp">
 
#include "SDK_lightmappedgeneric_ps20.inc"
 
#include "SDK_lightmappedgeneric_vs20.inc"
 
#include "SDK_lightmappedgeneric_ps20b.inc"
 
</source>
 
 
 
Vous allez les générer dans un moment, ne vous inquiétez pas. Mais maintenant cela va causer d’autres problèmes dans le code! Vous devrez remplacer toutes les instances du code du shader par défaut par votre SDK nouvellement copié.
 
 
 
Par exemple,
 
<source lang="cpp">
 
DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
 
</source>
 
 
 
en :
 
<source lang="cpp">
 
DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedgeneric_vs20 );
 
</source>
 
 
 
'''FAITE LE POUR CHAQUE INSTANCE !''' Modifier les importations vous aidera à compiler ce module dans un instant, car les anciens shaders '''lightmappedgeneric_*''' seront soulignés en rouge, pour vous aider à trouver où vous avez manqué un endroit spécifique.
 
 
 
Tout d’abord, faisons une vérification de sécurité. Nous devons nous assurer que nous avons '''tous''' les composants requis pour les Cubemaps Corrigés en Fonction de la Parallaxe fonctionnent correctement. À l'intérieur du
 
<source lang="cpp">
 
void InitParamsLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, LightmappedGeneric_DX9_Vars_t &info )
 
</source>
 
 
 
près du haut de ce fichier, ajoutez les lignes de code suivantes à la fin (vous l’avez deviné), après la ligne<code>InitFloatParam( info.m_nOutlineAlpha, params, 1.0 );</code>:
 
<source lang="cpp">
 
// Parallax cubemaps
 
// Cubemap parallax correction requires all 4 lines (if the 2nd, 3rd, or 4th are undef, undef the first one (checking done on first var)
 
if ( !( params[info.m_nEnvmapParallaxObb2]->IsDefined() && params[info.m_nEnvmapParallaxObb3]->IsDefined() && params[info.m_nEnvmapOrigin]->IsDefined() ) )
 
{
 
params[info.m_nEnvmapParallaxObb1]->SetUndefined();
 
}
 
</source>
 
 
 
Cela permet au code de la correction de parallaxe de ne pas fonctionner s’il y a un problème avec vos matériaux patchés ou quelque chose.
 
 
 
Ensuite, nous devons dire au shader lui-même si le code ci-dessus que nous avons ajouté retourne true, et si oui, pour faire le rendu des Cubemaps Corrigés en Fonction de la Parallaxe. À l'intérieur de la fonction
 
<source lang="cpp">
 
void DrawLightmappedGeneric_DX9_Internal( ... )
 
</source>
 
 
 
, après la line :
 
<source lang="cpp">
 
bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
 
</source>
 
 
 
Ajouter la déclaration booléenne suivante :
 
<source lang="cpp">
 
// Parallax cubemaps
 
bool hasParallaxCorrection = params[info.m_nEnvmapParallaxObb1]->IsDefined();
 
</source>
 
 
 
Maintenant, vérifions ce booléen. Plus bas dans cette fonction gargantuesque, nous devons définir le combo sur le pixel shader. À l'intérieure du bloc :
 
<source lang="cpp">
 
if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
 
</source>
 
 
 
, ajouter la ligne suivante '''AVANT''' la
 
<source lang="cpp">
 
SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20b );
 
</source>
 
 
 
ligne:
 
<source lang="cpp">
 
// Parallax cubemaps enabled for 2_0b and onwards
 
SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, hasParallaxCorrection );
 
</source>
 
 
 
Si vous êtes capable de lire, vous pouvez commencer à réaliser ce que nous allons faire ensuite : depuis Shader Model 2.0 était à la mode pour les jours [[GoldSource|GoldSource]] {{en}}, et quelque chose comme la parallaxe corrigée cubemaps est un peu élevé-technologie pour cela, nous devons l’activer uniquement si la carte graphique fonctionnant sur le moteur prend en charge Shader Model 2.0b (et plus). Donc un peu plus loin dans cette méga-fonction, à l’intérieur de l’instruction<code>else</code>pour le code ci-dessus, '''JUSTE AVANT''' la line<code>SET_STATIC_PIXEL_SHADER( sdk_lightmappedgeneric_ps20 );</code>, ajoutez ce qui suit :
 
<source lang="cpp">
 
// Parallax cubemaps
 
SET_STATIC_PIXEL_SHADER_COMBO( PARALLAXCORRECT, 0 ); // No parallax cubemaps with ps_2_0 :(
 
</source>
 
 
 
Donc maintenant notre pixel shader (que nous modifions dans la section suivante) sait si oui ou non il devrait gérer les Cubemaps Corrigés en Fonction de la Parallaxe.
 
 
 
Enfin, mais certainement pas le moins important (On n’a même pas encore édité le shader !), nous devons envoyer au pixel shader la bonne valeur à utiliser pour afficher nos Cubemaps Corrigés en Fonction de la Parallaxe. Donc, encore plus bas dans cette fonction de merde, JUSTE AVANT la ligne<code>pContextData->m_SemiStaticCmdsOut.End();</code>, ajouter le bloc de code suivant :
 
<source lang="cpp">
 
// Parallax cubemaps
 
if ( hasParallaxCorrection )
 
{
 
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 21, params[info.m_nEnvmapOrigin]->GetVecValue() );
 
 
 
float *vecs[3];
 
vecs[0] = const_cast<float *>( params[info.m_nEnvmapParallaxObb1]->GetVecValue() );
 
vecs[1] = const_cast<float *>( params[info.m_nEnvmapParallaxObb2]->GetVecValue() );
 
vecs[2] = const_cast<float *>( params[info.m_nEnvmapParallaxObb3]->GetVecValue() );
 
float matrix[4][4];
 
for ( int i = 0; i < 3; i++ )
 
{
 
for ( int j = 0; j < 4; j++ )
 
{
 
matrix[i][j] = vecs[i][j];
 
}
 
}
 
matrix[3][0] = matrix[3][1] = matrix[3][2] = 0;
 
matrix[3][3] = 1;
 
pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 22, &matrix[0][0], 4 );
 
}
 
</source>
 
 
 
[https://www.mariomayhem.com/downloads/sounds/super_mario_galaxy_sounds/Mario/Mario4.wav Waouh] ! Maintenant notre shader a les bonnes données. Bon, il est temps de mettre vos 8 chapeaux DirectX, on y va !
 
 
 
=== Les fichiers Shader ===
 
 
 
==== lightmappedgeneric_ps2_3_x.h ====
 
 
 
Maintenant, Je sais ce que tu penses. C’est loin d’être un fichier shader ! C’est un fichu fichier d’en-tête C++ ! Mais ne vous inquiétez pas, ce fichier est inclus dans le fichier suivant que nous modifions, le fichier source shader réel (FXC). Donc tout ce code sera en fait compilé dans le shader, ce qui en fait un shader [[Source|Source]] {{en}} déguisée !
 
 
 
Tout d’abord, déclarons-nous quelques registres à accrocher. Si vous vous demandez pourquoi ce shader ne fonctionne pas avec Shader Model 2.0, voici pourquoi. Dans ce fichier, juste en dessous de ça :
 
<source lang="cpp">
 
const float4 g_ShadowTweaks : register( c19 );
 
</source>
 
 
 
Ajouter ça :
 
<source lang="cpp">
 
// Parallax cubemaps
 
#if ( PARALLAXCORRECT )
 
const float3 g_CubemapPos : register( c21 );
 
const float4x4 g_ObbMatrix : register( c22 ); // Through c25
 
#endif
 
</source>
 
 
 
Ne vous inquiétez pas de cela<code>PARALLAXCORRECT</code>, cela aura un peu de sens.
 
 
 
Maintenant, faisons le calcul principal de shader dont nous avons besoin ! Nous pouvons sauter plus loin dans le dossier, et trouver où les cubemaps sont traités, à l'intérieure du bloc <code>if( bCubemap )</code>, ajouter le bloc de code suivant après la ligne <code>fresnel = fresnel * g_OneMinusFresnelReflection + g_FresnelReflection;</code> :
 
<source lang="cpp">
 
// Parallax correction (2_0b and beyond)
 
// Adapted from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
 
#if !( defined( SHADER_MODEL_PS_1_1 ) || defined( SHADER_MODEL_PS_1_4 ) || defined( SHADER_MODEL_PS_2_0 ) )
 
#if ( PARALLAXCORRECT )
 
float3 worldPos = i.worldPos_projPosZ.xyz;
 
float3 positionLS = mul( float4( worldPos, 1 ), g_ObbMatrix );
 
float3 rayLS = mul( reflectVect, (float3x3)g_ObbMatrix );
 
 
 
float3 firstPlaneIntersect = ( float3( 1.0f, 1.0f, 1.0f ) - positionLS ) / rayLS;
 
float3 secondPlaneIntersect = ( -positionLS ) / rayLS;
 
float3 furthestPlane = max( firstPlaneIntersect, secondPlaneIntersect );
 
float distance = min( furthestPlane.x, min( furthestPlane.y, furthestPlane.z ) );
 
 
 
// Use distance in WS directly to recover intersection
 
float3 intersectPositionWS = worldPos + reflectVect * distance;
 
reflectVect = intersectPositionWS - g_CubemapPos;
 
#endif
 
#endif
 
</source>
 
 
 
Merveilleux. Notre shader va maintenant faire des maths sophistiquées pour mettre en parallèle le cubemap basé sur la position du joueur. Passez au fichier FXC !
 
 
 
==== Un Shader Par Tout Autre Nom ====
 
 
 
Vous devrez ensuite faire une copie de ces fichiers :
 
<source lang="text">
 
lightmappedgeneric_ps2x.fxc
 
lightmappedgeneric_ps11.fxc
 
lightmappedgeneric_vs20.fxc
 
</source>
 
 
 
Puis renommez les copies en :
 
<source lang="text">
 
SDK_lightmappedgeneric_ps2x.fxc
 
SDK_lightmappedgeneric_ps11.fxc
 
SDK_lightmappedgeneric_vs20.fxc
 
</source>
 
 
 
==== SDK_lightmappedgeneric_ps2x.fxc ====
 
 
 
Heck ouais, nous y voilà, édition des fichiers du shader! Je t’avais dit qu’on arriverait ! D’accord, tu es prêt ? Accroche-toi bien, ces modifications sont ''tellement'' dures.
 
 
 
Ajouter la ligne suivante, après<code>// STATIC: "FLASHLIGHT" "0..1" [ps20b] [XBOX]</code>:
 
<source lang="text">
 
// STATIC: "PARALLAXCORRECT" "0..1"
 
</source>
 
 
 
C’est déclarer le combo statique que notre code de la section précédente déclare. Mais attendez, nous avons encore plus!
 
 
 
Nous devons optimiser le shader pour ne pas compiler sous certaines conditions. Par exemple, quand shadercompile travaille sur la version Shader Model 2.0, nous pouvons lui dire de ne pas construire la version avec les Cubemaps Corrigés en Fonction de la Parallaxe à l’intérieur. De même, s’il n’y a même pas un fichu cubemap pour commencer, nous ne voulons pas que le code du correcteur de parallaxe s’exécute ! Donc après la ligne<code>//  SKIP ($DETAIL_BLEND_MODE == 11 ) && ($BUMPMAP != 0 )</code>, ajouter:
 
<source lang="text">
 
// SKIP: $PARALLAXCORRECT && !$CUBEMAP
 
// SKIP: $PARALLAXCORRECT [ps20]
 
</source>
 
 
 
C’est tout ce qu’il y a à dire ! Tu peux ouvrir les yeux maintenant. En fait, j’espère qu’ils étaient ouverts pour tout ce tutoriel, parce que sinon, vous obtiendrez des résultats ''très'' intéressants.
 
 
 
=== Compiler le(s) shader(s) ===
 
 
 
{{note|''Psst, si vous avez besoin d’aide supplémentaire pour cette section, consultez la page [[Source_SDK_2013:_Your_First_Shader|Votre Premier Shader]] {{en}}, c’est une assez bonne ressource pour compiler des shaders !''}}
 
 
 
Maintenant nous devons compiler le shader. Tu as du café à faire ? Un repas à préparer ? T'es amis t'attends sur Fifa ? Bien! Compiler un shader '''LightmappedGeneric''' personnalisé va prendre à peu près ce temps. Chaque fois que vous avez besoin de changer quelque chose avec le shader, il faudra 30 minutes pour le recompiler complètement! J’espère que ça marchera au premier essai.
 
 
 
À l’intérieur de votre fichier '''stdshader_dx9_20b.txt''' (ou de votre jeu personnalisé, je ne juge pas), assurez-vous que les shaders suivantes sont ajoutées :
 
 
 
<source lang="text">
 
SDK_lightmappedgeneric_ps2x.fxc
 
SDK_lightmappedgeneric_ps11.fxc
 
SDK_lightmappedgeneric_vs20.fxc
 
</source>
 
 
 
Maintenant, compilez. Allez faire la tâche dont je vous parlais. Ça va prendre du temps parce que c’est un script Perl compilant l’un des shaders les plus complexes, donc il a beaucoup de combinaisons à passer. Il va utiliser toutes vos ressources, aussi, donc ne soyez pas effrayé. Est-ce l’hiver? (''Pour moi oui (24/12/2022, Joyeux Noël), mais, il ne neige pas?. '''9°C''', tu connais. Même au nord (Grand-Est, pas Lille. tkt)'') Bien, il réchauffera votre chambre. (''Si vous n'avez pas de four pour faire chauffer la volaille du Carrefour, C'est parfait.'')
 
 
 
Une fois terminé, il générera les bons fichiers '''SDK_lightmappedgeneric_*.inc''' que votre code utilise, et vous devriez avoir vos fichiers '''SDK_lightmappedgeneric_*.vcs''' dans le sous-répertoire '''shaders/fxc/'''. Vous pouvez les copier dans le dossier '''shaders/fxc/''' de votre jeu.
 
 
 
Avec vos nouveaux fichiers '''.inc''', vous devriez pouvoir compiler le projet '''game_shader_dx9'''. Assurez-vous que tous les noms correspondent ! Si vous manquez une '''SDK_*''', essayez de chercher le fichier et assurez-vous qu’il est nommé correctement ! Avec le projet compilé, vous aurez un joli '''game_shader_dx9.dll''' à copier dans le dossier ''bin/'' de votre jeu, à côté de votre serveur et des DLL client.
 
 
 
== Et Après ? ==
 
 
 
=== Utilisation du nouveau Shader SDK_LightmappedGeneric  ===
 
 
 
Maintenant, puisque Valve ne permet pas à [https://github.com/ValveSoftware/source-sdk-2013/tree/master/sp la branche SDK 2013] de remplacer le shader par défaut '''LightmappedGeneric''', vous allez devoir soit tronquer le système matériel et remplacer manuellement tous les shaders, soit simplement créer/copier les VMTs qui utilisent le shader.
 
 
 
=== Les fichiers FGD ===
 
 
 
'''parallaxcubes.fgd :'''
 
<source lang="text">
 
@include "YOUR FGD HERE. THIS ONE WILL OVERRIDE THE REGULAR ENV_CUBEMAP ENTITY AND ALSO ADD THE PARALLAX_OBB ENTITY. ONLY INCLUDE THIS ONE IN HAMMER."
 
 
 
@PointClass color(0 0 255) sidelist(sides) iconsprite("editor/env_cubemap.vmt") = env_cubemap :
 
"An entity that creates a sample point for the Cubic Environment Map."
 
[
 
cubemapsize(choices) : "Cubemap Size" : 0 =
 
[
 
0 : "Default"
 
1 : "1x1"
 
2 : "2x2"
 
3 : "4x4"
 
4 : "8x8"
 
5 : "16x16"
 
6 : "32x32"
 
7 : "64x64"
 
8 : "128x128"
 
9 : "256x256"
 
]
 
sides(sidelist) : "Brush faces": : "(Optional) Brushes faces to directly attach to the env_cubemap. Press Pick then click on faces in the 3D View to select them. Use CTRL while clicking to add or remove from the selection."
 
parallaxobb(target_destination) : "Cubemap Bounds" : : "(Optional) assigns this cubemap a bounding box for parallax correction (brush entity tied to parallax_obb)."
 
]
 
 
 
@SolidClass = parallax_obb
 
[
 
targetname(target_source) : "Name" : : "The name that other entities refer to this entity by."
 
]
 
</source>
 
 
 
== Conclusion ==
 
 
 
Et c’est tout, essayez de lancer votre mod pour voir si ça marche !
 
 
 
Ceci n’est actuellement testé que sur [https://github.com/ValveSoftware/source-sdk-2013/tree/master/sp la branche SP de Source SDK 2013]. [https://github.com/ValveSoftware/source-sdk-2013/tree/master/mp La branche MP] et [[Source SDK Base 2007|Source SDK 2007]] ne sont toujours pas testés au moment de la rédaction de cet article.
 
 
 
[[Category:Programming:fr|Programming:fr]]
 
[[Category:Shaders|Shaders]]
 
[[Category:Free source code]]
 

Latest revision as of 04:21, 10 May 2023

Warning icon.png
This article has been marked as a candidate for speedy deletion because it has moved, and no longer linked to.
If you object to this decision, then please discuss why hereIf this page doesn't meet the criteria for speedy deletion, then please remove this notice, but do not remove it from pages that you have created yourself
Administrators - Remember to check if anything links here and the page history (last edit) before deleting.