Visual glitching with shaders in vulcan?

Originally I was developing a project in the 2021 TD version pre vulcan, and now I am trying to get it working again in the 2022 Vulcan series.

It’s glitching out in strange ways, shader material preview does as well. There are no errors though.

What’s a good way to go about troubleshooting this? Is slowly commenting out functions and calls the best way? Feels tedious but I imagine I can get there eventually.

td_glsl_glitching.gif

Here’s a full size video of what I’m talking about:
https://www.enviral-design.com/downloads/TMP/td_glsl_glitching.mp4

Can you post the shader and I’ll see if there is anything obvious?

Totally!

Vertex:

#include <defines_fs>

void toTangentFrame(const highp vec4 q, out highp vec3 n) {
    n = vec3(0.0, 0.0, 1.0) +
        vec3(2.0, -2.0, -2.0) * q.x * q.zwx +
        vec3(2.0, 2.0, -2.0) * q.y * q.wzy;
}

void toTangentFrame(const highp vec4 q, out highp vec3 n, out highp vec3 t) {
    toTangentFrame(q, n);
    t = vec3(1.0, 0.0, 0.0) +
        vec3(-2.0, 2.0, -2.0) * q.y * q.yxw +
        vec3(-2.0, 2.0, 2.0) * q.z * q.zwx;
}

in vec4 T;
uniform vec3 uNdcOffset;

out Vertex
{
	vec4 color;
	mat3 tangentToWorld;
	vec3 cameraToPixelTangentSpace;
	vec3 worldSpacePos;
	vec3 worldSpaceNormal;
	vec4 worldSpaceTangent;
	vec2 texCoord0;
	flat int cameraIndex;

} oVert;

void main()
{

	{ // Avoid duplicate variable defs
		vec3 texcoord = TDInstanceTexCoord(uv[0]);
		oVert.texCoord0.st = texcoord.st;
	}
	
	// First deform the vertex and normal
	// TDDeform always returns values in world space
	vec4 worldSpacePos = TDDeform(P);
	vec3 uvUnwrapCoord = TDInstanceTexCoord(TDUVUnwrapCoord());
	gl_Position = TDWorldToProj(worldSpacePos, uvUnwrapCoord);
	gl_Position.xyz -= uNdcOffset;

	// This is here to ensure we only execute lighting etc. code
	// when we need it. If picking is active we don't need lighting, so
	// this entire block of code will be ommited from the compile.
	// The TD_PICKING_ACTIVE define will be set automatically when
	// picking is active.
#ifndef TD_PICKING_ACTIVE

	int cameraIndex = TDCameraIndex();
	oVert.cameraIndex = cameraIndex;
	oVert.worldSpacePos.xyz = worldSpacePos.xyz;
	oVert.color = TDInstanceColor(Cd);
	vec3 worldSpaceNorm = normalize(TDDeformNorm(N));
	// oVert.worldSpaceNorm.xyz = worldSpaceNorm;

	vec3 worldSpaceTangent = TDDeformNorm(T.xyz);
	worldSpaceTangent.xyz = normalize(worldSpaceTangent.xyz);
	// Create the matrix that will convert vectors and positions from
	// tangent space to world space
	// T.w contains the handedness of the tangent
	// It will be used to flip the bi-normal if needed
	mat3 tangentToWorld = TDCreateTBNMatrix(worldSpaceNorm, worldSpaceTangent, T.w);
	oVert.tangentToWorld = tangentToWorld;

	oVert.worldSpaceNormal = worldSpaceNorm;
	oVert.worldSpaceTangent.xyz = worldSpaceTangent.xyz;
	oVert.worldSpaceTangent.w = T.w;

#if defined(HEIGHT_LEVEL_MAP) || defined(HEIGHT_LEVEL_TOP)// if height level map is present, do parallax mapping.
	vec4 cameraEye = uTDMats[cameraIndex].camInverse[3];
	vec3 cameraToPixelTangentSpace = worldSpacePos.xyz - cameraEye.xyz;
	oVert.cameraToPixelTangentSpace = inverse(tangentToWorld) * cameraToPixelTangentSpace;
#endif

	// vec4 tangentSpaceNorm = worldSpaceNorm;
	// vec3 tangentSpaceTangent = worldSpaceTangent;
	// toTangentFrame(T, tangentSpaceNorm, tangentSpaceTangent.xyz);

#else // TD_PICKING_ACTIVE

	// This will automatically write out the nessessary values
	// for this shader to work with picking.
	// See the documentation if you want to write custom values for picking.
	TDWritePickingValues();

#endif // TD_PICKING_ACTIVE
// int x = gl_VertexID%1024;
// int y = gl_VertexID/1024;
// vec4 vtxDebug = vec4(vec3(worldSpaceTangent.xyz),1);
// imageStore( mTD2DArrayImageOutputs[0] , ivec3(x,y,1) , vtxDebug );


}

