RTS: Fog of War

Dear community,

I started to create a repository to encourage RTS developments in BabylonJS by providing a basic template. There will also be playgrounds with single features of the RTS-game. One of my ideas is to add Fog of War, depending on how difficult it would be.

I only found this topic: Fog of war in hexagonal grid

Which does point me to use Shaders for FoW. Is this the simple way, but not horrible looking, and/or do we have examples on how this would be done? Because you should be able to combine it with the minimap.

1 Like

Hello, I’ve been doing some research on the subject some time ago, but haven’t attempted any implementation in Babylon yet. I found a really nice example at some point, a custom-made WebGL engine, that had a FOW implementation that caught my eye. It uses shaders & texture overlays as far as I can tell - I guess the same idea can be ported over to BJS with some effort. Hope it proves useful.

Engine: https://github.com/Usnul/meep
FoW part: meep/src/model/level/fow at master · Usnul/meep · GitHub

My problem is I have almost no experience in shaders, is it required? Also is there a preview?

This is how I wanted it to look on ground map:

Thanks to the Babylon Node Material, you don’t need to know how to write shader code to create shaders :smiley: I put together a very simple example of how you could achieve FOW using it: Babylon.js Node Material Editor (babylonjs.com), Simple Fog of War | Babylon.js Playground (babylonjs.com). It just checks the distance to the fog center position, which I set to be the camera’s position :slight_smile:

7 Likes

here is a topdown one that i have bookmarked, also using a nme material.

2 Likes

That is amazing. Just will take some time to get into it. For now I got more questions:

  1. How do you combine this Fog of war material with ground material?
  1. How can I create multiple revealer i.e. buildings and units etc.?

@jeremy-coleman Do I get it right, that your NME Material is preferred due to perfomance, because it uses only x- and z-dimension instead of Vector3? The issue could be that it does not work if I have hills on my map?

Its not mine, its just a top down alternative. I don’t think its any better, maybe actually worse. Imo fog of war should probably be one of the last things to think about. I think game/map state has to come first anyway and you’ll want to see the enemy AI working while u dev too.

2 Likes

Combining it with an existing material will be a bit trickier. You’d have to either recreate the material on NME and multiply the result of the distance calculation to it, or you use a Material Plugins | Babylon.js Documentation (babylonjs.com), but that requires writing shader code. Through that’s probably the route you’re going to have to go if you want an non-limited amount of revealers, as that is going to require a buffer. It’s not a lot of shader code through, I modified the NME example with the plugin to show you: Simple Fog of War | Babylon.js Playground (babylonjs.com) :smiley:

EDIT: Oh and about the performance, there’s no difference between passing a single Vector2 or Vector3. It would be a different story if you had, say, 100000 points to pass, then it could make a difference.

2 Likes

There is also a concern that changing data size can cause the processors to reallocate registers. Idk that much about hardware internals, but smarter people than me have said using 0’d out values and keeping data size the same can be a lot faster. Somewhat unrelated but supposedly this is even more true when using simd instructions, because there are fewer processor registers. I wonder if the same is true for shader code and if tint or the platform driver does any optimizing. Well, I broke ground on the rabbit hole, how far will we dig? Lol

1 Like

I do get this error:

BJS - [20:36:35]: Offending line [266] in fragment code: float d = length(vWorldPos.xyz - fogCenter);

Does it require WebGL 2 or can it run on WebGL 1, too?

Hint: With logarithmicDepthBuffer on FragmentShader I had to add this:

#extension GL_EXT_frag_depth : enable

Hmmm I only tested in WebGL2, didn’t know that length was a newer GLSL thing :open_mouth: can you show the complete error?

What you might need to know is this:

BJS - [21:18:41]: Error: FRAGMENT SHADER ERROR: 0:266: 'fogCenter' : undeclared identifier

But here also whole console output (68000+ characters):

downloadable font: OS/2: Adjusting head.macStyle (regular) to match fsSelection (font-family: "acumin-pro-condensed" style:normal weight:700 stretch:100 src index:0) source: https://use.typekit.net/af/69b3c5/00000000000000003b9acb0e/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3
Failed to create WebGL context: WebGL creation failed: 
* tryANGLE (FEATURE_FAILURE_EGL_NO_CONFIG)
* Exhausted GL driver options. (FEATURE_FAILURE_WEBGL_EXHAUSTED_DRIVERS) thinEngine.ts:925:44
WEBGL_debug_renderer_info is deprecated in Firefox and will be removed. Please use RENDERER. thinEngine.ts:1193:43
Babylon.js v5.31.2 - WebGL1 thinEngine.ts:1012:16
BJS - [21:18:40]: Unable to compile effect: logger.ts:103:29
BJS - [21:18:40]: Uniforms:  world, view, viewProjection, vEyePosition, vLightsType, vAmbientColor, vDiffuseColor, vSpecularColor, vEmissiveColor, visibility, vFogInfos, vFogColor, pointSize, vDiffuseInfos, vAmbientInfos, vOpacityInfos, vReflectionInfos, vEmissiveInfos, vSpecularInfos, vBumpInfos, vLightmapInfos, vRefractionInfos, mBones, vClipPlane, vClipPlane2, vClipPlane3, vClipPlane4, vClipPlane5, vClipPlane6, diffuseMatrix, ambientMatrix, opacityMatrix, reflectionMatrix, emissiveMatrix, specularMatrix, bumpMatrix, normalMatrix, lightmapMatrix, refractionMatrix, diffuseLeftColor, diffuseRightColor, opacityParts, reflectionLeftColor, reflectionRightColor, emissiveLeftColor, emissiveRightColor, refractionLeftColor, refractionRightColor, vReflectionPosition, vReflectionSize, vRefractionPosition, vRefractionSize, logarithmicDepthConstant, vTangentSpaceParams, alphaCutOff, boneTextureWidth, morphTargetTextureInfo, morphTargetTextureIndices, vDetailInfos, detailMatrix, fogCenter, previousWorld, previousViewProjection, mPreviousBones, vLightData0, vLightDiffuse0, vLightSpecular0, vLightDirection0, vLightFalloff0, vLightGround0, lightMatrix0, shadowsInfo0, depthValues0, viewFrustumZ0, cascadeBlendFactor0, lightSizeUVCorrection0, depthCorrection0, penumbraDarkness0, frustumLengths0, diffuseSampler, ambientSampler, opacitySampler, reflectionCubeSampler, reflection2DSampler, emissiveSampler, specularSampler, bumpSampler, lightmapSampler, refractionCubeSampler, refraction2DSampler, boneSampler, morphTargets, oitDepthSampler, oitFrontColorSampler, detailSampler, shadowSampler0, depthSampler0 logger.ts:103:29
BJS - [21:18:40]: Attributes:  position, normal logger.ts:103:29
BJS - [21:18:40]: Defines:

