mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-25 13:31:15 +00:00
added pre-pass w/ normals, unified clip plane generation
motion vectors to be done later
This commit is contained in:
parent
7fab6ea376
commit
0cae0a9545
23 changed files with 563 additions and 115 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -57,6 +57,7 @@ struct Tessellator
|
|||
enum Id
|
||||
{
|
||||
None,
|
||||
Prepass,
|
||||
Opaque,
|
||||
Transp,
|
||||
Count
|
||||
|
@ -90,6 +91,25 @@ struct PSOCache
|
|||
uint32_t entryCount = 1; // we treat index 0 as invalid
|
||||
};
|
||||
|
||||
struct Prepass
|
||||
{
|
||||
void Init();
|
||||
void Draw(const drawSceneViewCommand_t& cmd);
|
||||
void ProcessShader(shader_t& shader);
|
||||
void TessellationOverflow();
|
||||
|
||||
private:
|
||||
void BeginBatch(const shader_t* shader);
|
||||
void EndBatch();
|
||||
|
||||
PSOCache::Entry psoCacheEntries[128];
|
||||
PSOCache psoCache;
|
||||
|
||||
float clipPlane[4];
|
||||
bool batchOldDepthHack;
|
||||
bool batchDepthHack;
|
||||
};
|
||||
|
||||
struct WorldOpaque
|
||||
{
|
||||
void Init();
|
||||
|
@ -304,6 +324,8 @@ struct CRP : IRenderPipeline
|
|||
float frameSeed;
|
||||
HTexture readbackRenderTarget;
|
||||
HTexture depthTexture;
|
||||
HTexture normalTexture;
|
||||
HTexture motionVectorTexture;
|
||||
HTexture renderTarget;
|
||||
TextureFormat::Id renderTargetFormat;
|
||||
HTexture renderTargets[2];
|
||||
|
@ -328,6 +350,7 @@ struct CRP : IRenderPipeline
|
|||
MipMapGenerator mipMapGen;
|
||||
ImGUI imgui;
|
||||
Nuklear nuklear;
|
||||
Prepass prepass;
|
||||
WorldOpaque opaque;
|
||||
WorldTransp transp;
|
||||
TranspResolve transpResolve;
|
||||
|
|
|
@ -305,6 +305,28 @@ void CRP::Init()
|
|||
depthTexture = RHI::CreateTexture(desc);
|
||||
}
|
||||
|
||||
{
|
||||
TextureDesc desc("GBuffer normals", glConfig.vidWidth, glConfig.vidHeight);
|
||||
desc.committedResource = true;
|
||||
desc.shortLifeTime = true;
|
||||
desc.initialState = ResourceStates::RenderTargetBit;
|
||||
desc.allowedState = ResourceStates::RenderTargetBit | ResourceStates::PixelShaderAccessBit | ResourceStates::ComputeShaderAccessBit;
|
||||
desc.format = TextureFormat::RG32_SNorm;
|
||||
desc.SetClearColor(vec4_zero);
|
||||
normalTexture = RHI::CreateTexture(desc);
|
||||
}
|
||||
|
||||
{
|
||||
TextureDesc desc("GBuffer motion vectors", glConfig.vidWidth, glConfig.vidHeight);
|
||||
desc.committedResource = true;
|
||||
desc.shortLifeTime = true;
|
||||
desc.initialState = ResourceStates::RenderTargetBit;
|
||||
desc.allowedState = ResourceStates::RenderTargetBit | ResourceStates::PixelShaderAccessBit | ResourceStates::ComputeShaderAccessBit;
|
||||
desc.format = TextureFormat::RG32_Float;
|
||||
desc.SetClearColor(vec4_zero);
|
||||
motionVectorTexture = RHI::CreateTexture(desc);
|
||||
}
|
||||
|
||||
{
|
||||
GraphicsPipelineDesc desc("blit LDR");
|
||||
desc.vertexShader = ShaderByteCode(g_fullscreen_vs);
|
||||
|
@ -322,6 +344,7 @@ void CRP::Init()
|
|||
imgui.Init(true, ShaderByteCode(g_imgui_vs), ShaderByteCode(g_imgui_ps), renderTargetFormat, RHI_MAKE_NULL_HANDLE(), NULL);
|
||||
nuklear.Init(true, ShaderByteCode(g_nuklear_vs), ShaderByteCode(g_nuklear_ps), renderTargetFormat, RHI_MAKE_NULL_HANDLE(), NULL);
|
||||
mipMapGen.Init(true, ShaderByteCode(g_mip_1_cs), ShaderByteCode(g_mip_2_cs), ShaderByteCode(g_mip_3_cs));
|
||||
prepass.Init();
|
||||
opaque.Init();
|
||||
transp.Init();
|
||||
transpResolve.Init();
|
||||
|
@ -464,6 +487,7 @@ void CRP::ProcessShader(shader_t& shader)
|
|||
{
|
||||
if(shader.isOpaque)
|
||||
{
|
||||
prepass.ProcessShader(shader);
|
||||
opaque.ProcessShader(shader);
|
||||
}
|
||||
else
|
||||
|
@ -553,6 +577,7 @@ void CRP::TessellationOverflow()
|
|||
{
|
||||
switch(tess.tessellator)
|
||||
{
|
||||
case Tessellator::Prepass: prepass.TessellationOverflow(); break;
|
||||
case Tessellator::Opaque: opaque.TessellationOverflow(); break;
|
||||
case Tessellator::Transp: transp.TessellationOverflow(); break;
|
||||
default: break;
|
||||
|
@ -598,6 +623,7 @@ void CRP::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
CmdTextureBarrier(renderTarget, ResourceStates::RenderTargetBit);
|
||||
CmdEndBarrier();
|
||||
CmdClearColorTarget(renderTarget, cmd.clearColor, &rect);
|
||||
prepass.Draw(newCmd);
|
||||
opaque.Draw(newCmd);
|
||||
fog.Draw();
|
||||
transp.Draw(newCmd);
|
||||
|
@ -620,6 +646,7 @@ void CRP::DrawSceneView(const drawSceneViewCommand_t& cmd)
|
|||
}
|
||||
else
|
||||
{
|
||||
prepass.Draw(cmd);
|
||||
opaque.Draw(cmd);
|
||||
fog.Draw();
|
||||
transp.Draw(cmd);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -65,47 +65,17 @@ void WorldOpaque::Draw(const drawSceneViewCommand_t& cmd)
|
|||
|
||||
backEnd.refdef = cmd.refdef;
|
||||
backEnd.viewParms = cmd.viewParms;
|
||||
|
||||
if(backEnd.viewParms.isPortal)
|
||||
{
|
||||
float plane[4];
|
||||
plane[0] = backEnd.viewParms.portalPlane.normal[0];
|
||||
plane[1] = backEnd.viewParms.portalPlane.normal[1];
|
||||
plane[2] = backEnd.viewParms.portalPlane.normal[2];
|
||||
plane[3] = backEnd.viewParms.portalPlane.dist;
|
||||
|
||||
float plane2[4];
|
||||
plane2[0] = DotProduct(backEnd.viewParms.orient.axis[0], plane);
|
||||
plane2[1] = DotProduct(backEnd.viewParms.orient.axis[1], plane);
|
||||
plane2[2] = DotProduct(backEnd.viewParms.orient.axis[2], plane);
|
||||
plane2[3] = DotProduct(plane, backEnd.viewParms.orient.origin) - plane[3];
|
||||
|
||||
float* o = plane;
|
||||
const float* m = s_flipMatrix;
|
||||
const float* v = plane2;
|
||||
o[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];
|
||||
o[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];
|
||||
o[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];
|
||||
o[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];
|
||||
|
||||
memcpy(clipPlane, plane, sizeof(clipPlane));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(clipPlane, 0, sizeof(clipPlane));
|
||||
}
|
||||
RB_CreateClipPlane(clipPlane);
|
||||
|
||||
CmdSetViewportAndScissor(backEnd.viewParms);
|
||||
batchOldDepthHack = false;
|
||||
batchDepthHack = false;
|
||||
|
||||
CmdBeginBarrier();
|
||||
CmdTextureBarrier(crp.depthTexture, ResourceStates::DepthWriteBit);
|
||||
CmdTextureBarrier(crp.depthTexture, ResourceStates::DepthReadBit);
|
||||
CmdBufferBarrier(srp.traceRenderBuffer, ResourceStates::UnorderedAccessBit);
|
||||
CmdEndBarrier();
|
||||
|
||||
CmdClearDepthStencilTarget(crp.depthTexture, true, 0.0f);
|
||||
|
||||
GeoBuffers& db = crp.dynBuffers[GetFrameIndex()];
|
||||
db.BeginUpload();
|
||||
|
||||
|
@ -207,16 +177,13 @@ void WorldOpaque::ProcessShader(shader_t& shader)
|
|||
desc.vertexShader = g_opaque_vs;
|
||||
desc.pixelShader = g_opaque_ps;
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Position, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 2, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::TexCoord, DataType::Float32, 2, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Color, DataType::UNorm8, 4, 0);
|
||||
desc.depthStencil.depthStencilFormat = TextureFormat::Depth32_Float;
|
||||
desc.depthStencil.depthComparison =
|
||||
(stateBits & GLS_DEPTHFUNC_EQUAL) != 0 ?
|
||||
ComparisonFunction::Equal :
|
||||
ComparisonFunction::GreaterEqual;
|
||||
desc.depthStencil.enableDepthTest = (stateBits & GLS_DEPTHTEST_DISABLE) == 0;
|
||||
desc.depthStencil.enableDepthWrites = (stateBits & GLS_DEPTHMASK_TRUE) != 0;
|
||||
desc.depthStencil.depthComparison = shader.isSky ? ComparisonFunction::GreaterEqual : ComparisonFunction::Equal;
|
||||
desc.depthStencil.enableDepthTest = true;
|
||||
desc.depthStencil.enableDepthWrites = false;
|
||||
desc.rasterizer.cullMode = shader.cullType;
|
||||
desc.rasterizer.polygonOffset = shader.polygonOffset != 0;
|
||||
desc.rasterizer.clampDepth = clampDepth;
|
||||
|
|
294
code/renderer/crp_prepass.cpp
Normal file
294
code/renderer/crp_prepass.cpp
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
Challenge Quake 3 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 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Challenge Quake 3 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 Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
// Cinematic Rendering Pipeline - full opaque pre-pass
|
||||
|
||||
|
||||
#include "crp_local.h"
|
||||
#include "compshaders/crp/prepass.h"
|
||||
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
struct PrepassVertexRC
|
||||
{
|
||||
float modelViewMatrix[16];
|
||||
float projectionMatrix[16];
|
||||
float normalMatrix[16];
|
||||
float clipPlane[4];
|
||||
};
|
||||
|
||||
struct PrepassPixelRC
|
||||
{
|
||||
uint32_t textureIndex;
|
||||
uint32_t samplerIndex;
|
||||
uint32_t alphaTest;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
void Prepass::Init()
|
||||
{
|
||||
psoCache.Init(psoCacheEntries, ARRAY_LEN(psoCacheEntries));
|
||||
}
|
||||
|
||||
void Prepass::Draw(const drawSceneViewCommand_t& cmd)
|
||||
{
|
||||
if(cmd.numDrawSurfs - cmd.numTranspSurfs <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
srp.renderMode = RenderMode::World;
|
||||
|
||||
backEnd.refdef = cmd.refdef;
|
||||
backEnd.viewParms = cmd.viewParms;
|
||||
RB_CreateClipPlane(clipPlane);
|
||||
|
||||
CmdSetViewportAndScissor(backEnd.viewParms);
|
||||
batchOldDepthHack = false;
|
||||
batchDepthHack = false;
|
||||
|
||||
CmdBeginBarrier();
|
||||
CmdTextureBarrier(crp.depthTexture, ResourceStates::DepthWriteBit);
|
||||
CmdTextureBarrier(crp.normalTexture, ResourceStates::RenderTargetBit);
|
||||
CmdTextureBarrier(crp.motionVectorTexture, ResourceStates::RenderTargetBit);
|
||||
CmdEndBarrier();
|
||||
|
||||
CmdClearDepthStencilTarget(crp.depthTexture, true, 0.0f);
|
||||
CmdClearColorTarget(crp.normalTexture, vec4_zero, NULL);
|
||||
CmdClearColorTarget(crp.motionVectorTexture, vec4_zero, NULL);
|
||||
|
||||
GeoBuffers& db = crp.dynBuffers[GetFrameIndex()];
|
||||
db.BeginUpload();
|
||||
|
||||
SCOPED_RENDER_PASS("Pre-pass", 1.0f, 0.5f, 0.5f);
|
||||
|
||||
const HTexture renderTargets[] = { crp.normalTexture, crp.motionVectorTexture };
|
||||
CmdBindRenderTargets(ARRAY_LEN(renderTargets), renderTargets, &crp.depthTexture);
|
||||
CmdBindVertexBuffers(ARRAY_LEN(db.vertexBuffers), db.vertexBuffers, db.vertexBufferStrides, NULL);
|
||||
CmdBindIndexBuffer(db.indexBuffer.buffer, IndexType::UInt32, 0);
|
||||
|
||||
const drawSurf_t* drawSurfs = cmd.drawSurfs;
|
||||
const int surfCount = cmd.numDrawSurfs - cmd.numTranspSurfs;
|
||||
const double originalTime = backEnd.refdef.floatTime;
|
||||
|
||||
const shader_t* shader = NULL;
|
||||
const shader_t* oldShader = NULL;
|
||||
int oldEntityNum = -1;
|
||||
backEnd.currentEntity = &tr.worldEntity;
|
||||
|
||||
tess.numVertexes = 0;
|
||||
tess.numIndexes = 0;
|
||||
|
||||
int ds;
|
||||
const drawSurf_t* drawSurf;
|
||||
for(ds = 0, drawSurf = drawSurfs; ds < surfCount; ++ds, ++drawSurf)
|
||||
{
|
||||
int entityNum;
|
||||
R_DecomposeSort(drawSurf->sort, &entityNum, &shader);
|
||||
Q_assert(shader != NULL);
|
||||
Q_assert(shader->isOpaque);
|
||||
|
||||
if(shader->isSky || shader->numStages <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool shaderChanged = shader != oldShader;
|
||||
const bool entityChanged = entityNum != oldEntityNum;
|
||||
if(shaderChanged || entityChanged)
|
||||
{
|
||||
oldShader = shader;
|
||||
oldEntityNum = entityNum;
|
||||
EndBatch();
|
||||
BeginBatch(shader);
|
||||
tess.greyscale = drawSurf->greyscale;
|
||||
}
|
||||
|
||||
if(entityChanged)
|
||||
{
|
||||
UpdateEntityData(batchDepthHack, entityNum, originalTime);
|
||||
}
|
||||
|
||||
R_TessellateSurface(drawSurf->surface);
|
||||
}
|
||||
|
||||
backEnd.refdef.floatTime = originalTime;
|
||||
|
||||
EndBatch();
|
||||
|
||||
db.EndUpload();
|
||||
|
||||
// restores the potentially "hacked" depth range as well
|
||||
CmdSetViewportAndScissor(backEnd.viewParms);
|
||||
batchOldDepthHack = false;
|
||||
batchDepthHack = false;
|
||||
}
|
||||
|
||||
void Prepass::ProcessShader(shader_t& shader)
|
||||
{
|
||||
if(shader.isSky)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Q_assert(shader.isOpaque);
|
||||
|
||||
if(shader.numStages < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool clampDepth = r_depthClamp->integer != 0 || shader.isSky;
|
||||
|
||||
const shaderStage_t& stage = *shader.stages[0];
|
||||
const unsigned int stateBits = stage.stateBits & (~GLS_POLYMODE_LINE);
|
||||
int a = 0;
|
||||
|
||||
Q_assert((stateBits & GLS_DEPTHTEST_DISABLE) == 0); // depth test enabled
|
||||
Q_assert((stateBits & GLS_DEPTHMASK_TRUE) != 0); // depth write enabled
|
||||
Q_assert((stateBits & GLS_DEPTHFUNC_EQUAL) == 0); // depth comparison GE
|
||||
|
||||
// @NOTE: we are not using any CTOR because we deliberately want to 0-init the struct
|
||||
// this is necessary for padding bytes not to mess up comparisons in the PSO cache
|
||||
GraphicsPipelineDesc desc = {};
|
||||
desc.name = "pre-pass";
|
||||
desc.rootSignature = RHI_MAKE_NULL_HANDLE();
|
||||
desc.shortLifeTime = true; // the PSO cache is only valid for this map!
|
||||
desc.vertexShader = g_prepass_vs;
|
||||
desc.pixelShader = g_prepass_ps;
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Position, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::TexCoord, DataType::Float32, 2, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Color, DataType::UNorm8, 4, 0);
|
||||
desc.depthStencil.depthStencilFormat = TextureFormat::Depth32_Float;
|
||||
desc.depthStencil.depthComparison = ComparisonFunction::GreaterEqual;
|
||||
desc.depthStencil.enableDepthTest = true;
|
||||
desc.depthStencil.enableDepthWrites = true;
|
||||
desc.rasterizer.cullMode = shader.cullType;
|
||||
desc.rasterizer.polygonOffset = shader.polygonOffset != 0;
|
||||
desc.rasterizer.clampDepth = clampDepth;
|
||||
desc.AddRenderTarget(0, TextureFormat::RG32_SNorm);
|
||||
desc.AddRenderTarget(0, TextureFormat::RG32_Float);
|
||||
|
||||
pipeline_t& p = shader.prepassPipeline;
|
||||
p.firstStage = 0;
|
||||
p.numStages = 1;
|
||||
p.pipeline = psoCache.AddPipeline(desc, va("pre-pass %d", psoCache.entryCount));
|
||||
desc.rasterizer.cullMode = GetMirrorredCullType(desc.rasterizer.cullMode);
|
||||
p.mirrorPipeline = psoCache.AddPipeline(desc, va("pre-pass %d mirrored", psoCache.entryCount));
|
||||
}
|
||||
|
||||
void Prepass::TessellationOverflow()
|
||||
{
|
||||
EndBatch();
|
||||
BeginBatch(tess.shader);
|
||||
}
|
||||
|
||||
void Prepass::BeginBatch(const shader_t* shader)
|
||||
{
|
||||
tess.tessellator = Tessellator::Prepass;
|
||||
tess.numVertexes = 0;
|
||||
tess.numIndexes = 0;
|
||||
tess.depthFade = DFT_NONE;
|
||||
tess.deformsPreApplied = qfalse;
|
||||
tess.xstages = (const shaderStage_t**)shader->stages;
|
||||
tess.shader = shader;
|
||||
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
|
||||
if(tess.shader->clampTime && tess.shaderTime >= tess.shader->clampTime)
|
||||
{
|
||||
tess.shaderTime = tess.shader->clampTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Prepass::EndBatch()
|
||||
{
|
||||
PrepassVertexRC vertexRC = {};
|
||||
PrepassPixelRC pixelRC = {};
|
||||
float tempMatrix[16];
|
||||
|
||||
const int vertexCount = tess.numVertexes;
|
||||
const int indexCount = tess.numIndexes;
|
||||
if(vertexCount <= 0 ||
|
||||
indexCount <= 0 ||
|
||||
tess.shader->numStages <= 0)
|
||||
{
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
const shader_t* const shader = tess.shader;
|
||||
|
||||
GeoBuffers& db = crp.dynBuffers[GetFrameIndex()];
|
||||
if(!db.CanAdd(vertexCount, indexCount, shader->numStages))
|
||||
{
|
||||
Q_assert(!"World surface geometry buffer too small!");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
RB_DeformTessGeometry(0, vertexCount, 0, indexCount);
|
||||
db.UploadBase();
|
||||
|
||||
if(batchDepthHack != batchOldDepthHack)
|
||||
{
|
||||
const viewParms_t& vp = backEnd.viewParms;
|
||||
CmdSetViewport(vp.viewportX, vp.viewportY, vp.viewportWidth, vp.viewportHeight, batchDepthHack ? 0.7f : 0.0f, 1.0f);
|
||||
batchOldDepthHack = batchDepthHack;
|
||||
}
|
||||
|
||||
memcpy(vertexRC.modelViewMatrix, backEnd.orient.modelMatrix, sizeof(vertexRC.modelViewMatrix));
|
||||
memcpy(vertexRC.projectionMatrix, backEnd.viewParms.projectionMatrix, sizeof(vertexRC.projectionMatrix));
|
||||
memcpy(vertexRC.clipPlane, clipPlane, sizeof(vertexRC.clipPlane));
|
||||
R_InvMatrix(backEnd.modelMatrix, tempMatrix);
|
||||
R_TransposeMatrix(tempMatrix, vertexRC.normalMatrix);
|
||||
CmdSetGraphicsRootConstants(0, sizeof(vertexRC), &vertexRC);
|
||||
|
||||
const shaderStage_t* const stage = shader->stages[0];
|
||||
|
||||
R_ComputeColors(stage, tess.svars[0], 0, vertexCount);
|
||||
R_ComputeTexCoords(stage, tess.svars[0], 0, vertexCount, qfalse);
|
||||
db.UploadStage(0);
|
||||
|
||||
const pipeline_t& pipeline = shader->prepassPipeline;
|
||||
const int psoIndex = backEnd.viewParms.isMirror ? pipeline.mirrorPipeline : pipeline.pipeline;
|
||||
Q_assert(psoIndex > 0);
|
||||
CmdBindPipeline(psoCache.entries[psoIndex].handle);
|
||||
|
||||
const image_t* image = GetBundleImage(stage->bundle);
|
||||
const uint32_t texIdx = image->textureIndex;
|
||||
const uint32_t sampIdx = GetSamplerIndex(image);
|
||||
const uint32_t alphaTest = AlphaTestShaderConstFromStateBits(stage->stateBits);
|
||||
Q_assert(sampIdx < ARRAY_LEN(crp.samplers));
|
||||
|
||||
pixelRC.textureIndex = texIdx;
|
||||
pixelRC.samplerIndex = sampIdx;
|
||||
pixelRC.alphaTest = alphaTest;
|
||||
CmdSetGraphicsRootConstants(sizeof(vertexRC), sizeof(pixelRC), &pixelRC);
|
||||
|
||||
db.DrawStage(vertexCount, indexCount);
|
||||
|
||||
db.EndBaseBatch(vertexCount);
|
||||
|
||||
clean_up:
|
||||
tess.tessellator = Tessellator::None;
|
||||
tess.numVertexes = 0;
|
||||
tess.numIndexes = 0;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -83,35 +83,7 @@ void WorldTransp::Draw(const drawSceneViewCommand_t& cmd)
|
|||
|
||||
backEnd.refdef = cmd.refdef;
|
||||
backEnd.viewParms = cmd.viewParms;
|
||||
|
||||
if(backEnd.viewParms.isPortal)
|
||||
{
|
||||
float plane[4];
|
||||
plane[0] = backEnd.viewParms.portalPlane.normal[0];
|
||||
plane[1] = backEnd.viewParms.portalPlane.normal[1];
|
||||
plane[2] = backEnd.viewParms.portalPlane.normal[2];
|
||||
plane[3] = backEnd.viewParms.portalPlane.dist;
|
||||
|
||||
float plane2[4];
|
||||
plane2[0] = DotProduct(backEnd.viewParms.orient.axis[0], plane);
|
||||
plane2[1] = DotProduct(backEnd.viewParms.orient.axis[1], plane);
|
||||
plane2[2] = DotProduct(backEnd.viewParms.orient.axis[2], plane);
|
||||
plane2[3] = DotProduct(plane, backEnd.viewParms.orient.origin) - plane[3];
|
||||
|
||||
float* o = plane;
|
||||
const float* m = s_flipMatrix;
|
||||
const float* v = plane2;
|
||||
o[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];
|
||||
o[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];
|
||||
o[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];
|
||||
o[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];
|
||||
|
||||
memcpy(clipPlane, plane, sizeof(clipPlane));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(clipPlane, 0, sizeof(clipPlane));
|
||||
}
|
||||
RB_CreateClipPlane(clipPlane);
|
||||
|
||||
SCOPED_RENDER_PASS("Transparent", 1.0f, 0.5f, 0.5f);
|
||||
|
||||
|
@ -222,7 +194,7 @@ void WorldTransp::ProcessShader(shader_t& shader)
|
|||
desc.vertexShader = g_transp_draw_vs;
|
||||
desc.pixelShader = g_transp_draw_ps;
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Position, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 2, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::TexCoord, DataType::Float32, 2, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Color, DataType::UNorm8, 4, 0);
|
||||
desc.depthStencil.depthStencilFormat = TextureFormat::Depth32_Float;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
|
|
@ -552,7 +552,7 @@ uint32_t GRP::CreatePSO(CachedPSO& cache, const char* name)
|
|||
desc.vertexShader = vertexShaderByteCodes[cache.stageCount - 1];
|
||||
desc.pixelShader = pixelShaderByteCode;
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Position, DataType::Float32, 3, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 2, 0);
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::Normal, DataType::Float32, 3, 0);
|
||||
for(int s = 0; s < cache.stageCount; ++s)
|
||||
{
|
||||
desc.vertexLayout.AddAttribute(a++, ShaderSemantic::TexCoord, DataType::Float32, 2, 0);
|
||||
|
|
|
@ -363,34 +363,7 @@ void World::Begin()
|
|||
{
|
||||
srp.renderMode = RenderMode::World;
|
||||
|
||||
if(backEnd.viewParms.isPortal)
|
||||
{
|
||||
float plane[4];
|
||||
plane[0] = backEnd.viewParms.portalPlane.normal[0];
|
||||
plane[1] = backEnd.viewParms.portalPlane.normal[1];
|
||||
plane[2] = backEnd.viewParms.portalPlane.normal[2];
|
||||
plane[3] = backEnd.viewParms.portalPlane.dist;
|
||||
|
||||
float plane2[4];
|
||||
plane2[0] = DotProduct(backEnd.viewParms.orient.axis[0], plane);
|
||||
plane2[1] = DotProduct(backEnd.viewParms.orient.axis[1], plane);
|
||||
plane2[2] = DotProduct(backEnd.viewParms.orient.axis[2], plane);
|
||||
plane2[3] = DotProduct(plane, backEnd.viewParms.orient.origin) - plane[3];
|
||||
|
||||
float* o = plane;
|
||||
const float* m = s_flipMatrix;
|
||||
const float* v = plane2;
|
||||
o[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];
|
||||
o[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];
|
||||
o[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];
|
||||
o[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];
|
||||
|
||||
memcpy(clipPlane, plane, sizeof(clipPlane));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(clipPlane, 0, sizeof(clipPlane));
|
||||
}
|
||||
RB_CreateClipPlane(clipPlane);
|
||||
|
||||
CmdSetViewportAndScissor(backEnd.viewParms);
|
||||
batchOldDepthHack = false;
|
||||
|
|
|
@ -1715,6 +1715,8 @@ namespace RHI
|
|||
case TextureFormat::R8_UNorm: return DXGI_FORMAT_R8_UNORM;
|
||||
case TextureFormat::R10G10B10A2_UNorm: return DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||
case TextureFormat::R32_UInt: return DXGI_FORMAT_R32_UINT;
|
||||
case TextureFormat::RG32_SNorm: return DXGI_FORMAT_R16G16_SNORM;
|
||||
case TextureFormat::RG32_Float: return DXGI_FORMAT_R16G16_FLOAT;
|
||||
default: Q_assert(!"Unsupported texture format"); return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,6 +170,8 @@ namespace RHI
|
|||
Depth24_Stencil8,
|
||||
R10G10B10A2_UNorm,
|
||||
R32_UInt,
|
||||
RG32_SNorm,
|
||||
RG32_Float,
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -138,7 +138,45 @@ float EaseInQuad(float x)
|
|||
return x * x;
|
||||
}
|
||||
|
||||
float SmoothStep(float x)
|
||||
float smoothstep01(float x)
|
||||
{
|
||||
return smoothstep(0.0, 1.0, x);
|
||||
}
|
||||
|
||||
// Oct*: octahedron normal vector encoding
|
||||
// original code from "A Survey of Efficient Representations for Independent Unit Vectors"
|
||||
// further improved by Krzysztof Narkowicz and Rune Stubbe
|
||||
|
||||
float2 OctWrap(float2 v)
|
||||
{
|
||||
return (1.0 - abs(v.yx)) * (v.xy >= 0.0 ? 1.0 : -1.0);
|
||||
}
|
||||
|
||||
float2 OctEncode(float3 n)
|
||||
{
|
||||
n /= (abs(n.x) + abs(n.y) + abs(n.z));
|
||||
n.xy = n.z >= 0.0 ? n.xy : OctWrap(n.xy);
|
||||
n.xy = n.xy * 0.5 + 0.5;
|
||||
|
||||
return n.xy;
|
||||
}
|
||||
|
||||
float3 OctDecode(float2 f)
|
||||
{
|
||||
f = f * 2.0 - 1.0;
|
||||
float3 n = float3(f.x, f.y, 1.0 - abs(f.x) - abs(f.y));
|
||||
float t = saturate(-n.z);
|
||||
n.xy += n.xy >= 0.0 ? -t : t;
|
||||
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
float3 GetPositionFromDepth(float2 tc01, float depthZW, float4x4 invMatrix)
|
||||
{
|
||||
float x = tc01.x * 2.0 - 1.0;
|
||||
float y = (1.0 - tc01.y) * 2.0 - 1.0;
|
||||
float4 position = mul(float4(x, y, depthZW, 1.0), invMatrix);
|
||||
float3 result = position.xyz / position.w;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 Gian 'myT' Schellenbaum
|
||||
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
|
@ -76,9 +76,7 @@ VOut vs(VIn input)
|
|||
return output;
|
||||
}
|
||||
|
||||
// @TODO: enable early-Z here once the full pre-pass is implemented
|
||||
// this will prevent fragments failing the depth test from writing to the shader ID buffer
|
||||
//[earlydepthstencil]
|
||||
[earlydepthstencil]
|
||||
float4 ps(VOut input) : SV_Target
|
||||
{
|
||||
// @TODO: Voronoi tiling
|
||||
|
|
98
code/renderer/shaders/crp/prepass.hlsl
Normal file
98
code/renderer/shaders/crp/prepass.hlsl
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
Challenge Quake 3 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 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Challenge Quake 3 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 Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
// generic shader for the prepass of opaque surfaces
|
||||
|
||||
|
||||
#include "common.hlsli"
|
||||
#include "world.h.hlsli"
|
||||
#include "world.hlsli"
|
||||
|
||||
|
||||
cbuffer RootConstants
|
||||
{
|
||||
// geometry
|
||||
matrix modelViewMatrix;
|
||||
matrix projectionMatrix;
|
||||
matrix normalMatrix;
|
||||
float4 clipPlane;
|
||||
|
||||
// general
|
||||
uint textureIndex;
|
||||
uint samplerIndex;
|
||||
uint alphaTest;
|
||||
};
|
||||
|
||||
struct VIn
|
||||
{
|
||||
float3 position : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float2 texCoords : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
};
|
||||
|
||||
struct VOut
|
||||
{
|
||||
float4 position : SV_Position;
|
||||
float3 normal : NORMAL;
|
||||
float2 texCoords : TEXCOORD0;
|
||||
float4 color : COLOR0;
|
||||
float clipDist : SV_ClipDistance0;
|
||||
};
|
||||
|
||||
VOut vs(VIn input)
|
||||
{
|
||||
float4 positionVS = mul(modelViewMatrix, float4(input.position.xyz, 1));
|
||||
|
||||
VOut output;
|
||||
output.position = mul(projectionMatrix, positionVS);
|
||||
output.normal = mul(normalMatrix, float4(input.normal, 0)).xyz;
|
||||
output.texCoords = input.texCoords;
|
||||
output.color = input.color;
|
||||
output.clipDist = dot(positionVS, clipPlane);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
struct POut
|
||||
{
|
||||
float2 normal : SV_Target0;
|
||||
float2 motionVector : SV_Target1;
|
||||
};
|
||||
|
||||
POut ps(VOut input)
|
||||
{
|
||||
if(alphaTest != ATEST_NONE)
|
||||
{
|
||||
Texture2D texture0 = ResourceDescriptorHeap[textureIndex];
|
||||
SamplerState sampler0 = ResourceDescriptorHeap[samplerIndex];
|
||||
float4 dst = texture0.Sample(sampler0, input.texCoords) * input.color;
|
||||
if(FailsAlphaTest(dst.a, alphaTest))
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
POut output;
|
||||
output.normal = OctEncode(normalize(input.normal));
|
||||
output.motionVector = float2(0, 0); // @TODO:
|
||||
|
||||
return output;
|
||||
}
|
|
@ -181,7 +181,7 @@ void UpdateEntityData(bool& depthHack, int entityNum, double originalTime)
|
|||
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
|
||||
|
||||
// set up the transformation matrix
|
||||
R_RotateForEntity(backEnd.currentEntity, &backEnd.viewParms, &backEnd.orient);
|
||||
R_RotateForEntity(backEnd.currentEntity, &backEnd.viewParms, &backEnd.orient, backEnd.modelMatrix);
|
||||
|
||||
if(backEnd.currentEntity->e.renderfx & RF_DEPTHHACK)
|
||||
{
|
||||
|
@ -193,6 +193,7 @@ void UpdateEntityData(bool& depthHack, int entityNum, double originalTime)
|
|||
backEnd.currentEntity = &tr.worldEntity;
|
||||
backEnd.refdef.floatTime = originalTime;
|
||||
backEnd.orient = backEnd.viewParms.world;
|
||||
R_MakeIdentityMatrix(backEnd.modelMatrix);
|
||||
// we have to reset the shaderTime as well otherwise image animations on
|
||||
// the world (like water) continue with the wrong frame
|
||||
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
|
||||
|
|
|
@ -64,8 +64,7 @@ void RB_PopShader()
|
|||
// used when a player has predicted a teleport, but hasn't arrived yet
|
||||
float RB_HyperspaceColor()
|
||||
{
|
||||
if ( r_teleporterFlash->integer == 0 )
|
||||
{
|
||||
if (r_teleporterFlash->integer == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
@ -73,3 +72,33 @@ float RB_HyperspaceColor()
|
|||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void RB_CreateClipPlane( float* clipPlane )
|
||||
{
|
||||
if (backEnd.viewParms.isPortal) {
|
||||
float plane[4];
|
||||
plane[0] = backEnd.viewParms.portalPlane.normal[0];
|
||||
plane[1] = backEnd.viewParms.portalPlane.normal[1];
|
||||
plane[2] = backEnd.viewParms.portalPlane.normal[2];
|
||||
plane[3] = backEnd.viewParms.portalPlane.dist;
|
||||
|
||||
float plane2[4];
|
||||
plane2[0] = DotProduct(backEnd.viewParms.orient.axis[0], plane);
|
||||
plane2[1] = DotProduct(backEnd.viewParms.orient.axis[1], plane);
|
||||
plane2[2] = DotProduct(backEnd.viewParms.orient.axis[2], plane);
|
||||
plane2[3] = DotProduct(plane, backEnd.viewParms.orient.origin) - plane[3];
|
||||
|
||||
float* o = plane;
|
||||
const float* m = s_flipMatrix;
|
||||
const float* v = plane2;
|
||||
o[0] = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];
|
||||
o[1] = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];
|
||||
o[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];
|
||||
o[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];
|
||||
|
||||
memcpy(clipPlane, plane, 4 * sizeof(float));
|
||||
} else {
|
||||
memset(clipPlane, 0, 4 * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -435,6 +435,8 @@ struct shader_t {
|
|||
pipeline_t transpPipelines[MAX_SHADER_STAGES];
|
||||
int numTranspPipelines;
|
||||
|
||||
pipeline_t prepassPipeline;
|
||||
|
||||
shader_t* next;
|
||||
};
|
||||
|
||||
|
@ -857,6 +859,7 @@ typedef struct {
|
|||
viewParms_t viewParms;
|
||||
orientationr_t orient;
|
||||
trRefEntity_t* currentEntity;
|
||||
float modelMatrix[16]; // real model matrix, not model-view
|
||||
|
||||
qbool projection2D; // if qtrue, drawstretchpic doesn't need to change modes
|
||||
byte color2D[4];
|
||||
|
@ -1121,7 +1124,7 @@ int R_CullLocalBox( const vec3_t bounds[2] );
|
|||
int R_CullPointAndRadius( const vec3_t origin, float radius );
|
||||
int R_CullLocalPointAndRadius( const vec3_t origin, float radius );
|
||||
|
||||
void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms, orientationr_t* orient );
|
||||
void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms, orientationr_t* orient, float* modelMatrix = NULL );
|
||||
void R_CreateWorldModelMatrix( const vec3_t origin, const vec3_t axis[3], float* viewMatrix );
|
||||
|
||||
typedef void (*updateAnimatedImage_t)( image_t* image, int w, int h, const byte* data, qbool dirty );
|
||||
|
@ -1572,8 +1575,8 @@ void RB_TakeVideoFrameCmd( const videoFrameCommand_t* cmd );
|
|||
|
||||
void RB_PushSingleStageShader( int stateBits, cullType_t cullType );
|
||||
void RB_PopShader();
|
||||
|
||||
float RB_HyperspaceColor();
|
||||
void RB_CreateClipPlane( float* clipPlane );
|
||||
|
||||
void RB_DrawSky();
|
||||
void R_BuildCloudData();
|
||||
|
|
|
@ -493,7 +493,7 @@ Does NOT produce any GL calls
|
|||
Called by both the front end and the back end
|
||||
=================
|
||||
*/
|
||||
void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms, orientationr_t* orient )
|
||||
void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms, orientationr_t* orient, float* modelMatrix )
|
||||
{
|
||||
float glMatrix[16];
|
||||
vec3_t delta;
|
||||
|
@ -530,6 +530,10 @@ void R_RotateForEntity( const trRefEntity_t* ent, const viewParms_t* viewParms,
|
|||
glMatrix[11] = 0;
|
||||
glMatrix[15] = 1;
|
||||
|
||||
if ( modelMatrix != NULL ) {
|
||||
Com_Memcpy( modelMatrix, glMatrix, sizeof( glMatrix ) );
|
||||
}
|
||||
|
||||
R_MultMatrix( glMatrix, viewParms->world.modelMatrix, orient->modelMatrix );
|
||||
|
||||
// calculate the viewer origin in the model's space
|
||||
|
|
|
@ -388,6 +388,7 @@ void ProcessCRP()
|
|||
CompileCompute("mip_1.h", "mip_1.hlsl", "mip_1");
|
||||
CompileCompute("mip_2.h", "mip_2.hlsl", "mip_2");
|
||||
CompileCompute("mip_3.h", "mip_3.hlsl", "mip_3");
|
||||
CompileGraphics("prepass.h", "prepass.hlsl", "prepass");
|
||||
CompileGraphics("opaque.h", "opaque.hlsl", "opaque");
|
||||
CompileGraphics("transp_draw.h", "transp_draw.hlsl", "transp_draw");
|
||||
CompilePixelShader("transp_resolve.h", "transp_resolve.hlsl", "transp_resolve");
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
<ClCompile Include="..\..\code\renderer\crp_magnifier.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_main.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_opaque.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_prepass.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_tone_map.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_draw.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_resolve.cpp" />
|
||||
|
@ -236,6 +237,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\opaque.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\prepass.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\tone_map.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<ClCompile Include="..\..\code\renderer\crp_magnifier.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_main.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_opaque.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_prepass.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_tone_map.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_draw.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_resolve.cpp" />
|
||||
|
@ -140,6 +141,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\opaque.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\prepass.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\tone_map.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
<ClCompile Include="..\..\code\renderer\crp_magnifier.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_main.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_opaque.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_prepass.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_tone_map.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_draw.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_resolve.cpp" />
|
||||
|
@ -238,6 +239,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\opaque.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\prepass.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\tone_map.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<ClCompile Include="..\..\code\renderer\crp_magnifier.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_main.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_opaque.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_prepass.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_tone_map.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_draw.cpp" />
|
||||
<ClCompile Include="..\..\code\renderer\crp_transp_resolve.cpp" />
|
||||
|
@ -140,6 +141,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\opaque.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\prepass.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\tone_map.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
|
|
Loading…
Reference in a new issue