Fragment:

// user switches for development
#define DO_FILAMENT_LIGHTING
#define CUBE_SAMPLERS_EXIST
#define DO_CUBE_MIPMAPPING // if turning this off, the old atlas mipmap mode only works correctly with maps generated @ 256 size from cmgen.
// #define LIGHTS_FROM_TEXTURE // turn this on to use texelFetch() from img buffer for punctual lights.. slower though!

// define vertex block
in Vertex
{
	vec4 color;
	mat3 tangentToWorld;
	vec3 cameraToPixelTangentSpace;
	vec3 worldSpacePos;
	vec3 worldSpaceNormal;
	vec4 worldSpaceTangent;
	vec2 texCoord0;
	flat int cameraIndex;
} iVert;

#include <general_utils>

// define some things early.
vec4 DEBUG2;
vec4 DEBUG3;
vec3 normal;
vec3 clearcoatNormalMap;
vec2 screenCoord;

// make some defines. Filament uses some of these variables internally, so this is our
// way of passing in what it needs from TD variables / functions that already exist and work fine.
#include <defines_fs>

#ifdef CALC_PIXEL_BITANGENT
	mat3 recalcualtedTangentToWorld = recalculated_bitangent( iVert.worldSpaceNormal , iVert.worldSpaceTangent );
	#define shading_tangentToWorld recalcualtedTangentToWorld
#else
	#define shading_tangentToWorld iVert.tangentToWorld
#endif
#define vertex_worldNormal iVert.tangentToWorld[2].xyz
#define vertex_worldPosition iVert.worldSpacePos.xyz
#define light_iblSpecular sLightIblMipMap
#define light_iblDFG sLightIblDFG

// define some Filament specific uniforms.
uniform sampler2D sLightIblMipMap;
uniform sampler2D sLightIblDFG;
uniform samplerCube sIblMip0;
uniform samplerCube sIblMip1;
uniform samplerCube sIblMip2;
uniform samplerCube sIblMip3;
uniform samplerCube sIblMip4;
uniform samplerCube sIblMip5;
uniform samplerCube sIblMip6;
uniform sampler2D sSsaoMap;
uniform sampler2D sPunctualBuffer;
// uniform sampler2D light_ssr;
uniform vec3 uSphericalHarmonics[9];
uniform float uIblRoughnessOneLevel;
uniform float uPunctualsBuffer[ FILA_LIGHT_BUFFER_LEN*NUM_FILA_LIGHTS ];

// define some other more general uniforms.
uniform float uBumpScale;
uniform vec4 uBaseColor;
uniform vec3 uEmission;
uniform float uMetallic;
uniform vec2 uRoughness;
uniform float uSpecularLevel;
uniform float uAmbientOcclusion;
uniform vec4 uParallaxSettings;
uniform bool uApplyCameraFog;
uniform bool uApplyemission;
uniform float uExposure;
uniform float uIblIlluminance;
uniform float uIblRotation;
uniform vec2 uAnisotropy;
uniform vec3 uSheenColor;
uniform float uSheenRoughness;
uniform vec3 uSubSurfaceColor;
uniform vec2 uSubSurfaceThickPower;
uniform vec3 uRefractionThickIor;
uniform vec4 uRefractionTransAbsorp;