#define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0
#define SPECULARTERM
#define NORMAL
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0
logger.ts:103:29
BJS - [21:18:40]: Vertex code: logger.ts:103:29
BJS - [21:18:40]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0
#define SPECULARTERM
#define NORMAL
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME vertex:default
precision highp float;

uniform mat4 viewProjection;

uniform mat4 view;

#define ADDITIONAL_VERTEX_DECLARATION

#define CUSTOM_VERTEX_BEGIN

attribute vec3 position;

attribute vec3 normal;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform mat4 world;

varying vec3 vPositionW;

varying vec3 vNormalW;

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

varying vec3 vWorldPos;

#define CUSTOM_VERTEX_DEFINITIONS

void main(void) {

#define CUSTOM_VERTEX_MAIN_BEGIN

vec3 positionUpdated=position;

vec3 normalUpdated=normal;

#define CUSTOM_VERTEX_UPDATE_POSITION

#define CUSTOM_VERTEX_UPDATE_NORMAL

mat4 finalWorld=world;

vec4 worldPos=finalWorld*vec4(positionUpdated,1.0);

mat3 normalWorld=mat3(finalWorld);

vNormalW=normalize(normalWorld*normalUpdated);

#define CUSTOM_VERTEX_UPDATE_WORLDPOS

gl_Position=viewProjection*worldPos;

vPositionW=vec3(worldPos);

vec2 uvUpdated=vec2(0.,0.);

vWorldPos = worldPos.xyz;

#define CUSTOM_VERTEX_MAIN_END

}

logger.ts:103:29
BJS - [21:18:40]: Fragment code: logger.ts:103:29
BJS - [21:18:40]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0
#define SPECULARTERM
#define NORMAL
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME fragment:default
precision highp float;

uniform vec4 vEyePosition;

uniform vec4 vDiffuseColor;

uniform vec4 vSpecularColor;

uniform vec3 vEmissiveColor;

uniform vec3 vAmbientColor;

uniform float visibility;

#define CUSTOM_FRAGMENT_BEGIN

#define RECIPROCAL_PI2 0.15915494

varying vec3 vPositionW;

varying vec3 vNormalW;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

struct lightingInfo

{

vec3 diffuse;

vec3 specular;

};

lightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 lightVectorW;

float attenuation=1.0;

if (lightData.w==0.)

{

vec3 direction=lightData.xyz-vPositionW;

attenuation=max(0.,1.0-length(direction)/range);

lightVectorW=normalize(direction);

}

else

{

lightVectorW=normalize(-lightData.xyz);

}

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

lightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 direction=lightData.xyz-vPositionW;

vec3 lightVectorW=normalize(direction);

float attenuation=max(0.,1.0-length(direction)/range);

float cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));

if (cosAngle>=lightDirection.w)

{

cosAngle=max(0.,pow(cosAngle,lightData.w));

attenuation*=cosAngle;

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

result.diffuse=vec3(0.);

result.specular=vec3(0.);

return result;

}

lightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {

lightingInfo result;

float ndl=dot(vNormal,lightData.xyz)*0.5+0.5;

result.diffuse=mix(groundColor,diffuseColor,ndl);

vec3 angleW=normalize(viewDirectionW+lightData.xyz);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor;

return result;

}

#define inline

vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler,mat4 textureProjectionMatrix){

vec4 strq=textureProjectionMatrix*vec4(vPositionW,1.0);

strq/=strq.w;

vec3 textureColor=texture2D(projectionLightSampler,strq.xy).rgb;

return textureColor;

}

vec4 applyImageProcessing(vec4 result) {

result.rgb=toGammaSpace(result.rgb);

result.rgb=saturate(result.rgb);

return result;

}

varying vec3 vWorldPos;

#define CUSTOM_FRAGMENT_DEFINITIONS

void main(void) {

#define CUSTOM_FRAGMENT_MAIN_BEGIN

vec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);

vec4 baseColor=vec4(1.,1.,1.,1.);

vec3 diffuseColor=vDiffuseColor.rgb;

float alpha=vDiffuseColor.a;

vec3 normalW=normalize(vNormalW);

vec2 uvOffset=vec2(0.0,0.0);

#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE

vec3 baseAmbientColor=vec3(1.,1.,1.);

#define CUSTOM_FRAGMENT_BEFORE_LIGHTS

float glossiness=vSpecularColor.a;

vec3 specularColor=vSpecularColor.rgb;

