This article or section needs to be cleaned up to conform to a higher standard of quality because:Перевод можно было сформулировать лучше
For help, see the VDC Editing Help and Wikipedia cleanup process. Also, remember to check for any notes left by the tagger at this article's talk page.
Эта статья покажет вам как реализовать динамическое небо в вашем
Source 2013 моде.
Примечание:Это руководство использует код из отмененного мода Vance
Предупреждение:Этот шейдер очень требовательный и снижает частоту кадров в секунду на 25-40. Поэтому лучше использовать его только на мощных компьютерах
Требования
- Умение компилировать шейдеры.
- Умение компилировать решения.
Реализация
Прежде чем что-то делать, нам нужно скачать файлы. Они внутри zip-архива.
Когда вы загрузите zip-файл, извлеките файлы из shaders в: 
src/materialsystem/stdshaders/
, а файлы из code в: 
src/game/
Откройте 
src/game/client/client_base.vpc
Перейдите к строке $File "$SRCDIR\game\client\c_vote_controller.cpp" и под ней добавьте:
$File "c_env_skydome.cpp"
$File "c_env_skydome.h"
Далее откройте 
src/game/server/server_base.vpc
и под $File "$SRCDIR\game\server\vote_controller.cpp" добавьте:
И после этого, пересоберите свое 
games.sln
решение.
Теперь мы можем перейти к реализации кода отрисовки.
Код отрисовки
Сначала нам нужно отредактировать код клиента для динамического неба.
Откройте 
src/game/client/view.cpp
В функции void CViewRender::Init( void ), под m_ModulateSingleColor.Init( "engine/modulatesinglecolor", TEXTURE_GROUP_OTHER ); добавьте:
m_SkydomeMaterial.Init("shaders/skydome", TEXTURE_GROUP_MODEL);
Теперь откройте 
src/game/client/viewrender.h
И под функцией void SetWaterOverlayMaterial( IMaterial *pMaterial ) добавьте:
void DrawSky(const CViewSetup& view);
Найдите CMaterialReference m_UnderWaterOverlayMaterial; и под этим добавьте:
CMaterialReference m_SkydomeMaterial;
Теперь нам нужно создать купол. Чтобы сделать это, откройте 
src/game/client/viewrender.cpp
Под #include "sourcevr/isourcevirtualreality.h" добавьте:
#include "c_env_skydome.h"
Примечание:Это должно исправить все ошибки с отсутствием определения для g_pSkyDome
Под функцией void CViewRender::DrawViewModels( const CViewSetup &view, bool drawViewmodel ) добавьте:
void CViewRender::DrawSky(const CViewSetup& view)
{
float flRadius = 32.0f;
int nTheta = 8;
int nPhi = 8;
CMatRenderContextPtr pRenderContext(materials);
pRenderContext->OverrideDepthEnable(true, false);
int nTriangles = 2 * nTheta * (nPhi - 1); // Two extra degenerate triangles per row (except the last one)
int nIndices = 2 * (nTheta + 1) * (nPhi - 1);
pRenderContext->Bind(m_SkydomeMaterial);
CMeshBuilder meshBuilder;
IMesh* pMesh = pRenderContext->GetDynamicMesh();
meshBuilder.Begin(pMesh, MATERIAL_TRIANGLE_STRIP, nTriangles, nIndices);
//
// Build the index buffer.
//
int i, j;
for (i = 0; i < nPhi; ++i)
{
for (j = 0; j < nTheta; ++j)
{
float u = j / (float)(nTheta - 1);
float v = i / (float)(nPhi - 1);
float theta = 2.0f * M_PI * u;
float phi = M_PI * v;
Vector vecPos;
vecPos.x = flRadius * sin(phi) * cos(theta);
vecPos.y = flRadius * sin(phi) * sin(theta);
vecPos.z = flRadius * cos(phi);
Vector vecNormal = vecPos;
VectorNormalize(vecNormal);
meshBuilder.Position3f(vecPos.x, vecPos.y, vecPos.z);
meshBuilder.AdvanceVertex();
}
}
//
// Emit the triangle strips.
//
int idx = 0;
for ( i = 0; i < nPhi - 1; ++i )
{
for ( j = 0; j < nTheta; ++j )
{
idx = nTheta * i + j;
meshBuilder.Index( idx );
meshBuilder.AdvanceIndex();
meshBuilder.Index( idx + nTheta );
meshBuilder.AdvanceIndex();
}
//
// Emit a degenerate triangle to skip to the next row without
// a connecting triangle.
//
if ( i < nPhi - 2 )
{
meshBuilder.Index( idx + nTheta );
meshBuilder.AdvanceIndex();
meshBuilder.Index( ( i + 1 ) * nTheta );
meshBuilder.AdvanceIndex();
}
}
pRenderContext->MatrixMode(MATERIAL_MODEL);
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->Translate(view.origin.x, view.origin.y, view.origin.z);
meshBuilder.End();
pMesh->Draw();
pRenderContext->MatrixMode(MATERIAL_MODEL);
pRenderContext->PopMatrix();
pRenderContext->OverrideDepthEnable(false, true);
}
Теперь для включения и отключения отрисовки вам нужно перейти к функции void CRendering3dView::DrawWorld( float waterZAdjust ) и
выше unsigned long engineFlags = BuildEngineDrawWorldListFlags( m_DrawFlags ); добавить:
if ((m_DrawFlags & DF_DRAWSKYBOX) && (g_pSkyDome && g_pSkyDome->IsDynamicSkyEnabled()))
{
m_DrawFlags &= ~DF_DRAWSKYBOX; // dont render engine sky, we have our own sky now
m_pMainView->DrawSky(*this);
}
Шейдеры
Примечание:Удалите все файлы из 
stdshader_dx9_30.txt
и убедитесь, что в вашем 
stdshader_dx9_30.txt
файле есть только skydome_ps30 и skydome_vs30, чтобы ускорить компиляцию шейдеров (НЕ ЗАБУДЬТЕ ОЧИСТИТЬ 
stdshader_dx9_20b.txt
)
А теперь откройте 
game_shader_dx9_base.vpc
И под $File "screenspace_general.cpp" добавьте:
$File "skydome_atmosphere.cpp"
$File "skydome_atmosphere_helper.cpp"
$File "skydome_atmosphere_helper.h"
Скомпилируйте шейдер динамического неба и пересоберите ваше решение.
Хорошо, а сейчас нам нужно сделать наше динамическое небо доступным через
Hammer.
Для этого вам понадобиться пользовательский fgd(en) файл.
@include "halflife2.fgd"
//-------------------------------------------------------------------------
// Environment (Global Light copy, also handles dynamic sky)
//-------------------------------------------------------------------------
@PointClass base(Targetname) iconsprite("editor/shadow_control.vmt") = env_skydome :
"An entity to control the sky dynamic sky."
[
sunpos(vector) : "Pitch Yaw Roll (Y Z X)" : "1 1 1 5" : "This is the light cast direction. Pitch is rotation around the Y axis, yaw is the rotation around the Z axis, and roll is the rotation around the X axis. THE LAST 0 IS FOR HOW BRIGHT THE SUN IS!!!!"
coverage(float) : "Coverage of clouds" : "0.50" : "How much of the clouds cover the sky"
thickness(float) : "Thickness of clouds" : "3" : "How thicker, how weirder the sky looks, DON'T GO ABOVE 100!"
windspeed(string) : "Dir and clearity of wind (X Y Z Clear)" : "0 0 0 5" : "Using stuff like .01 is a good habit as it is the most realistic"
// Inputs
input SetSunPos(vector) : "Set the position of the sun."
input SetWindSpeed(vector) : "Set the ambient color."
input InputSetThicknes(float) : "Set the thickness of the clouds."
input InputSetCoverage(float) : "Set how many clouds cover the sky."
input EnableDynamicSky(integer) : "Set if the sky is on or off"
]
Заключение
Теперь вам нужна последняя деталь и это - материал.
Перейдите в вашу директорию 
materials
и создайте поддиректорию с названием 
shaders
После этого, создайте файл 
skydome.vmt
и вставьте это внутрь:
"SKYDOME_ATMOSPHERE"
{
"$lut" "skybox/sky_fake_white"
"$ALPHATESTREFERENCE" 1
}
Создайте карту с сущностью env_skydome и вот оно! Теперь в вашем моде должно быть динамическое небо.