geomatry shader with uses_adjacency_information works wrong

Problems building or running the engine, queries about how to use features etc.
Post Reply
BAntDit
Kobold
Posts: 32
Joined: Mon Oct 27, 2014 5:43 pm
x 2

geomatry shader with uses_adjacency_information works wrong

Post by BAntDit »

Hi,
I try to use geometry shaders to draw edges around the mesh, ogre version Ogre3D 1.9, render system: OpenGL Render Subsystem
The problems is geometry shader miss part of triangles on output.

It looks like this bug: http://www.ogre3d.org/forums/viewtopic.php?f=5&t=64528 - but i've tested GLSLProgram::createLowLevelImpl(void) method, looks like it works fine in Ogre3D 1.9 (builded from brunch v1_9, revision: 7866 on mercurial).

And now i don't know what the problem - Is this some else bug of engine or maybe i've missed some bug in my code.

No any errors in log. No erros, nothing works and i do not why...

It looks like geometry shader missed all odd triangles.

this is how it looks like:
Image

HELP! Don't let elven girl looks ugly.

I put code below, maybe it help to find a reason.
------
There are snippets of my code:

program script:

Code: Select all

vertex_program Common/Skinning_NormalMapping_VP_GLSL glsl
{
	source skinning_vp.glsl
	includes_skeletal_animation true
	use_optimiser false
	preprocessor_defines BUMPMAP=1,RENDER_IN_VIEWSPACE=1
}

fragment_program Common/Skinning_NormalMapping_FP_GLSL glsl
{
	source skinning_fp.glsl
	preprocessor_defines BUMPMAP=1,RENDER_IN_VIEWSPACE=1,MAX_LIGHTS=8
	use_optimiser false
}