vec3 diffuseBase=vec3(0.,0.,0.);

lightingInfo info;

vec3 specularBase=vec3(0.,0.,0.);

float shadow=1.;

info=computeHemisphericLighting(viewDirectionW,normalW,vLightData0,vLightDiffuse0.rgb,vLightSpecular0.rgb,vLightGround0,glossiness);

shadow=1.;

diffuseBase+=info.diffuse*shadow;

specularBase+=info.specular*shadow;

vec4 refractionColor=vec4(0.,0.,0.,1.);

vec4 reflectionColor=vec4(0.,0.,0.,1.);

vec3 emissiveColor=vEmissiveColor;

vec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;

vec3 finalSpecular=specularBase*specularColor;

vec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+refractionColor.rgb,alpha);

#define CUSTOM_FRAGMENT_BEFORE_FOG

color.rgb=max(color.rgb,0.);

color.a*=visibility;

#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR

gl_FragColor=color;

float d = length(vWorldPos.xyz - fogCenter);

d = (10.0 - d)/10.0;

gl_FragColor.rgb *= vec3(d);

#define CUSTOM_FRAGMENT_MAIN_END

}

logger.ts:103:29
BJS - [21:18:40]: Offending line [258] in fragment code: float d = length(vWorldPos.xyz - fogCenter);
logger.ts:103:29
BJS - [21:18:40]: Error: FRAGMENT SHADER ERROR: 0:258: 'fogCenter' : undeclared identifier
logger.ts:103:29
BJS - [21:18:40]: Trying next fallback. logger.ts:103:29
BJS - [21:18:40]: Unable to compile effect: logger.ts:103:29
BJS - [21:18:40]: Uniforms:  world, view, viewProjection, vEyePosition, vLightsType, vAmbientColor, vDiffuseColor, vSpecularColor, vEmissiveColor, visibility, vFogInfos, vFogColor, pointSize, vDiffuseInfos, vAmbientInfos, vOpacityInfos, vReflectionInfos, vEmissiveInfos, vSpecularInfos, vBumpInfos, vLightmapInfos, vRefractionInfos, mBones, vClipPlane, vClipPlane2, vClipPlane3, vClipPlane4, vClipPlane5, vClipPlane6, diffuseMatrix, ambientMatrix, opacityMatrix, reflectionMatrix, emissiveMatrix, specularMatrix, bumpMatrix, normalMatrix, lightmapMatrix, refractionMatrix, diffuseLeftColor, diffuseRightColor, opacityParts, reflectionLeftColor, reflectionRightColor, emissiveLeftColor, emissiveRightColor, refractionLeftColor, refractionRightColor, vReflectionPosition, vReflectionSize, vRefractionPosition, vRefractionSize, logarithmicDepthConstant, vTangentSpaceParams, alphaCutOff, boneTextureWidth, morphTargetTextureInfo, morphTargetTextureIndices, vDetailInfos, detailMatrix, fogCenter, previousWorld, previousViewProjection, mPreviousBones, vLightData0, vLightDiffuse0, vLightSpecular0, vLightDirection0, vLightFalloff0, vLightGround0, lightMatrix0, shadowsInfo0, depthValues0, viewFrustumZ0, cascadeBlendFactor0, lightSizeUVCorrection0, depthCorrection0, penumbraDarkness0, frustumLengths0, diffuseSampler, ambientSampler, opacitySampler, reflectionCubeSampler, reflection2DSampler, emissiveSampler, specularSampler, bumpSampler, lightmapSampler, refractionCubeSampler, refraction2DSampler, boneSampler, morphTargets, oitDepthSampler, oitFrontColorSampler, detailSampler, shadowSampler0, depthSampler0 logger.ts:103:29
BJS - [21:18:40]: Attributes:  position, normal logger.ts:103:29
BJS - [21:18:40]: Defines:

#define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0

#define NORMAL
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0
logger.ts:103:29
BJS - [21:18:40]: Vertex code: logger.ts:103:29
BJS - [21:18:40]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0

#define NORMAL
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME vertex:default
precision highp float;

uniform mat4 viewProjection;

uniform mat4 view;

#define ADDITIONAL_VERTEX_DECLARATION

#define CUSTOM_VERTEX_BEGIN

attribute vec3 position;

attribute vec3 normal;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}


float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform mat4 world;

varying vec3 vPositionW;

varying vec3 vNormalW;

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

varying vec3 vWorldPos;

#define CUSTOM_VERTEX_DEFINITIONS

void main(void) {

#define CUSTOM_VERTEX_MAIN_BEGIN

vec3 positionUpdated=position;

vec3 normalUpdated=normal;

#define CUSTOM_VERTEX_UPDATE_POSITION

#define CUSTOM_VERTEX_UPDATE_NORMAL

mat4 finalWorld=world;

vec4 worldPos=finalWorld*vec4(positionUpdated,1.0);

mat3 normalWorld=mat3(finalWorld);

vNormalW=normalize(normalWorld*normalUpdated);

#define CUSTOM_VERTEX_UPDATE_WORLDPOS

gl_Position=viewProjection*worldPos;

vPositionW=vec3(worldPos);

vec2 uvUpdated=vec2(0.,0.);

vWorldPos = worldPos.xyz;

#define CUSTOM_VERTEX_MAIN_END

}

logger.ts:103:29
BJS - [21:18:40]: Fragment code: logger.ts:103:29
BJS - [21:18:40]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0

#define NORMAL
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME fragment:default
precision highp float;

uniform vec4 vEyePosition;

uniform vec4 vDiffuseColor;

uniform vec4 vSpecularColor;