// pull in other GLSL code modules from within TD.
#include <mipmap_utils>
#include <parallax_utils>
#include <lighting_utils>
#include <filament_utils>


layout(location = 0) out vec4 oFragColor;

#if TD_NUM_COLOR_BUFFERS > 1
layout(location = 1) out vec4 oFragDebug2;
#endif

#if TD_NUM_COLOR_BUFFERS > 1
layout(location = 2) out vec4 oFragDebug3;
#endif

void main()
{
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////// INITIAL SETUP /////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// This allows things such as order independent transparency
	// and Dual-Paraboloid rendering to work properly
	TDCheckDiscard();
	vec2 texCoord0 = iVert.texCoord0.st;
	vec2 texCoord0_parallaxed = iVert.texCoord0.st;
	
	float primary_roughness = uRoughness.x;
	float clearcoat_roughness = uRoughness.y;

	screenCoord = gl_FragCoord.xy * uTDGeneral.viewport.zw;
	DEBUG2 = vec4(0,0,0,1);
	DEBUG3 = vec4(0,0,0,1);
	vec4 outcol = vec4(0);

	// important, this function is something we added to the filament_utils.glsl to manually inject our TD parameters into Filament's
	// data structures.
#ifdef DO_FILAMENT_LIGHTING
	TD_Filament_INIT();
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////// PARALLAX RELIEF MAPPING ////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if defined(HEIGHT_LEVEL_MAP) || defined(HEIGHT_LEVEL_TOP)// if height level map or top is present, do parallax mapping.

	vec2 parallaxedUVs = vec2(0);

	// only apply the expensive parallax effect if the parallax scale is greater than 0. 
	if (uParallaxSettings.z > 0.0001){

		#ifdef HEIGHT_LEVEL_MAP
			parallaxedUVs.st = Parallax(HeightMapSampler, HeightMapSwizzleIndex, uParallaxSettings, iVert.cameraToPixelTangentSpace, texCoord0.st).xy;
		#endif
		
		#ifdef HEIGHT_LEVEL_TOP
			// assumes swizzle index of 0 for texture streams.
			parallaxedUVs.st = Parallax(HeightTopSampler, 0, uParallaxSettings, iVert.cameraToPixelTangentSpace, texCoord0.st).xy;
		#endif

	}
	else{
		parallaxedUVs.xy = 	texCoord0.xy;
	}

	texCoord0_parallaxed.xy = 	parallaxedUVs.xy;

#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////// SAMPLE TEXTURE BLOBS /////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// conditionally sample from the blob samplers, if they are defined.
#ifdef BLOB_SAMPLER_0
	vec4 blob0 = texture( sBlob0 , texCoord0_parallaxed );
#else
	vec4 blob0 = vec4(0);
#endif

#ifdef BLOB_SAMPLER_1
	vec4 blob1 = texture( sBlob1 , texCoord0_parallaxed );
#else
	vec4 blob1 = vec4(0);
#endif

#ifdef BLOB_SAMPLER_2
	vec4 blob2 = texture( sBlob2 , texCoord0_parallaxed );
#else
	vec4 blob2 = vec4(0);
#endif

#ifdef BLOB_SAMPLER_3
	vec4 blob3 = texture( sBlob3 , texCoord0_parallaxed );
#else
	vec4 blob3 = vec4(0);
#endif

#ifdef BLOB_SAMPLER_4
	vec4 blob4 = texture( sBlob4 , texCoord0_parallaxed );
#else
	vec4 blob4 = vec4(0);
#endif


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// SAMPLE TEXTURE STREAMS ////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef SINGLE_CHANNEL_TOPS
	vec4 stream_singlechannels = texture( sStream_singlechannels , texCoord0_parallaxed );
#else
	vec4 stream_singlechannels = vec4(1,1,1,1); // occlusion,rough,metal,specular
#endif

#ifdef BASE_COLOR_TOP
	vec4 stream_basecolor = texture( sStream_basecolor , texCoord0_parallaxed );
#else
	vec4 stream_basecolor = vec4(1,1,1,1); // rgb color, a=transparency
#endif

#ifdef EMIT_COLOR_TOP
	vec3 stream_emitcolor = texture( sStream_emitcolor , texCoord0_parallaxed ).rgb;
#else
	vec3 stream_emitcolor = vec3(0,0,0); // just rgb
#endif

#ifdef NORMAL_TOP
	vec3 stream_normalmap = texture( sStream_normalmap , texCoord0_parallaxed ).xyz;
#else
	vec3 stream_normalmap = vec3(0,0,1); // just xyz
#endif

#ifdef CLEARCOAT_NORMAL_TOP
	vec3 stream_clearcoat_norm = texture( sStream_clearcoatnormalmap , texCoord0 ).xyz; // use unparallaxed coords for clearcoat.
#else
	vec3 stream_clearcoat_norm = vec3(0,0,1);
#endif

#ifdef ANISOTROPY_TOP
	vec2 stream_anisotropy = texture( sStream_anisotropymap , texCoord0_parallaxed ).xy;
#else
	vec2 stream_anisotropy = vec2(0,1);
#endif

#ifdef SUBSURFACE_TOP
	vec4 stream_subsurface = texture( sStream_subsurfacemap , texCoord0_parallaxed ).rgba;
#else
	vec4 stream_subsurface = vec4(1);
#endif

#ifdef REFRACTTHICK_TOP
	float stream_refractionthickness = texture( sStream_refractionthicknessmap , texCoord0_parallaxed ).r;
#else
	float stream_refractionthickness = 1.0;
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////// SURFACE SHADING NORMALS ////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	shading_geometricNormal = iVert.tangentToWorld[2]; // since Filament needs shading_geometricNormal in some cases, setting it here.

#if defined(NORMAL_MAP) || defined(NORMAL_TOP) || defined(BASE_COLOR_TOP)
	
	vec3 normalMap = vec3(0);

	#ifdef NORMAL_MAP // this would be the static normals.
		normalMap = Normalmaptexture;
	#endif

	#ifdef NORMAL_TOP // this would be dynamic realtime normals. TODO: give user option to blend this into base normal.
		normalMap = stream_normalmap;
	#endif

	vec3 norm = (2.0 * (normalMap.xyz - 0.5)).xyz;
	norm.xy = norm.xy * uBumpScale;
#else
	vec3 norm = vec3(0,0,1);
#endif

	normal = normalize(norm);
	// Flip the normals on backfaces
	if (!TDFrontFacing(iVert.worldSpacePos.xyz, shading_geometricNormal.xyz))
	{
		normal = -normal;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////// CLEAR COAT NORMALS //////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#if defined(MATERIAL_HAS_CLEAR_COAT) && defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)

	clearcoatNormalMap = vec3(0,0,1);

	#ifdef CLEARCOAT_NORMAL_MAP
		clearcoatNormalMap = Clearcoatnormalstexture;
	#endif

	#ifdef CLEARCOAT_NORMAL_TOP
		clearcoatNormalMap = stream_clearcoat_norm;
	#endif

	clearcoatNormalMap = (2.0 * (clearcoatNormalMap.xyz - 0.5)).xyz; // remap to -1:1
#endif

	clearcoatNormalMap = normalize(clearcoatNormalMap);
	// Flip the normals on backfaces
	if (!TDFrontFacing(iVert.worldSpacePos.xyz, shading_geometricNormal.xyz))
	{
		clearcoatNormalMap = -clearcoatNormalMap;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////// SPECULAR LEVEL ////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	float specularLevel = uSpecularLevel;

#ifdef SPEC_LEVEL_MAP
	specularLevel = uSpecularLevel * Speculartexture;
#endif

#ifdef SPEC_LEVEL_TOP
	specularLevel = uSpecularLevel * stream_singlechannels.a;
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////// METALLIC LEVEL ////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	float metallicLevel = uMetallic;

#ifdef METAL_LEVEL_MAP
	metallicLevel = uMetallic * Metaltexture;
#endif
	
#ifdef METAL_LEVEL_TOP
	metallicLevel = uMetallic * stream_singlechannels.b;
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////// ROUGHNESS LEVEL ///////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	float roughnessLevel = primary_roughness;

#ifdef ROUGH_LEVEL_MAP
	roughnessLevel = primary_roughness * Roughnesstexture;
#endif

#ifdef ROUGH_LEVEL_TOP
	roughnessLevel = primary_roughness * stream_singlechannels.g;
#endif

	roughnessLevel = max(roughnessLevel, 0.0001);	// A roughness of exactly 0 is not allowed


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////// AMBIENT OCCLUSION LEVEL ////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	float ambientOcclusionLevel = uAmbientOcclusion;

#ifdef AO_LEVEL_MAP
	ambientOcclusionLevel = uAmbientOcclusion * Aomaptexture;
#endif

#ifdef AO_LEVEL_TOP
	ambientOcclusionLevel = uAmbientOcclusion * stream_singlechannels.r;
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////// EMISSION COLOR ////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// always assume emit color from color picker is provided as sRGB
	vec3 emitColor = srgb_to_linear(uEmission);

#ifdef EMIT_COLOR_MAP
	emitColor = uEmission * Emitcolortexture.rgb;
#endif

#ifdef EMIT_COLOR_TOP
	emitColor = uEmission * stream_emitcolor.rgb;
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////// BASE COLOR //////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// always assume base color from color picker is provided as sRGB
	vec3 baseColor = srgb_to_linear(uBaseColor.rgb) * iVert.color.rgb;

#ifdef BASE_COLOR_MAP
	baseColor *= Basecolortexture.rgb;
#endif

#ifdef BASE_COLOR_TOP
	baseColor *= stream_basecolor.rgb;
#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////// ANISOTROPY //////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	float anisotropy_strength = uAnisotropy.x;
	vec2 anisotropy_vector = vec2(1,0);

#ifdef MATERIAL_HAS_ANISOTROPY

	#if defined(ANISOTROPY_MAP) || defined(ANISOTROPY_TOP)

		#ifdef ANISOTROPY_MAP
			anisotropy_strength *= Anisotropytexture.x;
			anisotropy_vector.xy = Anisotropytexture.yz;
		#endif

		#ifdef ANISOTROPY_TOP
			anisotropy_strength *= stream_anisotropy.x;
			anisotropy_vector.xy = Anisotropytexture.yz;
		#endif

	#else
		float anisotropy_rotation_offset = uAnisotropy.y;
		anisotropy_rotation_offset *= PI * 2; // remap 0-1 rotational range to 360 degrees in radians
		anisotropy_vector = rotationMatrix2D(anisotropy_rotation_offset) * anisotropy_vector;
	#endif

#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////// SHEEN ////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	vec3 SheenColor = vec3(0);
	float SheenRoughness = 1.0;

#if defined(MATERIAL_HAS_SHEEN_COLOR) && !defined(SHADING_MODEL_CLOTH)
	SheenColor = uSheenColor;
	SheenRoughness = uSheenRoughness;
#endif

#ifdef SHADING_MODEL_CLOTH
	SheenColor = uSheenColor;
#endif

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////// SUB SURFACE /////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef SHADING_MODEL_CLOTH
	#ifdef MATERIAL_HAS_SUBSURFACE_COLOR
		// always assume subsurface from color picker is provided as sRGB
		vec3 subSurface = srgb_to_linear(uSubSurfaceColor.rgb);
	#endif
#endif

#ifdef SHADING_MODEL_SUBSURFACE
	// always assume subsurface from color picker is provided as sRGB
	// also multiply against base color, which can contain instance colors.
	vec3 subSurface = srgb_to_linear(uSubSurfaceColor.rgb) * baseColor;
	float subSurfaceThickness = uSubSurfaceThickPower.x;
	float subSurfacePower = uSubSurfaceThickPower.y;

	#ifdef SUBSURFACE_MAP
		// overwrite subsurface scattering uniforms.
		subSurface.rgb = Subsurfacetexture.rgb;
		subSurfaceThickness = Subsurfacetexture.a;
	#endif

	#ifdef SUBSURFACE_TOP
		// overwrite subsurface scattering uniforms.
		subSurface.rgb = stream_subsurface.rgb;
		subSurfaceThickness = stream_subsurface.a;
	#endif

#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////// REFRACTION /////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	float RefractionThickness = uRefractionThickIor.x;
	float RefractionMicroThickness = uRefractionThickIor.y;
	float RefractionIOR = uRefractionThickIor.z;
	float RefractionTransmission = uRefractionTransAbsorp.x;

	// always assume emit color from color picker is provided as sRGB
	vec3 RefractionAbsorption = srgb_to_linear(uRefractionTransAbsorp.yzw);

#ifdef REFRACTTHICK_MAP
	RefractionThickness *= Refractionthicknesstexture;
	RefractionMicroThickness *= Refractionthicknesstexture;
#endif

#ifdef REFRACTTHICK_TOP
	RefractionThickness *= stream_refractionthickness;
	RefractionMicroThickness *= stream_refractionthickness;
#endif



	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////// GOOGLE FILAMENT /////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
#ifdef DO_FILAMENT_LIGHTING

	// setting some tangent space normal information.
	inputs.normal.xyz = norm;
	

	// pass along the clear coat normals, if the top was plugged in / present.
#if defined(MATERIAL_HAS_CLEAR_COAT) && defined(MATERIAL_HAS_CLEAR_COAT_NORMAL)
	inputs.clearCoatNormal.xyz = clearcoatNormalMap;
#endif

#ifdef MATERIAL_HAS_CLEAR_COAT
	inputs.clearCoatRoughness = clearcoat_roughness;
#endif

    material(inputs);

    // overwrite some of the set parameters from our own params, from sampled textures etc.
    // eventually need to clean this up so that things happen in a more understandable, modular way.
    inputs.baseColor.rgb = vec3(baseColor);
    inputs.ambientOcclusion = ambientOcclusionLevel;
    inputs.roughness = roughnessLevel;
	inputs.emissive.rgb = emitColor;

#if !defined(SHADING_MODEL_CLOTH) && !defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
	inputs.metallic = metallicLevel;
	inputs.reflectance = specularLevel; // filament calls it reflectance, TD calls it specular level.
#endif

#ifdef MATERIAL_HAS_ANISOTROPY
	inputs.anisotropy = anisotropy_strength;
	inputs.anisotropyDirection = vec3(anisotropy_vector,0); // third component is always zero since we're defining in tangent space.
#endif

#if defined(MATERIAL_HAS_SHEEN_COLOR) && !defined(SHADING_MODEL_CLOTH) && !defined(SHADING_MODEL_SUBSURFACE)
	inputs.sheenColor = SheenColor;
	inputs.sheenRoughness = SheenRoughness;
#endif

#ifdef SHADING_MODEL_CLOTH
	inputs.sheenColor = SheenColor;
	#ifdef MATERIAL_HAS_SUBSURFACE_COLOR
		inputs.subsurfaceColor = subSurface;
	#endif
#endif

#ifdef SHADING_MODEL_SUBSURFACE

	inputs.thickness = subSurfaceThickness;
	inputs.subsurfacePower = subSurfacePower;
	inputs.subsurfaceColor = subSurface;

#endif

#ifdef HAS_REFRACTION
	#ifdef MATERIAL_HAS_ABSORPTION
		inputs.absorption = RefractionAbsorption;
	#endif

	#ifdef MATERIAL_HAS_IOR
		inputs.ior = RefractionIOR;
	#endif

	#ifdef MATERIAL_HAS_TRANSMISSION
		inputs.transmission = RefractionTransmission;
	#endif

	#ifdef MATERIAL_HAS_THICKNESS
		inputs.thickness = RefractionThickness;
	#endif

	#if defined(MATERIAL_HAS_MICRO_THICKNESS) && (REFRACTION_TYPE == REFRACTION_TYPE_THIN)
		inputs.microThickness = RefractionMicroThickness;
	#endif
#endif

    // this call does all of the lighting work.
    vec4 FilamentColor = evaluateMaterial(inputs);
    outcol = FilamentColor;

#endif


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////// ALPHA CALCULATION ///////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// #if 0

	float alpha = uBaseColor.a * iVert.color.a;

#ifdef ALPHA_LEVEL_MAP
	alpha *= Basecolortexture.a;
#endif

#ifdef BASE_COLOR_TOP
	alpha *= stream_basecolor.a;
#endif

	outcol.rgb *= alpha;

	// Modern GL removed the implicit alpha test, so we need to apply
	// it manually here. This function does nothing if alpha test is disabled.
	TDAlphaTest(alpha);

	outcol.a = alpha;

// #endif
	// DEBUG2.xy = screenCoord;

	// DEBUG2.xyz = vertex_worldNormal;
	// DEBUG2.xyz = iVert.worldSpaceTangent.xyz;


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////// BUFFER OUTPUT /////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	oFragColor = TDOutputSwizzle(outcol);

	//////////////////////////// DEBUGGING /////////////////////////////////////
	#if TD_NUM_COLOR_BUFFERS > 1
	oFragDebug2 = TDOutputSwizzle(vec4(vec3(DEBUG2.xyz),1));
	#endif

	#if TD_NUM_COLOR_BUFFERS > 2
	oFragDebug3 = TDOutputSwizzle(vec4(vec3(DEBUG3.xyz),1));
	#endif
	
	
	
	
	
	
	
	
}


1 Like

I should add, I am getting a warning from the compiler. I assume this is not creating an error, but maybe I’m wrong?

Vertex Shader Compile Results:

Compiled Successfully

=============
Pixel Shader Compile Results:
WARNING: /Engine/Viewport/Templates/material_asset_v2/filament_utils:5: '' : all default precisions are highp; use precision statements to quiet warning, e.g.:
         "precision mediump int; precision highp float;"

Compiled Successfully

=============

Linked Successfully

1 Like

Nothing obvious there, but there is lots of code in the includes.
I think the first thing I’d do is start commenting our sections of code until the error goes away, to narrow it down.

yes there is a ton there, I will see if I can narrow down with vertex and fragment first.

I’m already just writing the color red to the fragment with no other calcs going on… so maybe this is a vertex shader thing. might explain why the geometry is shifting around so weirdly.

Oye, so the problem was simply that I had a vec3 uniform defined that was offsetting some vertex coordinates by a set amount. This was only used in certain use cases of the shader (thumbnail generation) and I just didn’t have this uniform specified in the main render top or other instances of the shader.

I guess it was accessing data in random parts of the gpu memory and thus it was jittering all over the place due to that?

Def an error in my code, though interesting that it didn’t manifest pre Vulcan - any insights to why? Purely curious.

Anyways, easy solve, I should have been doing that anyways! Thank you.

The OpenGL driver may have been doing more fault tolerance than Vulkan. Vulkan in general does not. One thing you can also use to help debug this is

Which turns on fault tolerance in Vulkan. If setting this fixes issues, then it likely means you are accessing buffers outside of range.

1 Like

Oh this is super cool, I’ll try this out for one of my other flickering bugs that feels very similar but within fragment shader and report back.