DCLN OBB transform fix

This commit is contained in:
Jack Andersen 2019-03-07 18:16:42 -10:00
parent 4b042f6f9a
commit f40bf707f6
13 changed files with 45 additions and 40 deletions

View File

@ -49,15 +49,17 @@ static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C, const Co
// find the right, up and forward vectors from the eigenvectors // find the right, up and forward vectors from the eigenvectors
zeus::CVector3f r(eigvec(0, 0), eigvec(1, 0), eigvec(2, 0)); zeus::CVector3f r(eigvec(0, 0), eigvec(1, 0), eigvec(2, 0));
zeus::CVector3f u(eigvec(0, 1), eigvec(1, 1), eigvec(2, 1)); zeus::CVector3f f(eigvec(0, 1), eigvec(1, 1), eigvec(2, 1));
zeus::CVector3f f(eigvec(0, 2), eigvec(1, 2), eigvec(2, 2)); zeus::CVector3f u(eigvec(0, 2), eigvec(1, 2), eigvec(2, 2));
r.normalize(); r.normalize();
u.normalize(), f.normalize(); f.normalize();
u.normalize();
// set the rotation matrix using the eigvenvectors // set the rotation matrix using the eigvenvectors
ret.xf.basis[0] = r; ret.xf.basis[0] = r;
ret.xf.basis[1] = u; ret.xf.basis[1] = f;
ret.xf.basis[2] = f; ret.xf.basis[2] = u;
ret.xf.orthonormalize();
// now build the bounding box extents in the rotated frame // now build the bounding box extents in the rotated frame
zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f); zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f);
@ -65,7 +67,7 @@ static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix<float>& C, const Co
std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, triIdx); std::unordered_set<uint32_t> verts = GetTriangleVerts(mesh, triIdx);
for (uint32_t v : verts) { for (uint32_t v : verts) {
const zeus::CVector3f& p = mesh.verts[v].val; const zeus::CVector3f& p = mesh.verts[v].val;
zeus::CVector3f p_prime(r.dot(p), u.dot(p), f.dot(p)); zeus::CVector3f p_prime(ret.xf.basis[0].dot(p), ret.xf.basis[1].dot(p), ret.xf.basis[2].dot(p));
minim = zeus::min(minim, p_prime); minim = zeus::min(minim, p_prime);
maxim = zeus::max(maxim, p_prime); maxim = zeus::max(maxim, p_prime);
} }

View File