uniform vec3 vEmissiveColor;

uniform vec3 vAmbientColor;

uniform float visibility;

#define CUSTOM_FRAGMENT_BEGIN

#define RECIPROCAL_PI2 0.15915494

varying vec3 vPositionW;

varying vec3 vNormalW;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

struct lightingInfo

{

vec3 diffuse;

vec3 specular;

};

lightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 lightVectorW;

float attenuation=1.0;

if (lightData.w==0.)

{

vec3 direction=lightData.xyz-vPositionW;

attenuation=max(0.,1.0-length(direction)/range);

lightVectorW=normalize(direction);

}

else

{

lightVectorW=normalize(-lightData.xyz);

}

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

lightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 direction=lightData.xyz-vPositionW;

vec3 lightVectorW=normalize(direction);

float attenuation=max(0.,1.0-length(direction)/range);

float cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));

if (cosAngle>=lightDirection.w)

{

cosAngle=max(0.,pow(cosAngle,lightData.w));

attenuation*=cosAngle;

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

result.diffuse=vec3(0.);

result.specular=vec3(0.);

return result;

}

lightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {

lightingInfo result;

float ndl=dot(vNormal,lightData.xyz)*0.5+0.5;

result.diffuse=mix(groundColor,diffuseColor,ndl);

vec3 angleW=normalize(viewDirectionW+lightData.xyz);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor;

return result;

}

#define inline

vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler,mat4 textureProjectionMatrix){

vec4 strq=textureProjectionMatrix*vec4(vPositionW,1.0);

strq/=strq.w;

vec3 textureColor=texture2D(projectionLightSampler,strq.xy).rgb;

return textureColor;

}

vec4 applyImageProcessing(vec4 result) {

result.rgb=toGammaSpace(result.rgb);

result.rgb=saturate(result.rgb);

return result;

}

varying vec3 vWorldPos;

#define CUSTOM_FRAGMENT_DEFINITIONS

void main(void) {

#define CUSTOM_FRAGMENT_MAIN_BEGIN

vec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);

vec4 baseColor=vec4(1.,1.,1.,1.);

vec3 diffuseColor=vDiffuseColor.rgb;

float alpha=vDiffuseColor.a;

vec3 normalW=normalize(vNormalW);

vec2 uvOffset=vec2(0.0,0.0);

#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE

vec3 baseAmbientColor=vec3(1.,1.,1.);

#define CUSTOM_FRAGMENT_BEFORE_LIGHTS

float glossiness=vSpecularColor.a;

vec3 specularColor=vSpecularColor.rgb;

vec3 diffuseBase=vec3(0.,0.,0.);

lightingInfo info;

vec3 specularBase=vec3(0.,0.,0.);

float shadow=1.;

info=computeHemisphericLighting(viewDirectionW,normalW,vLightData0,vLightDiffuse0.rgb,vLightSpecular0.rgb,vLightGround0,glossiness);

shadow=1.;

diffuseBase+=info.diffuse*shadow;

specularBase+=info.specular*shadow;

vec4 refractionColor=vec4(0.,0.,0.,1.);

vec4 reflectionColor=vec4(0.,0.,0.,1.);

vec3 emissiveColor=vEmissiveColor;

vec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;

vec3 finalSpecular=specularBase*specularColor;

vec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+refractionColor.rgb,alpha);

#define CUSTOM_FRAGMENT_BEFORE_FOG

color.rgb=max(color.rgb,0.);

color.a*=visibility;

#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR

gl_FragColor=color;

float d = length(vWorldPos.xyz - fogCenter);

d = (10.0 - d)/10.0;

gl_FragColor.rgb *= vec3(d);

#define CUSTOM_FRAGMENT_MAIN_END

}

logger.ts:103:29
BJS - [21:18:40]: Offending line [258] in fragment code: float d = length(vWorldPos.xyz - fogCenter);
logger.ts:103:29
BJS - [21:18:40]: Error: FRAGMENT SHADER ERROR: 0:258: 'fogCenter' : undeclared identifier
logger.ts:103:29
WebGL warning: checkFramebufferStatus: Using format enabled by implicitly enabled extension: WEBGL_color_buffer_float. For maximal portability enable it explicitly.
WebGL warning: checkFramebufferStatus: Using format enabled by implicitly enabled extension: EXT_color_buffer_half_float. For maximal portability enable it explicitly.
WebGL warning: linkProgram: Must have a compiled fragment shader attached:
SHADER_INFO_LOG:
ERROR: 0:258: 'fogCenter' : undeclared identifier
2
BJS - [21:18:41]: Unable to compile effect: logger.ts:103:29
BJS - [21:18:41]: Uniforms:  world, view, viewProjection, vEyePosition, vLightsType, vAmbientColor, vDiffuseColor, vSpecularColor, vEmissiveColor, visibility, vFogInfos, vFogColor, pointSize, vDiffuseInfos, vAmbientInfos, vOpacityInfos, vReflectionInfos, vEmissiveInfos, vSpecularInfos, vBumpInfos, vLightmapInfos, vRefractionInfos, mBones, vClipPlane, vClipPlane2, vClipPlane3, vClipPlane4, vClipPlane5, vClipPlane6, diffuseMatrix, ambientMatrix, opacityMatrix, reflectionMatrix, emissiveMatrix, specularMatrix, bumpMatrix, normalMatrix, lightmapMatrix, refractionMatrix, diffuseLeftColor, diffuseRightColor, opacityParts, reflectionLeftColor, reflectionRightColor, emissiveLeftColor, emissiveRightColor, refractionLeftColor, refractionRightColor, vReflectionPosition, vReflectionSize, vRefractionPosition, vRefractionSize, logarithmicDepthConstant, vTangentSpaceParams, alphaCutOff, boneTextureWidth, morphTargetTextureInfo, morphTargetTextureIndices, vDetailInfos, detailMatrix, fogCenter, previousWorld, previousViewProjection, mPreviousBones, vLightData0, vLightDiffuse0, vLightSpecular0, vLightDirection0, vLightFalloff0, vLightGround0, lightMatrix0, shadowsInfo0, depthValues0, viewFrustumZ0, cascadeBlendFactor0, lightSizeUVCorrection0, depthCorrection0, penumbraDarkness0, frustumLengths0, diffuseSampler, ambientSampler, opacitySampler, reflectionCubeSampler, reflection2DSampler, emissiveSampler, specularSampler, bumpSampler, lightmapSampler, refractionCubeSampler, refraction2DSampler, boneSampler, morphTargets, oitDepthSampler, oitFrontColorSampler, detailSampler, shadowSampler0, depthSampler0 logger.ts:103:29
BJS - [21:18:41]: Attributes:  position, normal, uv logger.ts:103:29
BJS - [21:18:41]: Defines:

#define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSE
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0
#define SPECULARTERM
#define NORMAL
#define UV1
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0
logger.ts:103:29
BJS - [21:18:41]: Vertex code: logger.ts:103:29
BJS - [21:18:41]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSE
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0
#define SPECULARTERM
#define NORMAL
#define UV1
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME vertex:default
precision highp float;

uniform mat4 viewProjection;

uniform mat4 view;

uniform mat4 diffuseMatrix;

uniform vec2 vDiffuseInfos;

#define ADDITIONAL_VERTEX_DECLARATION

#define CUSTOM_VERTEX_BEGIN

attribute vec3 position;

attribute vec3 normal;

attribute vec2 uv;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform mat4 world;

varying vec2 vDiffuseUV;

varying vec3 vPositionW;

varying vec3 vNormalW;

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

varying vec3 vWorldPos;

#define CUSTOM_VERTEX_DEFINITIONS

void main(void) {

#define CUSTOM_VERTEX_MAIN_BEGIN

vec3 positionUpdated=position;

vec3 normalUpdated=normal;

vec2 uvUpdated=uv;

#define CUSTOM_VERTEX_UPDATE_POSITION

#define CUSTOM_VERTEX_UPDATE_NORMAL

mat4 finalWorld=world;

vec4 worldPos=finalWorld*vec4(positionUpdated,1.0);

mat3 normalWorld=mat3(finalWorld);

vNormalW=normalize(normalWorld*normalUpdated);

#define CUSTOM_VERTEX_UPDATE_WORLDPOS

gl_Position=viewProjection*worldPos;

vPositionW=vec3(worldPos);

if (vDiffuseInfos.x==0.)

{

vDiffuseUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));

}

vWorldPos = worldPos.xyz;

#define CUSTOM_VERTEX_MAIN_END

}

logger.ts:103:29
BJS - [21:18:41]: Fragment code: logger.ts:103:29
BJS - [21:18:41]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSE
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0
#define SPECULARTERM
#define NORMAL
#define UV1
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME fragment:default
precision highp float;

uniform vec4 vEyePosition;

uniform vec4 vDiffuseColor;

uniform vec4 vSpecularColor;

uniform vec3 vEmissiveColor;

uniform vec3 vAmbientColor;

uniform float visibility;

uniform vec2 vDiffuseInfos;

#define CUSTOM_FRAGMENT_BEGIN

#define RECIPROCAL_PI2 0.15915494

varying vec3 vPositionW;

varying vec3 vNormalW;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

struct lightingInfo

{

vec3 diffuse;

vec3 specular;

};

lightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 lightVectorW;

float attenuation=1.0;

if (lightData.w==0.)

{

vec3 direction=lightData.xyz-vPositionW;

attenuation=max(0.,1.0-length(direction)/range);

lightVectorW=normalize(direction);

}

else

{

lightVectorW=normalize(-lightData.xyz);

}

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

lightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 direction=lightData.xyz-vPositionW;

vec3 lightVectorW=normalize(direction);

float attenuation=max(0.,1.0-length(direction)/range);

float cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));

if (cosAngle>=lightDirection.w)

{

cosAngle=max(0.,pow(cosAngle,lightData.w));

attenuation*=cosAngle;

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

result.diffuse=vec3(0.);

result.specular=vec3(0.);

return result;

}

lightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {

lightingInfo result;

float ndl=dot(vNormal,lightData.xyz)*0.5+0.5;

result.diffuse=mix(groundColor,diffuseColor,ndl);

vec3 angleW=normalize(viewDirectionW+lightData.xyz);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor;

return result;

}

#define inline

vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler,mat4 textureProjectionMatrix){

vec4 strq=textureProjectionMatrix*vec4(vPositionW,1.0);

strq/=strq.w;

vec3 textureColor=texture2D(projectionLightSampler,strq.xy).rgb;

return textureColor;

}

varying vec2 vDiffuseUV;

uniform sampler2D diffuseSampler;

vec4 applyImageProcessing(vec4 result) {

result.rgb=toGammaSpace(result.rgb);

result.rgb=saturate(result.rgb);

return result;

}

varying vec3 vWorldPos;

#define CUSTOM_FRAGMENT_DEFINITIONS

void main(void) {

#define CUSTOM_FRAGMENT_MAIN_BEGIN

vec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);

vec4 baseColor=vec4(1.,1.,1.,1.);

vec3 diffuseColor=vDiffuseColor.rgb;

float alpha=vDiffuseColor.a;

