Commit 1c88fc4f authored by Laszlo Agocs's avatar Laszlo Agocs

Fix up the shadowmap example for gl at least

parent e530fef5
......@@ -10,11 +10,13 @@ layout(binding = 1) uniform sampler2DShadow shadowMap;
void main()
{
vec3 ECCameraPosition = vec3(0.0, 0.0, 4.0); // matches C++
// These should be passed in the ubuf but just hardcode them for now.
// Positions must match the C++ side.
vec3 ECCameraPosition = vec3(0.0, 0.0, 4.0);
vec3 ECLightPosition = vec3(0.0, 10.0, 0.0);
vec3 ka = vec3(0.05, 0.05, 0.05);
vec3 kd = vec3(0.3, 0.7, 0.6);
vec3 ks = vec3(0.66, 0.66, 0.66);
vec3 ECLightPosition = vec3(0.0, 10.0, 1.0); // matches C++
vec3 attenuation = vec3(1.0, 0.0, 0.0);
vec3 color = vec3(1.0, 1.0, 1.0);
float intensity = 0.8;
......@@ -34,9 +36,12 @@ void main()
float RV = max(0.0, dot(R, V));
vec3 sColor = att * intensity * color * pow(RV, specularExp);
float sc = textureProj(shadowMap, vLCVertPos);
vec4 adjustedLcVertPos = vLCVertPos;
adjustedLcVertPos.z -= 0.0001; // bias to avoid acne
float sc = textureProj(shadowMap, adjustedLcVertPos);
float shadowFactor = 0.2;
if (sc > 0)
fragColor = vec4(ka + kd * dColor + ks * sColor, 1.0);
else
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
shadowFactor = 1.0;
fragColor = vec4(ka + kd * dColor + ks * sColor, 1.0) * shadowFactor;
}
......@@ -4,11 +4,12 @@ layout(location = 0) in vec4 position;
layout(location = 1) in vec3 normal;
layout(std140, binding = 0) uniform buf {
mat4 mvp;
mat4 mv;
mat4 m;
mat4 lightViewProj;
mat3 n;
mat4 clipSpaceCorr;
mat4 mvp; // projection * model_to_view
mat4 mv; // model_to_view
mat4 m; // model
mat4 lightViewProj; // light_cam_projection * light_model_to_view
mat3 n; // normal matrix for model
} ubuf;
out gl_PerVertex { vec4 gl_Position; };
......@@ -19,12 +20,13 @@ layout(location = 2) out vec4 vLCVertPos;
void main()
{
mat4 bias = mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
vLCVertPos = bias * ubuf.lightViewProj * ubuf.m * position;
// [-1,1] -> [0,1]
mat4 shadowMatrix = mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
vLCVertPos = ubuf.clipSpaceCorr * shadowMatrix * ubuf.lightViewProj * ubuf.m * position;
vECVertNormal = normalize(ubuf.n * normal);
vECVertPos = vec3(ubuf.m * position);
gl_Position = ubuf.mvp * position;
vECVertPos = vec3(ubuf.clipSpaceCorr * ubuf.m * position);
gl_Position = ubuf.clipSpaceCorr * ubuf.mvp * position;
}
......@@ -54,6 +54,9 @@
// Depth texture / shadow sampler / shadow map example.
// Not available on GLES 2.0.
// enable to render from the shadow casting light's viewpoint
//#define SHADOW_CAM_VIEW
static float quadVertexData[] =
{ // Y up, CCW, x-y-z, normalX-normalY-normalZ
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
......@@ -86,7 +89,8 @@ struct {
QRhiGraphicsPipeline *shadowPs = nullptr;
} d;
const int UBLOCK_SIZE = 64 * 4 + 48;
const int UBLOCK_SIZE = 64 * 5 + 48;
const int SHADOW_UBLOCK_SIZE = 64 * 2;
const int UBUF_SLOTS = 4; // 2 objects * 2 passes with different cameras
void Window::customInit()
......@@ -107,14 +111,14 @@ void Window::customInit()
d.ubuf->build();
d.releasePool << d.ubuf;
d.shadowMap = m_r->newTexture(QRhiTexture::D32F, QSize(512, 512), 1, QRhiTexture::RenderTarget);
d.shadowMap = m_r->newTexture(QRhiTexture::D32F, QSize(1024, 1024), 1, QRhiTexture::RenderTarget);
d.releasePool << d.shadowMap;
d.shadowMap->build();
d.shadowSampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
d.releasePool << d.shadowSampler;
d.shadowSampler->setTextureCompareOp(QRhiSampler::LessOrEqual);
d.shadowSampler->setTextureCompareOp(QRhiSampler::Less);
d.shadowSampler->build();
d.srb = m_r->newShaderResourceBindings();
......@@ -162,7 +166,7 @@ void Window::customInit()
d.shadowSrb = m_r->newShaderResourceBindings();
d.releasePool << d.shadowSrb;
d.shadowSrb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, stages, d.ubuf, UBLOCK_SIZE) });
d.shadowSrb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, stages, d.ubuf, SHADOW_UBLOCK_SIZE) });
d.shadowSrb->build();
d.shadowPs = m_r->newGraphicsPipeline();
......@@ -217,15 +221,15 @@ void Window::customRender()
d.initialUpdates = nullptr;
}
const QVector3D lightPos(0, 10, 1); // must match the shader
const QVector3D shadowCamCenter(0, 0, 0);
const QVector3D shadowCamUp(0, 1, 0);
const QMatrix4x4 cm = m_r->clipSpaceCorrMatrix();
const QVector3D lightPos(0, 10, 0.0001f); // must match the shader (but what's with the z bias??)
const int oneRoundedUniformBlockSize = m_r->ubufAligned(UBLOCK_SIZE);
QMatrix4x4 lightViewProj = m_r->clipSpaceCorrMatrix();
lightViewProj.perspective(45.0f, 1, 0.01f, 1000.0f);
lightViewProj.lookAt(lightPos, shadowCamCenter, shadowCamUp);
QMatrix4x4 lightViewProj;
lightViewProj.perspective(45.0f, 1, 0.1f, 100.0f);
lightViewProj.lookAt(lightPos, QVector3D(0, 0, 0), QVector3D(0, 1, 0));
// uniform data for the ground
if (d.winProj != m_proj) {
......@@ -239,48 +243,62 @@ void Window::customRender()
mv.translate(0, 0, -4); // must match the shader
mv *= m;
QMatrix4x4 shadowMvp = lightViewProj * m;
// for the main pass
QMatrix4x4 mvp = m_r->clipSpaceCorrMatrix() * m_rawProj * mv;
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
mv = m_r->clipSpaceCorrMatrix() * mv;
u->updateDynamicBuffer(d.ubuf, 64, 64, mv.constData());
m = m_r->clipSpaceCorrMatrix() * m;
u->updateDynamicBuffer(d.ubuf, 128, 64, m.constData());
u->updateDynamicBuffer(d.ubuf, 192, 64, lightViewProj.constData());
QMatrix3x3 n = m.normalMatrix();
u->updateDynamicBuffer(d.ubuf, 256, 48, n.constData());
QMatrix4x4 mvp = m_rawProj * mv;
u->updateDynamicBuffer(d.ubuf, 0, 64, cm.constData());
u->updateDynamicBuffer(d.ubuf, 64, 64, mvp.constData());
u->updateDynamicBuffer(d.ubuf, 128, 64, mv.constData());
u->updateDynamicBuffer(d.ubuf, 192, 64, m.constData());
u->updateDynamicBuffer(d.ubuf, 256, 64, lightViewProj.constData());
QMatrix3x3 n = (cm * m).normalMatrix();
u->updateDynamicBuffer(d.ubuf, 320, 48, n.constData());
// for the shadow pass
mvp = lightViewProj * mv;
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize, 64, mvp.constData());
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize, 64, cm.constData());
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize + 64, 64, shadowMvp.constData());
#ifdef SHADOW_CAM_VIEW
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize + 128, 64, mv.constData());
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize + 192, 64, m.constData());
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize + 256, 64, lightViewProj.constData());
u->updateDynamicBuffer(d.ubuf, 2 * oneRoundedUniformBlockSize + 320, 48, n.constData());
#endif
}
// uniform data for the rotating cube
QMatrix4x4 m;
m.translate(0, 1, 0);
m.translate(0, 1.2f, 0);
m.scale(0.5f);
m.rotate(d.cubeRot, 1, 0, 0);
m.rotate(20, 0, 1, 0);
m.rotate(d.cubeRot, 0, 1, 0);
m.rotate(45, 1, 0, 0);
d.cubeRot += 1;
QMatrix4x4 mv;
mv.translate(0, 0, -4); // must match the shader
mv *= m;
QMatrix4x4 shadowMvp = lightViewProj * m;
// for the main pass
QMatrix4x4 mvp = m_r->clipSpaceCorrMatrix() * m_rawProj * mv;
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize, 64, mvp.constData());
mv = m_r->clipSpaceCorrMatrix() * mv;
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 64, 64, mv.constData());
m = m_r->clipSpaceCorrMatrix() * m;
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 128, 64, m.constData());
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 192, 64, lightViewProj.constData());
QMatrix3x3 n = m.normalMatrix();
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 256, 48, n.constData());
QMatrix4x4 mvp = m_rawProj * mv;
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize, 64, cm.constData());
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 64, 64, mvp.constData());
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 128, 64, mv.constData());
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 192, 64, m.constData());
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 256, 64, lightViewProj.constData());
QMatrix3x3 n = (cm * m).normalMatrix();
u->updateDynamicBuffer(d.ubuf, oneRoundedUniformBlockSize + 320, 48, n.constData());
// for the shadow pass
mvp = lightViewProj * mv;
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize, 64, mvp.constData());
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize, 64, cm.constData());
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize + 64, 64, shadowMvp.constData());
#ifdef SHADOW_CAM_VIEW
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize + 128, 64, mv.constData());
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize + 192, 64, m.constData());
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize + 256, 64, lightViewProj.constData());
u->updateDynamicBuffer(d.ubuf, 3 * oneRoundedUniformBlockSize + 320, 48, n.constData());
#endif
cb->resourceUpdate(u);
......@@ -296,6 +314,10 @@ void Window::customRender()
cb->beginPass(m_sc->currentFrameRenderTarget(), { 0.4f, 0.7f, 0.0f, 1.0f }, { 1.0f, 0 });
cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
#ifdef SHADOW_CAM_VIEW
enqueueScene(cb, d.srb, oneRoundedUniformBlockSize, 2);
#else
enqueueScene(cb, d.srb, oneRoundedUniformBlockSize, 0);
#endif
cb->endPass();
}
......@@ -3,6 +3,7 @@
layout(location = 0) in vec4 position;
layout(std140, binding = 0) uniform buf {
mat4 clipSpaceCorr;
mat4 mvp;
} ubuf;
......@@ -10,5 +11,5 @@ out gl_PerVertex { vec4 gl_Position; };
void main()
{
gl_Position = ubuf.mvp * position;
gl_Position = ubuf.clipSpaceCorr * ubuf.mvp * position;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment