Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use 4D position buffer for stencil shadows #2096

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Components/MeshLodGenerator/include/OgreLod0Stripifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ namespace Ogre
vertexData->vertexStart = 0;
vertexData->vertexCount = remapInfo.usedCount;

vertexData->hardwareShadowVolWBuffer = HardwareVertexBufferSharedPtr(); // TODO: check this
vertexData->hwAnimationDataList.clear(); // TODO: check this
vertexData->hwAnimDataItemsUsed = 0; // TODO: check this
}
Expand Down
3 changes: 1 addition & 2 deletions Media/Main/ShadowExtrudeDirLight.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ uniform mat4 worldviewproj_matrix;
uniform vec4 light_position_object_space; // homogenous, object space

MAIN_PARAMETERS
IN(vec4 uv0, TEXCOORD0)
IN(vec4 position, POSITION)
MAIN_DECLARATION
{
// Extrusion in object space
// Vertex unmodified if w==1, extruded if w==0
vec4 newpos =
(uv0.xxxx * (position + light_position_object_space)) - light_position_object_space;
(position.wwww * (position + light_position_object_space)) - light_position_object_space;

gl_Position = mul(worldviewproj_matrix, newpos);
}
3 changes: 1 addition & 2 deletions Media/Main/ShadowExtrudeDirLightFinite.vert
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ uniform vec4 light_position_object_space; // homogenous, object space
uniform float shadow_extrusion_distance; // how far to extrude