vec3 normalW=normalize(vNormalW);

vec2 uvOffset=vec2(0.0,0.0);

baseColor=texture2D(diffuseSampler,vDiffuseUV+uvOffset);

#define CUSTOM_FRAGMENT_UPDATE_ALPHA

baseColor.rgb*=vDiffuseInfos.y;

#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE

vec3 baseAmbientColor=vec3(1.,1.,1.);

#define CUSTOM_FRAGMENT_BEFORE_LIGHTS

float glossiness=vSpecularColor.a;

vec3 specularColor=vSpecularColor.rgb;

vec3 diffuseBase=vec3(0.,0.,0.);

lightingInfo info;

vec3 specularBase=vec3(0.,0.,0.);

float shadow=1.;

info=computeHemisphericLighting(viewDirectionW,normalW,vLightData0,vLightDiffuse0.rgb,vLightSpecular0.rgb,vLightGround0,glossiness);

shadow=1.;

diffuseBase+=info.diffuse*shadow;

specularBase+=info.specular*shadow;

vec4 refractionColor=vec4(0.,0.,0.,1.);

vec4 reflectionColor=vec4(0.,0.,0.,1.);

vec3 emissiveColor=vEmissiveColor;

vec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;

vec3 finalSpecular=specularBase*specularColor;

vec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+refractionColor.rgb,alpha);

#define CUSTOM_FRAGMENT_BEFORE_FOG

color.rgb=max(color.rgb,0.);

color.a*=visibility;

#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR

gl_FragColor=color;

float d = length(vWorldPos.xyz - fogCenter);

d = (10.0 - d)/10.0;

gl_FragColor.rgb *= vec3(d);

#define CUSTOM_FRAGMENT_MAIN_END

}

logger.ts:103:29
BJS - [21:18:41]: Offending line [266] in fragment code: float d = length(vWorldPos.xyz - fogCenter);
logger.ts:103:29
BJS - [21:18:41]: Error: FRAGMENT SHADER ERROR: 0:266: 'fogCenter' : undeclared identifier
logger.ts:103:29
BJS - [21:18:41]: Trying next fallback. logger.ts:103:29
BJS - [21:18:41]: Unable to compile effect: logger.ts:103:29
BJS - [21:18:41]: Uniforms:  world, view, viewProjection, vEyePosition, vLightsType, vAmbientColor, vDiffuseColor, vSpecularColor, vEmissiveColor, visibility, vFogInfos, vFogColor, pointSize, vDiffuseInfos, vAmbientInfos, vOpacityInfos, vReflectionInfos, vEmissiveInfos, vSpecularInfos, vBumpInfos, vLightmapInfos, vRefractionInfos, mBones, vClipPlane, vClipPlane2, vClipPlane3, vClipPlane4, vClipPlane5, vClipPlane6, diffuseMatrix, ambientMatrix, opacityMatrix, reflectionMatrix, emissiveMatrix, specularMatrix, bumpMatrix, normalMatrix, lightmapMatrix, refractionMatrix, diffuseLeftColor, diffuseRightColor, opacityParts, reflectionLeftColor, reflectionRightColor, emissiveLeftColor, emissiveRightColor, refractionLeftColor, refractionRightColor, vReflectionPosition, vReflectionSize, vRefractionPosition, vRefractionSize, logarithmicDepthConstant, vTangentSpaceParams, alphaCutOff, boneTextureWidth, morphTargetTextureInfo, morphTargetTextureIndices, vDetailInfos, detailMatrix, fogCenter, previousWorld, previousViewProjection, mPreviousBones, vLightData0, vLightDiffuse0, vLightSpecular0, vLightDirection0, vLightFalloff0, vLightGround0, lightMatrix0, shadowsInfo0, depthValues0, viewFrustumZ0, cascadeBlendFactor0, lightSizeUVCorrection0, depthCorrection0, penumbraDarkness0, frustumLengths0, diffuseSampler, ambientSampler, opacitySampler, reflectionCubeSampler, reflection2DSampler, emissiveSampler, specularSampler, bumpSampler, lightmapSampler, refractionCubeSampler, refraction2DSampler, boneSampler, morphTargets, oitDepthSampler, oitFrontColorSampler, detailSampler, shadowSampler0, depthSampler0 logger.ts:103:29
BJS - [21:18:41]: Attributes:  position, normal, uv logger.ts:103:29
BJS - [21:18:41]: Defines:

#define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSE
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0

#define NORMAL
#define UV1
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0
logger.ts:103:29
BJS - [21:18:41]: Vertex code: logger.ts:103:29
BJS - [21:18:41]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSE
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0

#define NORMAL
#define UV1
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME vertex:default
precision highp float;

uniform mat4 viewProjection;

uniform mat4 view;

uniform mat4 diffuseMatrix;

uniform vec2 vDiffuseInfos;

#define ADDITIONAL_VERTEX_DECLARATION

#define CUSTOM_VERTEX_BEGIN

attribute vec3 position;

attribute vec3 normal;

attribute vec2 uv;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform mat4 world;

varying vec2 vDiffuseUV;

varying vec3 vPositionW;

varying vec3 vNormalW;

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

varying vec3 vWorldPos;

#define CUSTOM_VERTEX_DEFINITIONS