@ -15,9 +15,9 @@ void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const
"obj.location = mtxd[0]\n" "obj.location = mtxd[0]\n"
"obj.rotation_quaternion = mtxd[1]\n" "obj.rotation_quaternion = mtxd[1]\n"
"obj.scale = (%f,%f,%f)\n", "obj.scale = (%f,%f,%f)\n",
isLeaf ? "leaf" : "branch", xf[0].vec[0], xf[0].vec[1], xf[0].vec[2], xf[0].vec[3], xf[1].vec[0], xf[1].vec[1], isLeaf ? "leaf" : "branch", xf[0].simd[0], xf[0].simd[1], xf[0].simd[2], xf[0].simd[3], xf[1].simd[0],
xf[1].vec[2], xf[1].vec[3], xf[2].vec[0], xf[2].vec[1], xf[2].vec[2], xf[2].vec[3], halfExtent.vec[0], xf[1].simd[1], xf[1].simd[2], xf[1].simd[3], xf[2].simd[0], xf[2].simd[1], xf[2].simd[2], xf[2].simd[3],
halfExtent.vec[1], halfExtent.vec[2]); halfExtent.simd[0], halfExtent.simd[1], halfExtent.simd[2]);
if (isLeaf) if (isLeaf)
os << "obj.show_name = True\n"; os << "obj.show_name = True\n";
if (!isLeaf) { if (!isLeaf) {

View File

@ -21,7 +21,7 @@ struct Actor : IScriptObject {
AnimationParameters animationParameters; AnimationParameters animationParameters;
ActorParameters actorParameters; ActorParameters actorParameters;
Value<bool> looping; Value<bool> looping;
Value<bool> snow; Value<bool> immovable;
Value<bool> solid; Value<bool> solid;
Value<bool> cameraPassthrough; Value<bool> cameraPassthrough;
Value<bool> active; Value<bool> active;

View File

@ -24,9 +24,8 @@ class CCollidableOBBTreeGroup : public CCollisionPrimitive {
const CCollidableOBBTreeGroupContainer* x10_container; const CCollidableOBBTreeGroupContainer* x10_container;
public: public:
CCollidableOBBTreeGroup(CInputStream& in);
CCollidableOBBTreeGroup(const CCollidableOBBTreeGroupContainer*, const CMaterialList&); CCollidableOBBTreeGroup(const CCollidableOBBTreeGroupContainer*, const CMaterialList&);
virtual ~CCollidableOBBTreeGroup() {} virtual ~CCollidableOBBTreeGroup() = default;
void ResetTestStats() const; void ResetTestStats() const;
virtual u32 GetTableIndex() const; virtual u32 GetTableIndex() const;

View File

@ -56,7 +56,7 @@ void Buckets::Sort() {
u32 precision = 50; u32 precision = 50;
if (sPlaneObjectBucket->size()) { if (sPlaneObjectBucket->size()) {
std::sort(sPlaneObjectBucket->begin(), sPlaneObjectBucket->end(), std::sort(sPlaneObjectBucket->begin(), sPlaneObjectBucket->end(),
[](u16 a, u16 b) { return (*sPlaneObjectData)[a].GetDistance() > (*sPlaneObjectData)[b].GetDistance(); }); [](u16 a, u16 b) { return (*sPlaneObjectData)[a].GetDistance() < (*sPlaneObjectData)[b].GetDistance(); });
precision = 50 / u32(sPlaneObjectBucket->size() + 1); precision = 50 / u32(sPlaneObjectBucket->size() + 1);
pitch = 1.f / (delta / float(precision - 2)); pitch = 1.f / (delta / float(precision - 2));

View File

@ -24,8 +24,9 @@ void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& c
vec.normalize(); vec.normalize();
vec *= zeus::CVector2f(std::sqrt(mag)); vec *= zeus::CVector2f(std::sqrt(mag));
} }
data[y][x][0] = zeus::clamp(0, int((((vec.x() / 2.f + 0.5f) - x / float(WARP_RAMP_RES)) + 0.5f) * 255), 255); data[y][x][3] = zeus::clamp(0, int((((vec.x() / 2.f + 0.5f) - x / float(WARP_RAMP_RES)) + 0.5f) * 255), 255);
data[y][x][1] = zeus::clamp(0, int((((vec.y() / 2.f + 0.5f) - y / float(WARP_RAMP_RES)) + 0.5f) * 255), 255); data[y][x][2] = zeus::clamp(0, int((((vec.y() / 2.f + 0.5f) - y / float(WARP_RAMP_RES)) + 0.5f) * 255), 255);
data[y][x][0] = data[y][x][1] = data[y][x][2];
} }
} }
m_warpTex = m_warpTex =
@ -41,10 +42,10 @@ CSpaceWarpFilter::CSpaceWarpFilter() {
zeus::CVector2f m_pos; zeus::CVector2f m_pos;
zeus::CVector2f m_uv; zeus::CVector2f m_uv;
} verts[4] = { } verts[4] = {
{{-1.0, -1.0}, {0.0, 0.0}}, {{-1.f, -1.f}, {0.f, 0.f}},
{{-1.0, 1.0}, {0.0, 1.0}}, {{-1.f, 1.f}, {0.f, 1.f}},
{{1.0, -1.0}, {1.0, 0.0}}, {{1.f, -1.f}, {1.f, 0.f}},
{{1.0, 1.0}, {1.0, 1.0}}, {{1.f, 1.f}, {1.f, 1.f}},
}; };
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, 32, 4); m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, 32, 4);
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
@ -117,10 +118,13 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) {
m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y(); m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y();
m_uniform.m_matrix[3][0] = pt.x() + (1.f / vp.x()); m_uniform.m_matrix[3][0] = pt.x() + (1.f / vp.x());
m_uniform.m_matrix[3][1] = pt.y() + (1.f / vp.y()); m_uniform.m_matrix[3][1] = pt.y() + (1.f / vp.y());
if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) {
m_uniform.m_matrix[3][2] = pt.z() * 2.f - 1.f; m_uniform.m_matrix[3][2] = pt.z() * 2.f - 1.f;
else } else {
m_uniform.m_matrix[1][1] *= -1.f;
m_uniform.m_matrix[3][1] *= -1.f;
m_uniform.m_matrix[3][2] = pt.z(); m_uniform.m_matrix[3][2] = pt.z();
}
if (clipRect.x4_left) { if (clipRect.x4_left) {
clipRect.x4_left -= 1; clipRect.x4_left -= 1;

View File

@ -12,7 +12,7 @@ CScriptSpawnPoint::CScriptSpawnPoint(TUniqueId uid, std::string_view name, const
const rstl::reserved_vector<u32, int(CPlayerState::EItemType::Max)>& itemCounts, const rstl::reserved_vector<u32, int(CPlayerState::EItemType::Max)>& itemCounts,
bool defaultSpawn, bool active, bool morphed) bool defaultSpawn, bool active, bool morphed)
: CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts) { : CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts) {
//#ifndef NDEBUG #ifndef NDEBUG
x64_itemCounts[int(CPlayerState::EItemType::MorphBall)] = 1; x64_itemCounts[int(CPlayerState::EItemType::MorphBall)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::MorphBallBombs)] = 1; x64_itemCounts[int(CPlayerState::EItemType::MorphBallBombs)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::GravitySuit)] = 1; x64_itemCounts[int(CPlayerState::EItemType::GravitySuit)] = 1;
@ -25,7 +25,7 @@ CScriptSpawnPoint::CScriptSpawnPoint(TUniqueId uid, std::string_view name, const
x64_itemCounts[int(CPlayerState::EItemType::SpaceJumpBoots)] = 1; x64_itemCounts[int(CPlayerState::EItemType::SpaceJumpBoots)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::Missiles)] = x64_itemCounts[int(CPlayerState::EItemType::Missiles)] =
std::max(x64_itemCounts[int(CPlayerState::EItemType::Missiles)], u32(5)); std::max(x64_itemCounts[int(CPlayerState::EItemType::Missiles)], u32(5));
//#endif #endif
x10c_24_firstSpawn = defaultSpawn; x10c_24_firstSpawn = defaultSpawn;
x10c_25_morphed = morphed; x10c_25_morphed = morphed;
} }