MAIN_PARAMETERS
IN(vec4 uv0, TEXCOORD0)
IN(vec4 position, POSITION)
MAIN_DECLARATION
{
Expand All @@ -16,7 +15,7 @@ MAIN_DECLARATION
extrusionDir = normalize(extrusionDir);

vec4 newpos = vec4(position.xyz +
((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);
((1.0 - position.w) * shadow_extrusion_distance * extrusionDir), 1.0);

gl_Position = mul(worldviewproj_matrix, newpos);
}
3 changes: 1 addition & 2 deletions Media/Main/ShadowExtrudePointLight.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ uniform mat4 worldviewproj_matrix;
uniform vec4 light_position_object_space; // homogenous, object space

MAIN_PARAMETERS
IN(vec4 uv0, TEXCOORD0)
IN(vec4 position, POSITION)
MAIN_DECLARATION
{
// Extrusion in object space
// Vertex unmodified if w==1, extruded if w==0
vec4 newpos =
(uv0.xxxx * light_position_object_space) +
(position.wwww * light_position_object_space) +
vec4(position.xyz - light_position_object_space.xyz, 0.0);

gl_Position = mul(worldviewproj_matrix, newpos);
Expand Down
3 changes: 1 addition & 2 deletions Media/Main/ShadowExtrudePointLightFinite.vert
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ uniform vec4 light_position_object_space; // homogenous, object space
uniform float shadow_extrusion_distance; // how far to extrude

MAIN_PARAMETERS
IN(vec4 uv0, TEXCOORD0)
IN(vec4 position, POSITION)
MAIN_DECLARATION
{
Expand All @@ -16,7 +15,7 @@ MAIN_DECLARATION
extrusionDir = normalize(extrusionDir);

vec4 newpos = vec4(position.xyz +
((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);
((1.0 - position.w) * shadow_extrusion_distance * extrusionDir), 1.0);

gl_Position = mul(worldviewproj_matrix, newpos);
}
3 changes: 0 additions & 3 deletions OgreMain/include/OgreEntity.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,6 @@ namespace Ogre {
Entity* mParent;
/// Shared link to position buffer.
HardwareVertexBufferSharedPtr mPositionBuffer;
/// Shared link to w-coord buffer (optional).
HardwareVertexBufferSharedPtr mWBuffer;
/// Link to current vertex data used to bind (maybe changes).
const VertexData* mCurrentVertexData;
/// Link to SubEntity, only present if SubEntity has it's own geometry.
Expand All @@ -343,7 +341,6 @@ namespace Ogre {
void _createSeparateLightCap();
void getWorldTransforms(Matrix4* xform) const override;
HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
/// Rebind the source positions (for temp buffer users).
void rebindPositionBuffer(const VertexData* vertexData, bool force);
bool isVisible(void) const override;
Expand Down
3 changes: 0 additions & 3 deletions OgreMain/include/OgreManualObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,6 @@ namespace Ogre
ManualObject* mParent;
// Shared link to position buffer
HardwareVertexBufferSharedPtr mPositionBuffer;
// Shared link to w-coord buffer (optional)
HardwareVertexBufferSharedPtr mWBuffer;

public:
ManualObjectSectionShadowRenderable(ManualObject* parent,
Expand All @@ -633,7 +631,6 @@ namespace Ogre
~ManualObjectSectionShadowRenderable();
void getWorldTransforms(Matrix4* xform) const override;
HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) override;


Expand Down
4 changes: 3 additions & 1 deletion OgreMain/include/OgreOptimisedUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ namespace Ogre {
@param faceNormals The array of Vector4 used to store triangles face normal,
Must be aligned to SIMD alignment.
@param numTriangles Number of triangles to calculate face normal.
@param components Number of components in positions buffer. Must be 3 or 4
*/
virtual void calculateFaceNormals(
const float *positions,
const EdgeData::Triangle *triangles,
Vector4 *faceNormals,
size_t numTriangles) = 0;
size_t numTriangles,
int components = 3) = 0;

/** Calculate the light facing state of the triangle's face normals
@remarks
Expand Down
4 changes: 0 additions & 4 deletions OgreMain/include/OgreStaticGeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,17 +292,13 @@ namespace Ogre {
LODBucket* mParent;
// Shared link to position buffer
HardwareVertexBufferSharedPtr mPositionBuffer;
// Shared link to w-coord buffer (optional)
HardwareVertexBufferSharedPtr mWBuffer;

public:
LODShadowRenderable(LODBucket* parent,
HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData,
bool createSeparateLightCap, bool isLightCap = false);
~LODShadowRenderable();
void getWorldTransforms(Matrix4* xform) const override;
HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) override;

};
Expand Down
16 changes: 0 additions & 16 deletions OgreMain/include/OgreVertexIndexData.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,22 +144,6 @@ namespace Ogre {
*/
void prepareForShadowVolume(void);

/** Additional shadow volume vertex buffer storage.
@remarks
This additional buffer is only used where we have prepared this VertexData for
use in shadow volume construction, and where the current render system supports
vertex programs. This buffer contains the 'w' vertex position component which will
be used by that program to differentiate between extruded and non-extruded vertices.
This 'w' component cannot be included in the original position buffer because
DirectX does not allow 4-component positions in the fixed-function pipeline, and the original
position buffer must still be usable for fixed-function rendering.
@par
Note that we don't store any vertex declaration or vertex buffer binding here because this
can be reused in the shadow algorithm.
*/
HardwareVertexBufferSharedPtr hardwareShadowVolWBuffer;


/** Reorganises the data in the vertex buffers according to the
new vertex declaration passed in. Note that new vertex buffers
are created and written to, so if the buffers being referenced
Expand Down
9 changes: 5 additions & 4 deletions OgreMain/src/OgreEdgeListBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,11 @@ namespace Ogre {
void EdgeData::updateFaceNormals(size_t vertexSet,
const HardwareVertexBufferSharedPtr& positionBuffer)
{
assert (positionBuffer->getVertexSize() == sizeof(float) * 3
&& "Position buffer should contain only positions!");
OgreAssert(positionBuffer->getVertexSize() == sizeof(float) * 4,
"Position buffer should contain only positions!");

// Triangle face normals should be 1:1 with triangles
assert(triangleFaceNormals.size() == triangles.size());
OgreAssert(triangleFaceNormals.size() == triangles.size(), "size mismatch");

// Calculate triangles which are using this vertex set
const EdgeData::EdgeGroup& eg = edgeGroups[vertexSet];
Expand All @@ -429,7 +429,8 @@ namespace Ogre {
static_cast<float*>(positionsLock.pData),
&triangles[eg.triStart],
&triangleFaceNormals[eg.triStart],
eg.triCount);
eg.triCount,
4);
}
}
//---------------------------------------------------------------------
Expand Down
15 changes: 5 additions & 10 deletions OgreMain/src/OgreEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1987,8 +1987,10 @@ namespace Ogre {
// Lock, we'll be locking the (suppressed hardware update) shadow buffer
HardwareBufferLockGuard posLock(esrPositionBuffer, HardwareBuffer::HBL_NORMAL);
float* pSrc = static_cast<float*>(posLock.pData);
float* pDest = pSrc + (egi->vertexData->vertexCount * 3);
memcpy(pDest, pSrc, sizeof(float) * 3 * egi->vertexData->vertexCount);
float* pDest = pSrc + (egi->vertexData->vertexCount * 4);
memcpy(pDest, pSrc, sizeof(float) * 4 * egi->vertexData->vertexCount);
for (size_t i = 0; i < egi->vertexData->vertexCount; i++)
pDest[i * 4 + 3] = 0; // second part needs w=0
}
if (egi->vertexData == mMesh->sharedVertexData)
{
Expand Down Expand Up @@ -2121,18 +2123,11 @@ namespace Ogre {
// Create vertex data which just references position component (and 2 component)
mRenderOp.vertexData = OGRE_NEW VertexData();
// Map in position data
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION);
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT4, VES_POSITION);
mOriginalPosBufferBinding =
vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(mOriginalPosBufferBinding);
mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer);
// Map in w-coord buffer (if present)
if(vertexData->hardwareShadowVolWBuffer)
{
mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0);
mWBuffer = vertexData->hardwareShadowVolWBuffer;
mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer);
}
// Use same vertex start as input
mRenderOp.vertexData->vertexStart = vertexData->vertexStart;

Expand Down
2 changes: 1 addition & 1 deletion OgreMain/src/OgreHardwareBufferManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ namespace Ogre {
if (positions && !destPositionBuffer)
{
destPositionBuffer = srcPositionBuffer->getManager()->allocateVertexBufferCopy(srcPositionBuffer,
HardwareBufferManagerBase::BLT_AUTOMATIC_RELEASE, this);
HardwareBufferManagerBase::BLT_AUTOMATIC_RELEASE, this, true); // copy contents to keep W-coord for stencil shadows
}
if (normals && !posNormalShareBuffer && srcNormalBuffer && !destNormalBuffer)
{
Expand Down
9 changes: 1 addition & 8 deletions OgreMain/src/OgreManualObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,18 +773,11 @@ ManualObject::ManualObject(const String& name)
// Create vertex data which just references position component (and 2 component)
mRenderOp.vertexData = OGRE_NEW VertexData();
// Map in position data
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION);
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT4, VES_POSITION);
ushort origPosBind =
vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(origPosBind);
mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer);
// Map in w-coord buffer (if present)
if(vertexData->hardwareShadowVolWBuffer)
{
mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0);
mWBuffer = vertexData->hardwareShadowVolWBuffer;
mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer);
}
// Use same vertex start as input
mRenderOp.vertexData->vertexStart = vertexData->vertexStart;

Expand Down
6 changes: 2 additions & 4 deletions OgreMain/src/OgreMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1993,10 +1993,8 @@ namespace Ogre {


// Lock destination buffers for writing
HardwareBufferLockGuard destPosLock(destPosBuf,
(destNormBuf != destPosBuf && destPosBuf->getVertexSize() == destElemPos->getSize()) ||
(destNormBuf == destPosBuf && destPosBuf->getVertexSize() == destElemPos->getSize() + destElemNorm->getSize()) ?
HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL);
// HBL_NORMAL to keep W-coord for stencil shadows
HardwareBufferLockGuard destPosLock(destPosBuf, HardwareBuffer::HBL_NORMAL);
destElemPos->baseVertexPointerToElement(destPosLock.pData, &pDestPos);
HardwareBufferLockGuard destNormLock;
if (includeNormals)
Expand Down
6 changes: 4 additions & 2 deletions OgreMain/src/OgreOptimisedUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ namespace Ogre {
const float *positions,
const EdgeData::Triangle *triangles,
Vector4 *faceNormals,
size_t numTriangles)
size_t numTriangles,
int components)
{
static ProfileItems results;
static size_t index;
Expand All @@ -215,7 +216,8 @@ namespace Ogre {
positions,
triangles,
faceNormals,
numTriangles);
numTriangles,
components);
profile.end();

//
Expand Down
14 changes: 9 additions & 5 deletions OgreMain/src/OgreOptimisedUtilGeneral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ namespace Ogre {
const float *positions,
const EdgeData::Triangle *triangles,
Vector4 *faceNormals,
size_t numTriangles);
size_t numTriangles,
int components);

/// @copydoc OptimisedUtil::calculateLightFacing
virtual void calculateLightFacing(
Expand Down Expand Up @@ -286,20 +287,21 @@ namespace Ogre {
const float *positions,
const EdgeData::Triangle *triangles,
Vector4 *faceNormals,
size_t numTriangles)
size_t numTriangles,
int components)
{
for ( ; numTriangles; --numTriangles)
{
const EdgeData::Triangle& t = *triangles++;
size_t offset;

offset = t.vertIndex[0] * 3;
offset = t.vertIndex[0] * components;
Vector3 v1(positions[offset+0], positions[offset+1], positions[offset+2]);

offset = t.vertIndex[1] * 3;
offset = t.vertIndex[1] * components;
Vector3 v2(positions[offset+0], positions[offset+1], positions[offset+2]);

offset = t.vertIndex[2] * 3;
offset = t.vertIndex[2] * components;
Vector3 v3(positions[offset+0], positions[offset+1], positions[offset+2]);

*faceNormals++ = Math::calculateFaceNormalWithoutNormalize(v1, v2, v3);
Expand Down Expand Up @@ -341,6 +343,7 @@ namespace Ogre {
*pDestPos++ = *pSrcPos++ + extrusionDir.x;
*pDestPos++ = *pSrcPos++ + extrusionDir.y;
*pDestPos++ = *pSrcPos++ + extrusionDir.z;
pDestPos++, pSrcPos++;
}
}
else
Expand All @@ -360,6 +363,7 @@ namespace Ogre {
*pDestPos++ = *pSrcPos++ + extrusionDir.x;
*pDestPos++ = *pSrcPos++ + extrusionDir.y;
*pDestPos++ = *pSrcPos++ + extrusionDir.z;
pDestPos++, pSrcPos++;
}
}
}
Expand Down
Loading