geometry_program Common/Edge_Lines_NormalMapping_GP_GLSL glsl
{
	source edge_lines_gp.glsl
	[color=#FF0000][b]uses_adjacency_information true[/b][/color]
	input_operation_type triangles_adjacenncy
	output_operation_type triangle_strip
	max_output_vertices 15
	use_optimiser false
	preprocessor_defines BUMPMAP=1,RENDER_IN_VIEWSPACE=1
}
vertex shader:

Code: Select all

#version 440

#define COUNT_BONES 255

uniform vec4 posesMatrix[COUNT_BONES];  // world_matrix_array_3x4
uniform mat4 viewProjectionMatrix;		// viewproj_matrix
#ifndef RENDER_IN_VIEWSPACE
uniform vec3 cameraPosition;			// camera_position
#else 
uniform mat4 viewMatrix; 				// view_matrix
#endif

in vec4 vertex;
in vec3 normal;
#ifndef RENDER_IN_VIEWSPACE
#ifdef BUMPMAP
in vec3 tangent;
#endif
#endif
in vec4 uv0;

in vec4 blendIndices;
in vec4 blendWeights;

out vec3 vPosition;
out vec3 vNormal;
#ifndef RENDER_IN_VIEWSPACE
#ifdef BUMPMAP
out vec3 vTangent;
out vec3 vBinormal;
#endif
#endif
out vec3 vViewDir;
out vec2 vUV0;

void main()
{
	// main code of vertex shader... (nothing important here)

	gl_Position = viewProjectionMatrix * vec4(blendPosition.xyz, 1.0);
}
geometry shader:

Code: Select all


#version 440

layout (triangles_adjacency) in;
layout (triangle_strip, max_vertices = 15) out;

in vec3 vPosition[];
in vec3 vNormal[];
#ifndef RENDER_IN_VIEWSPACE
#ifdef BUMPMAP
in vec3 vTangent[];
in vec3 vBinormal[];
#endif
#endif
in vec3 vViewDir[];
in vec2 vUV0[];

out vec3 gNormal;
out vec3 gPosition;
#ifndef RENDER_IN_VIEWSPACE
#ifdef BUMPMAP
out vec3 gTangent;
out vec3 gBinormal;
#endif
#endif
out vec3 gViewDir;
out vec2 gUV0;

flat out float gIsEdge;

bool isFrontFacing(vec3 a, vec3 b, vec3 c)
{
	return ((a.x * b.y - b.x * a.y) +
			(b.x * c.y - c.x * b.y) +
			(c.x * a.y - a.x * c.y)) > 0;
}

void emitEdgeQuad(vec3 e0, vec3 e1)
{
	vec2 ext = 0.001 * (e1.xy - e0.xy);
	vec2 v = normalize(e1.xy - e0.xy);
	vec2 n = vec2(-v.y, v.x) * 0.0001;
	
	gIsEdge = 1.0;
	
	gl_Position = vec4(e0.xy - ext, e0.z, 1.0);
	EmitVertex();
	
	gl_Position = vec4(e0.xy - n - ext, e0.z, 1.0);
	EmitVertex();
	
	gl_Position = vec4(e1.xy + ext, e1.z, 1.0);
	EmitVertex();
	
	gl_Position = vec4(e1.xy - n + ext, e1.z, 1.0);
	EmitVertex();
	
	EndPrimitive();
}

void main()
{
	vec3 p0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
	vec3 p1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
	vec3 p2 = gl_in[2].gl_Position.xyz / gl_in[2].gl_Position.w;
	vec3 p3 = gl_in[3].gl_Position.xyz / gl_in[3].gl_Position.w;
	vec3 p4 = gl_in[4].gl_Position.xyz / gl_in[4].gl_Position.w;
	vec3 p5 = gl_in[5].gl_Position.xyz / gl_in[5].gl_Position.w;
	
	if (isFrontFacing(p0, p2, p4)) {
		if (!isFrontFacing(p0, p1, p2))
			emitEdgeQuad(p0, p2);
		
		if(!isFrontFacing(p2, p3, p4))
			emitEdgeQuad(p2, p4);
			
		if(!isFrontFacing(p4, p5, p0))
			emitEdgeQuad(p4, p0);
	}
	
	gIsEdge = 0.0;
	
	gNormal = vNormal[0];
	#ifndef RENDER_IN_VIEWSPACE
	#ifdef BUMPMAP
	gTangent = vTangent[0];
	gBinormal = vBinormal[0];
	#endif
	#endif
	gViewDir = vViewDir[0];
	gUV0 = vUV0[0];
	gPosition = vPosition[0];
	gl_Position = gl_in[0].gl_Position;
	EmitVertex();
	
	gNormal = vNormal[2];
	#ifndef RENDER_IN_VIEWSPACE
	#ifdef BUMPMAP
	gTangent = vTangent[2];
	gBinormal = vBinormal[2];
	#endif
	#endif
	gViewDir = vViewDir[2];
	gUV0 = vUV0[2];
	gPosition = vPosition[2];
	gl_Position = gl_in[2].gl_Position;
	EmitVertex();
	
	gNormal = vNormal[4];
	#ifndef RENDER_IN_VIEWSPACE
	#ifdef BUMPMAP
	gTangent = vTangent[4];
	gBinormal = vBinormal[4];
	#endif
	#endif
	gViewDir = vViewDir[4];
	gUV0 = vUV0[4];
	gPosition = vPosition[4];
	gl_Position = gl_in[4].gl_Position;
	EmitVertex();
	
	EndPrimitive();
}
Maybe i emit wrong vertices or maybe i have to emit quads instead trinagles...

and part of fragment shader (actualy no metter what i do on fragment shader)

Code: Select all


#version 440

uniform vec4 lightPositions[MAX_LIGHTS];		// light_position_array // or light_position_view_space for RENDER_IN_VIEWSPACE
uniform vec4 lightDiffuseColours[MAX_LIGHTS];	// light_diffuse_colour_power_scaled_array
uniform vec4 lightSpecularColours[MAX_LIGHTS];	// light_specular_colour_power_scaled_array
uniform vec4 lightAttenuations[MAX_LIGHTS];		// light_attenuation_array
uniform vec4 lightParameters[MAX_LIGHTS];		// spotlight_params_array
uniform vec4 lightDirections[MAX_LIGHTS];		// light_direction_array // or light_direction_view_space for RENDER_IN_VIEWSPACE

uniform vec4 materialAmbient;					// surface_ambient_colour
uniform vec4 materialDiffuse;					// surface_diffuse_colour
uniform vec4 materialSpecular;					// surface_specular_colour

uniform sampler2D mainTexture;

#ifdef BUMPMAP
uniform sampler2D normalMap;
#endif

uniform float IOR;
uniform float roughness;

in vec3 gPosition;
in vec3 gNormal;

flat in float gIsEdge;

#ifndef RENDER_IN_VIEWSPACE
#ifdef BUMPMAP
in vec3 gTangent;
in vec3 gBinormal;
#endif
#endif
in vec3 gViewDir;
in vec2 gUV0;

out vec4 fragColour;

// tons of code there...

void main()
{
 // and there ... 
}
base material:

Code: Select all

material Common/Skinning_NormalMapping
{
	technique 0
	{
		pass 0
		{
			ambient 1 1 1 1
			diffuse 1 1 1 1
			specular 1 1 1 1
			
			vertex_program_ref Common/Skinning_NormalMapping_VP_GLSL
			{
				param_named_auto posesMatrix 			world_matrix_array_3x4
				param_named_auto viewProjectionMatrix	viewproj_matrix
				param_named_auto viewMatrix 			view_matrix
			}
			
			geometry_program_ref Common/Edge_Lines_NormalMapping_GP_GLSL
			{
			}
			
			fragment_program_ref Common/Skinning_NormalMapping_FP_GLSL
			{
				param_named_auto lightPositions 		light_position_view_space_array 8
				param_named_auto lightDiffuseColours	light_diffuse_colour_power_scaled_array 8
				param_named_auto lightSpecularColours	light_specular_colour_power_scaled_array 8
				param_named_auto lightAttenuations		light_attenuation_array 8
				param_named_auto lightParameters		spotlight_params_array 8
				param_named_auto lightDirections		light_direction_view_space 8
				param_named_auto materialAmbient		surface_ambient_colour
				param_named_auto materialDiffuse		surface_diffuse_colour
				param_named_auto materialSpecular		surface_specular_colour
				
				param_named IOR float 0.0
				param_named roughness float 0.1
				
				param_named mainTexture int 0
				param_named normalMap int 1
			}
			
			texture_unit MainTexture
			{
			}
			
			texture_unit NormalMap
			{
			}
		}
	}
}
derived material that i actualy use on mesh:

Code: Select all

import Common/Skinning_NormalMapping from "core.material"

material Elven_Hunter_body_blue : Common/Skinning_NormalMapping
{
	technique 0
	{
		pass 0
		{
			ambient 0.831373 0.713726 0.713726 1
			diffuse 1 1 1 1
			specular 1 1 1 1
			
			fragment_program_ref Common/Skinning_NormalMapping_FP_GLSL
			{				
				param_named IOR float 0.01
				param_named roughness float 0.36
			}
			
			texture_unit MainTexture
			{
				texture elven_color_brown.tif
			}
			
			texture_unit NormalMap
			{
				texture Elven_normals.tif
			}
		}
	}
}
BAntDit
Kobold
Posts: 32
Joined: Mon Oct 27, 2014 5:43 pm
x 2

Re: geomatry shader with uses_adjacency_information works wr

Post by BAntDit »

Finally, i have found the reason.
The geometry shader takes verticies in wrong order. I expect vertices in follwing order: p0, p2, p4 - the vertices of current primitive, p1,p3,p5 - adjacency verticies, but the shader took em in order: p0, p1,p2 - current primitive, p3,p4,p5 - next primitive instead adjacency. The reason why my shader has this wrong behaviour is wrong source data in the index buffer of my mesh. Adjacency elements were not present in the index buffer.
Post Reply