View File

@ -409,7 +409,7 @@ CEntity* ScriptLoader::LoadActor(CStateManager& mgr, CInputStream& in, int propC
CActorParameters actParms = LoadActorParameters(in); CActorParameters actParms = LoadActorParameters(in);
bool looping = in.readBool(); bool looping = in.readBool();
bool snow = in.readBool(); bool immovable = in.readBool();
bool solid = in.readBool(); bool solid = in.readBool();
bool cameraPassthrough = in.readBool(); bool cameraPassthrough = in.readBool();
bool active = in.readBool(); bool active = in.readBool();
@ -427,8 +427,8 @@ CEntity* ScriptLoader::LoadActor(CStateManager& mgr, CInputStream& in, int propC
zeus::CAABox aabb = GetCollisionBox(mgr, info.GetAreaId(), collisionExtent, centroid); zeus::CAABox aabb = GetCollisionBox(mgr, info.GetAreaId(), collisionExtent, centroid);
CMaterialList list; CMaterialList list;
if (snow) // Bool 2 if (immovable) // Bool 2
list.Add(EMaterialTypes::Snow); list.Add(EMaterialTypes::Immovable);
if (solid) // Bool 3 if (solid) // Bool 3
list.Add(EMaterialTypes::Solid); list.Add(EMaterialTypes::Solid);

View File

@ -372,7 +372,7 @@ TBINDING1 uniform sampler2D sceneMap;
TBINDING2 uniform sampler2D tindMap; TBINDING2 uniform sampler2D tindMap;
void main() void main()
{ {
vec2 tindTexel = texture(tindMap, vtf.uvTind).zw; vec2 tindTexel = texture(tindMap, vtf.uvTind).ab;
vec4 sceneTexel = texture(sceneMap, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); vec4 sceneTexel = texture(sceneMap, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
vec4 texrTexel = texture(texrMap, vtf.uvTexr); vec4 texrTexel = texture(texrMap, vtf.uvTexr);
colorOut = vtf.color * vec4(sceneTexel.rgb, 1.0) + texrTexel; colorOut = vtf.color * vec4(sceneTexel.rgb, 1.0) + texrTexel;
@ -430,7 +430,7 @@ struct VertToFrag
float4 main(in VertToFrag vtf) : SV_Target0 float4 main(in VertToFrag vtf) : SV_Target0
{ {
float2 tindTexel = tex2.Sample(samp, vtf.uvTind).zw; float2 tindTexel = tex2.Sample(samp, vtf.uvTind).ab;
float4 sceneTexel = tex1.Sample(samp, lerp(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); float4 sceneTexel = tex1.Sample(samp, lerp(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
float4 texrTexel = tex0.Sample(samp, vtf.uvTexr); float4 texrTexel = tex0.Sample(samp, vtf.uvTexr);
float4 colorOut = vtf.color * float4(sceneTexel.rgb, 1.0) + texrTexel; float4 colorOut = vtf.color * float4(sceneTexel.rgb, 1.0) + texrTexel;
@ -492,7 +492,7 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
texture2d<float> tex1 [[ texture(1) ]], texture2d<float> tex1 [[ texture(1) ]],
texture2d<float> tex2 [[ texture(2) ]]) texture2d<float> tex2 [[ texture(2) ]])
{ {
float2 tindTexel = tex2.sample(samp, vtf.uvTind).ba; float2 tindTexel = tex2.sample(samp, vtf.uvTind).ab;
float4 sceneTexel = tex1.sample(samp, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); float4 sceneTexel = tex1.sample(samp, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
float4 texrTexel = tex0.sample(samp, vtf.uvTexr); float4 texrTexel = tex0.sample(samp, vtf.uvTexr);
float4 colorOut = vtf.color * float4(sceneTexel.rgb, 1.0) + texrTexel; float4 colorOut = vtf.color * float4(sceneTexel.rgb, 1.0) + texrTexel;
@ -542,7 +542,7 @@ TBINDING1 uniform sampler2D sceneMap;
TBINDING2 uniform sampler2D tindMap; TBINDING2 uniform sampler2D tindMap;
void main() void main()
{ {
vec2 tindTexel = texture(tindMap, vtf.uvTind).zw; vec2 tindTexel = texture(tindMap, vtf.uvTind).ab;
vec4 sceneTexel = texture(sceneMap, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); vec4 sceneTexel = texture(sceneMap, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
colorOut = vtf.color * vec4(sceneTexel.rgb, 1.0) * texture(texrMap, vtf.uvTexr); colorOut = vtf.color * vec4(sceneTexel.rgb, 1.0) * texture(texrMap, vtf.uvTexr);
} }
@ -563,7 +563,7 @@ struct VertToFrag
float4 main(in VertToFrag vtf) : SV_Target0 float4 main(in VertToFrag vtf) : SV_Target0
{ {
float2 tindTexel = tex2.Sample(samp, vtf.uvTind).ba; float2 tindTexel = tex2.Sample(samp, vtf.uvTind).ab;
float4 sceneTexel = tex1.Sample(samp, lerp(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); float4 sceneTexel = tex1.Sample(samp, lerp(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
return vtf.color * float4(sceneTexel.rgb, 1.0) * tex0.Sample(samp, vtf.uvTexr); return vtf.color * float4(sceneTexel.rgb, 1.0) * tex0.Sample(samp, vtf.uvTexr);
} }
@ -584,7 +584,7 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
texture2d<float> tex1 [[ texture(1) ]], texture2d<float> tex1 [[ texture(1) ]],
texture2d<float> tex2 [[ texture(2) ]]) texture2d<float> tex2 [[ texture(2) ]])
{ {
float2 tindTexel = tex2.sample(samp, vtf.uvTind).ba; float2 tindTexel = tex2.sample(samp, vtf.uvTind).ab;
float4 sceneTexel = tex1.sample(samp, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); float4 sceneTexel = tex1.sample(samp, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
return vtf.color * float4(sceneTexel.rgb, 1.0) * tex0.sample(samp, vtf.uvTexr); return vtf.color * float4(sceneTexel.rgb, 1.0) * tex0.sample(samp, vtf.uvTexr);
} }

View File

@ -60,7 +60,7 @@ TBINDING2 uniform sampler2D maskTex;
TBINDING3 uniform sampler2D maskTexBlur; TBINDING3 uniform sampler2D maskTexBlur;
void main() void main()
{ {
vec2 indUv = (texture(indTex, vtf.indUv).ra - vec2(0.5, 0.5)) * vec2 indUv = (texture(indTex, vtf.indUv).ab - vec2(0.5, 0.5)) *
vtf.indScaleOff.xy + vtf.indScaleOff.zw; vtf.indScaleOff.xy + vtf.indScaleOff.zw;
float maskBlurAlpha = clamp(0.0, (texture(maskTexBlur, vtf.maskUv).a - texture(maskTex, vtf.maskUv).a) * 2.0, 1.0); float maskBlurAlpha = clamp(0.0, (texture(maskTexBlur, vtf.maskUv).a - texture(maskTex, vtf.maskUv).a) * 2.0, 1.0);
colorOut = vtf.color * texture(screenTex, indUv + vtf.screenUv) * maskBlurAlpha; colorOut = vtf.color * texture(screenTex, indUv + vtf.screenUv) * maskBlurAlpha;
@ -123,7 +123,7 @@ Texture2D maskTex : register(t2);
Texture2D maskTexBlur : register(t3); Texture2D maskTexBlur : register(t3);
float4 main(in VertToFrag vtf) : SV_Target0 float4 main(in VertToFrag vtf) : SV_Target0
{ {
float2 indUv = (indTex.Sample(samp, vtf.indUv).ra - float2(0.5, 0.5)) * float2 indUv = (indTex.Sample(samp, vtf.indUv).ab - float2(0.5, 0.5)) *
vtf.indScaleOff.xy + vtf.indScaleOff.zw; vtf.indScaleOff.xy + vtf.indScaleOff.zw;
float maskBlurAlpha = saturate((maskTexBlur.Sample(samp, vtf.maskUv).a - maskTex.Sample(samp, vtf.maskUv).a) * 2.0); float maskBlurAlpha = saturate((maskTexBlur.Sample(samp, vtf.maskUv).a - maskTex.Sample(samp, vtf.maskUv).a) * 2.0);
return float4((vtf.color * screenTex.Sample(samp, indUv + vtf.screenUv) * maskBlurAlpha).rgb, vtf.color.a); return float4((vtf.color * screenTex.Sample(samp, indUv + vtf.screenUv) * maskBlurAlpha).rgb, vtf.color.a);
@ -186,7 +186,7 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
texture2d<float> maskTex [[ texture(2) ]], texture2d<float> maskTex [[ texture(2) ]],
texture2d<float> maskTexBlur [[ texture(3) ]]) texture2d<float> maskTexBlur [[ texture(3) ]])
{ {
float2 indUv = (indTex.sample(samp, vtf.indUv).ra - float2(0.5, 0.5)) * float2 indUv = (indTex.sample(samp, vtf.indUv).ab - float2(0.5, 0.5)) *
vtf.indScaleOff.xy + vtf.indScaleOff.zw; vtf.indScaleOff.xy + vtf.indScaleOff.zw;
float maskBlurAlpha = saturate((maskTexBlur.sample(samp, vtf.maskUv).a - maskTex.sample(samp, vtf.maskUv).a) * 2.0); float maskBlurAlpha = saturate((maskTexBlur.sample(samp, vtf.maskUv).a - maskTex.sample(samp, vtf.maskUv).a) * 2.0);
return float4((vtf.color * screenTex.sample(samp, indUv + vtf.screenUv) * maskBlurAlpha).rgb, vtf.color.a); return float4((vtf.color * screenTex.sample(samp, indUv + vtf.screenUv) * maskBlurAlpha).rgb, vtf.color.a);

View File

@ -49,7 +49,7 @@ TBINDING0 uniform sampler2D sceneTex;
TBINDING1 uniform sampler2D indTex; TBINDING1 uniform sampler2D indTex;
void main() void main()
{ {
vec2 indUv = texture(indTex, vtf.indUv).xy * vec2(2.0) - vec2(1.0 - 1.0 / 256.0); vec2 indUv = texture(indTex, vtf.indUv).ab * vec2(2.0) - vec2(1.0 - 1.0 / 256.0);
colorOut = vec4(texture(sceneTex, vtf.sceneUv + indUv * vtf.strength.xy).rgb, 1.0); colorOut = vec4(texture(sceneTex, vtf.sceneUv + indUv * vtf.strength.xy).rgb, 1.0);
} }
@ -100,7 +100,7 @@ struct VertToFrag
float4 main(in VertToFrag vtf) : SV_Target0 float4 main(in VertToFrag vtf) : SV_Target0
{ {
float2 indUv = indTex.Sample(samp, vtf.indUv).xy * float2(2.0, 2.0) - float2(1.0 - 1.0 / 256.0, 1.0 - 1.0 / 256.0); float2 indUv = indTex.Sample(samp, vtf.indUv).ab * float2(2.0, 2.0) - float2(1.0 - 1.0 / 256.0, 1.0 - 1.0 / 256.0);
return float4(sceneTex.Sample(samp, vtf.sceneUv + indUv * vtf.strength.xy).rgb, 1.0); return float4(sceneTex.Sample(samp, vtf.sceneUv + indUv * vtf.strength.xy).rgb, 1.0);
} }
@ -151,6 +151,6 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
texture2d<float> sceneTex [[ texture(0) ]], texture2d<float> sceneTex [[ texture(0) ]],
texture2d<float> indTex [[ texture(1) ]]) texture2d<float> indTex [[ texture(1) ]])
{ {
float2 indUv = indTex.sample(samp, vtf.indUv).xy * float2(2.0) - float2(1.0 - 1.0 / 256.0); float2 indUv = indTex.sample(samp, vtf.indUv).ab * float2(2.0) - float2(1.0 - 1.0 / 256.0);
return float4(sceneTex.sample(samp, vtf.sceneUv + indUv * vtf.strength.xy).rgb, 1.0); return float4(sceneTex.sample(samp, vtf.sceneUv + indUv * vtf.strength.xy).rgb, 1.0);
} }

2
hecl

@ -1 +1 @@
Subproject commit 8393970b82fabcf604be5935368a77b949416ebb Subproject commit 180d304cfaf7261d7e29d9176a63e1734574d5e5

@ -1 +1 @@
Subproject commit c56b69627ca3daee510ca1c52aa7198634519d0a Subproject commit c2d69c84931174f016577369ba47ac1151005ce4