Repe [T3DU] Update - 31f26d171bba0355ce2a77031e3aad4c64dbc7e9

This commit is contained in:
2026-09-04 10:46:13 -07:00
parent c915312901
commit 0460b9d587
482 changed files with 27797 additions and 3226 deletions

View File

@ -10,9 +10,9 @@
const int samples = 8; // Samples on the first ring
const int rings = 6; // Ring count
const vec2 focus = vec2(0.5, 0.5);
//const vec2 focus = vec2(0.5, 0.5);
const float coc = 0.03; // Circle of confusion size in mm (35mm film = 0.03mm)
const float maxblur = 1.0;
//const float maxblur = 1.0;
const float threshold = 0.5; // Highlight threshold
const float gain = 2.0; // Highlight gain
const float bias = 0.5; // Bokeh edge bias
@ -41,7 +41,9 @@ vec3 dof(
const bool autoFocus,
const float DOFDistance,
const float DOFLength,
const float DOFFStop) {
const float DOFFStop,
const vec2 focus,
const float maxblur) {
float depth = linearize(gdepth, cameraProj);
float fDepth = 0.0;
@ -85,7 +87,6 @@ vec3 dof(
float pw = (cos(float(j) * step) * float(i));
float ph = (sin(float(j) * step) * float(i));
float p = 1.0;
// if (pentagon) p = penta(vec2(pw, ph));
blurredCol += color(texCoord + vec2(pw * w, ph * h), blur, tex, texStep) * mix(1.0, (float(i)) / (float(rings)), bias) * p;
s += 1.0 * mix(1.0, (float(i)) / (float(rings)), bias) * p;
}

View File

@ -28,15 +28,14 @@
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifdef _Spot
#ifndef _LTC
uniform sampler2DShadow shadowMapSpot[1];
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapSpotTransparent[1];
#endif
uniform mat4 LWVPSpotArray[1];
#if defined(_Spot) || defined(_LTC)
uniform sampler2DShadow shadowMapSpot[1];
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapSpotTransparent[1];
#endif
#else
uniform mat4 LWVPSpotArray[1];
#endif
#ifndef _Spot
uniform samplerCubeShadow shadowMapPoint[1];
#ifdef _ShadowMapTransparent
uniform samplerCube shadowMapPointTransparent[1];
@ -45,41 +44,35 @@
#endif
#endif
#ifdef _Clusters
#ifdef _SingleAtlas
//!uniform sampler2DShadow shadowMapAtlas;
#ifdef _ShadowMapTransparent
//!uniform sampler2D shadowMapAtlasTransparent;
#endif
#endif
#ifndef _SinglePoint
uniform vec2 lightProj;
#endif
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasPoint;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasPointTransparent;
#endif
#endif
#else
uniform samplerCubeShadow shadowMapPoint[4];
#ifdef _ShadowMapTransparent
uniform samplerCube shadowMapPointTransparent[4];
#endif
#endif
#ifdef _Spot
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
uniform sampler2DShadow shadowMapAtlasPoint;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasSpotTransparent;
uniform sampler2D shadowMapAtlasPointTransparent;
#endif
#endif
#else
uniform samplerCubeShadow shadowMapPoint[4];
#ifdef _ShadowMapTransparent
uniform samplerCube shadowMapPointTransparent[4];
#endif
#endif
#if defined(_Spot) || defined(_LTC)
#ifdef _ShadowMapAtlas
#ifndef _SingleAtlas
uniform sampler2DShadow shadowMapAtlasSpot;
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapAtlasSpotTransparent;
#endif
#endif
#else
uniform sampler2DShadow shadowMapSpot[4];
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapSpotTransparent[4];
#endif
uniform sampler2DShadow shadowMapSpot[4];
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapSpotTransparent[4];
#endif
#endif
uniform mat4 LWVPSpotArray[maxLightsCluster];
#endif
@ -93,15 +86,6 @@ uniform vec3 lightArea2;
uniform vec3 lightArea3;
uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
#ifdef _ShadowMap
#ifdef _SinglePoint
uniform sampler2DShadow shadowMapSpot[1];
#ifdef _ShadowMapTransparent
uniform sampler2D shadowMapSpotTransparent[1];
#endif
uniform mat4 LWVPSpotArray[1];
#endif
#endif
#endif
vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
@ -143,37 +127,41 @@ vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV
#ifdef _VoxelPass
vec3 direct = vec3(dotNL);
#else
#ifdef _LTC
float theta = acos(dotNV);
vec2 tuv = vec2(rough, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
vec4 t = textureLod(sltcMat, tuv, 0.0);
mat3 invM = mat3(
vec3(1.0, 0.0, t.y),
vec3(0.0, t.z, 0.0),
vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
#else
vec3 standard;
#ifdef _Anisotropy
vec3 direct;
if (abs(anisotropy) > 0.001 && dot(tangent, tangent) > 0.001) {
vec3 bitangent = normalize(cross(n, tangent));
direct = lambertDiffuseBRDF(albedo, dotNL) +
standard = lambertDiffuseBRDF(albedo, dotNL) +
anisotropicBRDF(f0, rough, anisotropy, anisoRot,
tangent, bitangent, n, l, v, dotNL, dotNV) * spec;
} else {
direct = lambertDiffuseBRDF(albedo, dotNL) +
standard = lambertDiffuseBRDF(albedo, dotNL) +
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
}
#else
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
standard = lambertDiffuseBRDF(albedo, dotNL) +
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
#endif
#ifdef _Spot
if (isSpot) {
standard *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
}
#endif
vec3 area = vec3(0.0);
#ifdef _LTC
float theta = acos(dotNV);
vec2 tuv = vec2(rough, theta / (0.5 * PI)) * LUT_SCALE + LUT_BIAS;
vec4 t = textureLod(sltcMat, tuv, 0.0);
mat3 invM = mat3(vec3(1.0, 0.0, t.y), vec3(0.0, t.z, 0.0), vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
area = albedo * ltcdiff + ltcspec * spec * 0.05;
#endif
vec3 direct = standard + area;
// before attenuate/shadow so everything is properly shadowed in one pass
#ifdef _ExtBRDF
float layerWeight;
@ -195,26 +183,31 @@ vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV
direct *= attenuate(dist);
direct *= min(lightCol, vec3(100.0));
#ifdef _LTC
#ifdef _LightIES
direct *= iesAttenuation(-l);
#endif
vec3 visibility = vec3(1.0);
#ifdef _ShadowMap
if (receiveShadow) {
if (receiveShadow) {
#if defined(_Spot) || defined(_LTC)
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10.0, 1.0);
visibility = shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
tileBounds = tileBoundsSpotArray[index];
direct *= shadowTest(
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10.0, 1.0);
#ifdef _ShadowMapAtlas
tileBounds = tileBoundsSpotArray[index];
visibility = shadowTest(
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
@ -233,147 +226,48 @@ vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV
, transparent
#endif
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[2],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[3],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
l_out = l;
return direct;
#endif
#ifdef _Spot
if (isSpot) {
direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
#ifdef _ShadowMap
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#ifdef _Clusters
vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
#ifdef _ShadowMapAtlas
tileBounds = tileBoundsSpotArray[index];
direct *= shadowTest(
#else
if (index == 0) visibility = shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
#else
shadowMapAtlas, shadowMapAtlasTransparent
shadowMapSpotTransparent[0],
#endif
#else
#ifndef _SingleAtlas
shadowMapAtlasSpot
#else
shadowMapAtlas
#endif
#endif
, lPos.xyz / lPos.w, bias
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) visibility = shadowTest(shadowMapSpot[1],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) visibility = shadowTest(shadowMapSpot[2],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[2],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) visibility = shadowTest(shadowMapSpot[3],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[3],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#else
if (index == 0) direct *= shadowTest(shadowMapSpot[0],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[0],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= shadowTest(shadowMapSpot[1],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[1],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= shadowTest(shadowMapSpot[2],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[2],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= shadowTest(shadowMapSpot[3],
#ifdef _ShadowMapTransparent
shadowMapSpotTransparent[3],
#endif
lPos.xyz / lPos.w, bias
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
l_out = l;
return direct;
}
#endif
#ifdef _LightIES
direct *= iesAttenuation(-l);
#endif
#ifdef _ShadowMap
if (receiveShadow) {
#endif
#else
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0],
visibility = PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
@ -383,10 +277,9 @@ vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV
#endif
);
#endif
#endif
#ifdef _Clusters
#ifdef _ShadowMapAtlas
direct *= PCFFakeCube(
visibility = PCFFakeCube(
#ifdef _ShadowMapTransparent
#ifndef _SingleAtlas
shadowMapAtlasPoint, shadowMapAtlasPointTransparent
@ -406,49 +299,50 @@ vec3 sampleLightCore(const vec3 p, const vec3 n, const vec3 v, const float dotNV
#endif
);
#else
if (index == 0) direct *= PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[1],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[2],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[3],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
if (index == 0) visibility = PCFCube(shadowMapPoint[0],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[0],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 1) visibility = PCFCube(shadowMapPoint[1],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[1],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 2) visibility = PCFCube(shadowMapPoint[2],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[2],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
else if (index == 3) visibility = PCFCube(shadowMapPoint[3],
#ifdef _ShadowMapTransparent
shadowMapPointTransparent[3],
#endif
ld, -l, bias, lightProj, n
#ifdef _ShadowMapTransparent
, transparent
#endif
);
#endif
#endif
}
#endif
}
#endif
l_out = l;
return direct;
return direct * visibility;
}
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,

View File

@ -1,41 +1,81 @@
/*
https://github.com/JonasFolletete/glsl-triplanar-mapping
vec4 boxProjection(sampler2D image, vec3 normal, vec3 coord, float blend) {
vec3 n = normalize(normal);
vec3 N = abs(n);
vec4 color1, color2, color3;
MIT License
vec2 uv = coord.yz;
if (n.x < 0.0) {
uv.x = 1.0 - uv.x;
}
color1 = texture(image, uv);
Copyright (c) 2018 Jonas Folletête
uv = coord.xz;
if (n.y > 0.0) {
uv.x = 1.0 - uv.x;
}
color2 = texture(image, uv);
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
uv = vec2(coord.y, 1.0 - coord.x);
if (n.z > 0.0) {
uv.x = 1.0 - uv.x;
}
color3 = texture(image, uv);
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
N /= max(dot(N, vec3(1.0)), 1e-8);
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
float limit = 0.5 + 0.5 * clamp(blend, 0.0, 1.0);
vec3 weight;
weight = N.xyz / (N.xyx + N.yzz);
weight = clamp((weight - 0.5 * (1.0 - clamp(blend, 0.0, 1.0))) / max(1e-8, clamp(blend, 0.0, 1.0)), 0.0, 1.0);
vec3 blendNormal(vec3 normal) {
vec3 blending = abs(normal);
blending = normalize(max(blending, 0.00001));
blending /= vec3(blending.x + blending.y + blending.z);
return blending;
if (N.z < (1.0 - limit) * (N.y + N.x)) {
weight.z = 0.0;
weight.y = 1.0 - weight.x;
}
else if (N.x < (1.0 - limit) * (N.y + N.z)) {
weight.x = 0.0;
weight.z = 1.0 - weight.y;
}
else if (N.y < (1.0 - limit) * (N.x + N.z)) {
weight.y = 0.0;
weight.x = 1.0 - weight.z;
}
else {
weight = ((2.0 - limit) * N + (limit - 1.0)) / max(1e-8, clamp(blend, 0.0, 1.0));
}
return color1 * weight.x + color2 * weight.y + color3 * weight.z;
}
vec3 triplanarMapping (sampler2D ImageTexture, vec3 normal, vec3 position) {
vec3 normalBlend = blendNormal(normal);
vec3 xColor = texture(ImageTexture, position.yz).rgb;
vec3 yColor = texture(ImageTexture, position.xz).rgb;
vec3 zColor = texture(ImageTexture, position.xy).rgb;
return (xColor * normalBlend.x + yColor * normalBlend.y + zColor * normalBlend.z);
vec2 sphericalMapping(vec3 coord) {
vec3 vin = coord * 2.0 - vec3(1.0);
float len = length(vin);
float v, u;
if (len > 0.0) {
if (vin.x == 0.0 && vin.y == 0.0) {
u = 0.0;
}
else {
u = (1.0 - atan(vin.x, vin.y) / PI) * 0.5;
}
v = acos(clamp(vin.z / len, -1.0, 1.0)) / PI;
}
else {
v = u = 0.0;
}
return vec2(u, v);
}
vec2 tubeMapping(vec3 coord) {
vec3 vin = coord * 2.0 - vec3(1.0);
float u, v;
v = - (vin.z + 1.0) * 0.5;
float len = sqrt(vin.x * vin.x + vin.y * vin.y);
if (len > 0.0) {
u = (1.0 - (atan(vin.x / len, vin.y / len) / PI)) * 0.5;
}
else {
v = u = 0.0;
}
return vec2(u, v);
}

View File

@ -19,6 +19,14 @@ vec2 envMapEquirect(const vec3 normal) {
return vec2(theta / PI2, phi / PI);
}
vec2 envMapMirror(const vec3 co) {
vec3 nco = normalize(co);
nco.y -= 1.0;
float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
nco /= max(1e-8, div);
return 0.5 * nco.xz + 0.5;
}
float rand(const vec2 co) { // Unreliable
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}

View File

@ -4,6 +4,36 @@ uniform vec2 morphScaleOffset;
uniform vec2 morphDataDim;
uniform vec4 morphWeights[8];
void getMorphedVertex(vec2 uvCoord, inout vec3 A, vec4 imorph) {
vec3 morph = texture(morphDataPos, uvCoord).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += imorph.x * morph;
morph = texture(morphDataPos, vec2(uvCoord.x, uvCoord.y - morphDataDim.y)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += imorph.y * morph;
morph = texture(morphDataPos, vec2(uvCoord.x, uvCoord.y - 2.0 * morphDataDim.y)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += imorph.z * morph;
morph = texture(morphDataPos, vec2(uvCoord.x, uvCoord.y - 3.0 * morphDataDim.y)).rgb * morphScaleOffset.x + morphScaleOffset.y;
A += imorph.w * morph;
}
void getMorphedNormal(vec2 uvCoord, vec3 oldNor, inout vec3 morphNor, vec4 imorph) {
vec3 norm = oldNor + imorph.x * (texture(morphDataNor, uvCoord).rgb * 2.0 - 1.0);
morphNor += norm;
norm = oldNor + imorph.y * (texture(morphDataNor, vec2(uvCoord.x, uvCoord.y - morphDataDim.y)).rgb * 2.0 - 1.0);
morphNor += norm;
norm = oldNor + imorph.z * (texture(morphDataNor, vec2(uvCoord.x, uvCoord.y - 2.0 * morphDataDim.y)).rgb * 2.0 - 1.0);
morphNor += norm;
norm = oldNor + imorph.w * (texture(morphDataNor, vec2(uvCoord.x, uvCoord.y - 3.0 * morphDataDim.y)).rgb * 2.0 - 1.0);
morphNor += norm;
morphNor = normalize(morphNor);
}
void getMorphedVertex(vec2 uvCoord, inout vec3 A){
vec3 totalDelta = vec3(0.0);
for(int i = 0; i<8; i++ )