void main(void) {

#define CUSTOM_VERTEX_MAIN_BEGIN

vec3 positionUpdated=position;

vec3 normalUpdated=normal;

vec2 uvUpdated=uv;

#define CUSTOM_VERTEX_UPDATE_POSITION

#define CUSTOM_VERTEX_UPDATE_NORMAL

mat4 finalWorld=world;

vec4 worldPos=finalWorld*vec4(positionUpdated,1.0);

mat3 normalWorld=mat3(finalWorld);

vNormalW=normalize(normalWorld*normalUpdated);

#define CUSTOM_VERTEX_UPDATE_WORLDPOS

gl_Position=viewProjection*worldPos;

vPositionW=vec3(worldPos);

if (vDiffuseInfos.x==0.)

{

vDiffuseUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));

}

vWorldPos = worldPos.xyz;

#define CUSTOM_VERTEX_MAIN_END

}

logger.ts:103:29
BJS - [21:18:41]: Fragment code: logger.ts:103:29
BJS - [21:18:41]: #define MATERIALPLUGIN_2
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define FogOfWar
#define DIFFUSE
#define DIFFUSEDIRECTUV 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define EMISSIVEDIRECTUV 0
#define SPECULARDIRECTUV 0
#define BUMPDIRECTUV 0

#define NORMAL
#define UV1
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define LIGHTMAPDIRECTUV 0
#define NUM_MORPH_INFLUENCERS 0
#define ALPHABLEND
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_SQRT_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define LIGHT0
#define HEMILIGHT0

#define SHADER_NAME fragment:default
precision highp float;

uniform vec4 vEyePosition;

uniform vec4 vDiffuseColor;

uniform vec4 vSpecularColor;

uniform vec3 vEmissiveColor;

uniform vec3 vAmbientColor;

uniform float visibility;

uniform vec2 vDiffuseInfos;

#define CUSTOM_FRAGMENT_BEGIN

#define RECIPROCAL_PI2 0.15915494

varying vec3 vPositionW;

varying vec3 vNormalW;

const float PI=3.1415926535897932384626433832795;

const float HALF_MIN=5.96046448e-08;

const float LinearEncodePowerApprox=2.2;

const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;

const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);

const float Epsilon=0.0000001;

#define saturate(x) clamp(x,0.0,1.0)

#define absEps(x) abs(x)+Epsilon

#define maxEps(x) max(x,Epsilon)

#define saturateEps(x) clamp(x,Epsilon,1.0)

mat3 transposeMat3(mat3 inMatrix) {

vec3 i0=inMatrix[0];

vec3 i1=inMatrix[1];

vec3 i2=inMatrix[2];

mat3 outMatrix=mat3(

vec3(i0.x,i1.x,i2.x),

vec3(i0.y,i1.y,i2.y),

vec3(i0.z,i1.z,i2.z)

);

return outMatrix;

}

mat3 inverseMat3(mat3 inMatrix) {

float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];

float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];

float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];

float b01=a22*a11-a12*a21;

float b11=-a22*a10+a12*a20;

float b21=a21*a10-a11*a20;

float det=a00*b01+a01*b11+a02*b21;

return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),

b11,(a22*a00-a02*a20),(-a12*a00+a02*a10),

b21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;

}

float toLinearSpace(float color)

{

return pow(color,LinearEncodePowerApprox);

}

vec3 toLinearSpace(vec3 color)

{

return pow(color,vec3(LinearEncodePowerApprox));

}

vec4 toLinearSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);

}

float toGammaSpace(float color)

{

return pow(color,GammaEncodePowerApprox);

}

vec3 toGammaSpace(vec3 color)

{

return pow(color,vec3(GammaEncodePowerApprox));

}

vec4 toGammaSpace(vec4 color)

{

return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);

}

float square(float value)

{

return value*value;

}

vec3 square(vec3 value)

{

return value*value;

}

float pow5(float value) {

float sq=value*value;

return sq*sq*value;

}

float getLuminance(vec3 color)

{

return clamp(dot(color,LuminanceEncodeApprox),0.,1.);

}

float getRand(vec2 seed) {

return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);

}

float dither(vec2 seed,float varianceAmount) {

float rand=getRand(seed);

float normVariance=varianceAmount/255.0;

float dither=mix(-normVariance,normVariance,rand);

return dither;

}

const float rgbdMaxRange=255.0;

vec4 toRGBD(vec3 color) {

float maxRGB=maxEps(max(color.r,max(color.g,color.b)));

float D =max(rgbdMaxRange/maxRGB,1.);

D =clamp(floor(D)/255.0,0.,1.);

vec3 rgb=color.rgb*D;

rgb=toGammaSpace(rgb);

return vec4(clamp(rgb,0.,1.),D);

}

vec3 fromRGBD(vec4 rgbd) {

rgbd.rgb=toLinearSpace(rgbd.rgb);

return rgbd.rgb/rgbd.a;

}

vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {

vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;

vec3 halfSize=cubeSize*0.5;

vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;

vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;

vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);

float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);

vec3 intersectPositionWS=vertexPos+origVec*distance;

return intersectPositionWS-cubePos;

}

uniform vec4 vLightData0;

uniform vec4 vLightDiffuse0;

uniform vec4 vLightSpecular0;

uniform vec3 vLightGround0;

struct lightingInfo

{

vec3 diffuse;

vec3 specular;

};

lightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 lightVectorW;

float attenuation=1.0;

if (lightData.w==0.)

{

vec3 direction=lightData.xyz-vPositionW;

attenuation=max(0.,1.0-length(direction)/range);

lightVectorW=normalize(direction);

}

else

{

lightVectorW=normalize(-lightData.xyz);

}

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

lightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {

lightingInfo result;

vec3 direction=lightData.xyz-vPositionW;

vec3 lightVectorW=normalize(direction);

float attenuation=max(0.,1.0-length(direction)/range);

float cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));

if (cosAngle>=lightDirection.w)

{

cosAngle=max(0.,pow(cosAngle,lightData.w));

attenuation*=cosAngle;

float ndl=max(0.,dot(vNormal,lightVectorW));

result.diffuse=ndl*diffuseColor*attenuation;

vec3 angleW=normalize(viewDirectionW+lightVectorW);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor*attenuation;

return result;

}

result.diffuse=vec3(0.);

result.specular=vec3(0.);

return result;

}

lightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {

lightingInfo result;

float ndl=dot(vNormal,lightData.xyz)*0.5+0.5;

result.diffuse=mix(groundColor,diffuseColor,ndl);

vec3 angleW=normalize(viewDirectionW+lightData.xyz);

float specComp=max(0.,dot(vNormal,angleW));

specComp=pow(specComp,max(1.,glossiness));

result.specular=specComp*specularColor;

return result;

}

#define inline

vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler,mat4 textureProjectionMatrix){

vec4 strq=textureProjectionMatrix*vec4(vPositionW,1.0);

strq/=strq.w;

vec3 textureColor=texture2D(projectionLightSampler,strq.xy).rgb;

return textureColor;

}

varying vec2 vDiffuseUV;

uniform sampler2D diffuseSampler;

vec4 applyImageProcessing(vec4 result) {

result.rgb=toGammaSpace(result.rgb);

result.rgb=saturate(result.rgb);

return result;

}

varying vec3 vWorldPos;

#define CUSTOM_FRAGMENT_DEFINITIONS

void main(void) {

#define CUSTOM_FRAGMENT_MAIN_BEGIN

vec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);

vec4 baseColor=vec4(1.,1.,1.,1.);

vec3 diffuseColor=vDiffuseColor.rgb;

float alpha=vDiffuseColor.a;

vec3 normalW=normalize(vNormalW);

vec2 uvOffset=vec2(0.0,0.0);

baseColor=texture2D(diffuseSampler,vDiffuseUV+uvOffset);

#define CUSTOM_FRAGMENT_UPDATE_ALPHA

baseColor.rgb*=vDiffuseInfos.y;

#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE

vec3 baseAmbientColor=vec3(1.,1.,1.);

#define CUSTOM_FRAGMENT_BEFORE_LIGHTS

float glossiness=vSpecularColor.a;

vec3 specularColor=vSpecularColor.rgb;

vec3 diffuseBase=vec3(0.,0.,0.);

lightingInfo info;

vec3 specularBase=vec3(0.,0.,0.);

float shadow=1.;

info=computeHemisphericLighting(viewDirectionW,normalW,vLightData0,vLightDiffuse0.rgb,vLightSpecular0.rgb,vLightGround0,glossiness);

shadow=1.;

diffuseBase+=info.diffuse*shadow;

specularBase+=info.specular*shadow;

vec4 refractionColor=vec4(0.,0.,0.,1.);

vec4 reflectionColor=vec4(0.,0.,0.,1.);

vec3 emissiveColor=vEmissiveColor;

vec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;

vec3 finalSpecular=specularBase*specularColor;

vec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor.rgb+refractionColor.rgb,alpha);

#define CUSTOM_FRAGMENT_BEFORE_FOG

color.rgb=max(color.rgb,0.);

color.a*=visibility;

#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR

gl_FragColor=color;

float d = length(vWorldPos.xyz - fogCenter);

d = (10.0 - d)/10.0;

gl_FragColor.rgb *= vec3(d);

#define CUSTOM_FRAGMENT_MAIN_END

}

logger.ts:103:29
BJS - [21:18:41]: Offending line [266] in fragment code: float d = length(vWorldPos.xyz - fogCenter);
logger.ts:103:29
BJS - [21:18:41]: Error: FRAGMENT SHADER ERROR: 0:266: 'fogCenter' : undeclared identifier
logger.ts:103:29
WebGL warning: linkProgram: Must have a compiled fragment shader attached:
SHADER_INFO_LOG:
ERROR: 0:266: 'fogCenter' : undeclared identifier
2

Can you try checking if this one works: Simple Fog of War | Babylon.js Playground (babylonjs.com)? I had copied the template of another Material Plugin but forgot to change a name, so a variable declaration was missing. Seems like it works without it in WebGL2 but not 1 :thinking:

1 Like

Seems like it works without it in WebGL2 but not 1

Yes, the:

#ifdef FogOfWar
    uniform vec3 fogCenter;
#endif

part is only used when uniform buffers are not supported. Uniform buffer support is required in WebGL 2 but not in 1, so it’s possible it’s not available.

3 Likes

oooh thanks for the explanation Alexis! :smiley:

The examples here pass a single fogCenter to the shader. In RTS game @Takemura wants to build, I guess every player/ally units expand vision.

Passing an vec3 array of unit positions is supported on WebGL2, but not WebGL1. Also if this array size is at scale of tens and hundreds, it adds overhead to loop through this array in fragment shader to check if fogOfWar or regular color should be applied. In addition to fog of war, you might also want to have custom fragment shader for highlighting a group of selected units. That will also add more overhead.

The other problem with passing vec3 array unifrom is it is good with blending circles or images with a central point on terrain. But difficult to draw for example path trailing as arrowed lines with multiple turning points.

From my experience, it is more efficient to draw on a dynamic texture, and blend it with the terrain. It is also easier to draw arrowed lines. The problem is if the terrain is large, high resolution dynamic texture also becomes equally slow as passing vec3 array as uniform. I haven’t got time to test if it is more efficient to work with multiple lower resolution dynamic textures. I also don’t know if dynamic texture uniform is the right approach. Does anyone know if there is better way of doing this?

2 Likes

:slight_smile:

3 Likes

Dox’d