Apply vegetation shaders not working

Hello, I am trying to apply vegetation on my mesh, currently am using the CardPlane just for testing.
the current problem is the whole thing is not working and I can not see my plane thither the vegetation, So is what I’ve done so far is correct?

the following shaders can be found in the following tutorial: https://vulpinii.github.io/tutorials/grass-modelisation/en/
here are the shaders that am using:

Vertex Shader:

#version 410 core
layout (location = 0) in vec3 aPos;
// out VS_OUT {} vs_out;

void main() {
	gl_Position = vec4(aPos, 1.0);
}

Geometry Shader:

#version 410 core
layout (points) in;
layout (triangle_strip, max_vertices = 36) out;
// in VS_OUT {} gs_in[];

out GS_OUT {
	vec2 textCoord;
	float colorVariation;
} gs_out;

uniform mat4 p3d_ViewMatrix;
uniform mat4 p3d_ProjectionMatrix;
uniform vec3 u_cameraPosition;
uniform sampler2D u_wind;
uniform float u_time;

/* CONST PARAMETERS */
const float c_min_size = 0.4f;
const float LOD1 = 5.0f;
const float LOD2 = 10.0f;
const float LOD3 = 20.0f;
const float PI = 3.141592653589793;

/* PARAMETERS */
float grass_size;

/* USEFUL FUNCTIONS */
mat4 rotationX(in float angle);
mat4 rotationY(in float angle);
mat4 rotationZ(in float angle);
float random (vec2 st);
float noise (in vec2 st);
float fbm ( in vec2 _st);

/* MAIN FUNCTIONS */
void createQuad(vec3 base_position, mat4 crossmodel){
	vec4 vertexPosition[4];
	vertexPosition[0] = vec4(-0.25, 0.0, 0.0, 0.0); 	// down left
	vertexPosition[1] = vec4( 0.25, 0.0, 0.0, 0.0);		// down right
	vertexPosition[2] = vec4(-0.25, 0.5, 0.0, 0.0);		// up left
	vertexPosition[3] = vec4( 0.25, 0.5, 0.0, 0.0);		// up right

	vec2 textCoords[4];
	textCoords[0] = vec2(0.0, 0.0);						// down left
	textCoords[1] = vec2(1.0, 0.0);						// down right
	textCoords[2] = vec2(0.0, 1.0);						// up left
	textCoords[3] = vec2(1.0, 1.0);						// up right

//	// wind
//	vec2 windDirection = vec2(1.0, 1.0); float windStrength = 0.15f;
//	vec2 uv = base_position.xz/10.0 + windDirection * windStrength * u_time ;
//	uv.x = mod(uv.x,1.0);
//	uv.y = mod(uv.y,1.0);
//	vec4 wind = texture(u_wind, uv);
//	mat4 modelWind =  (rotationX(wind.x*PI*0.75f - PI*0.25f) * rotationZ(wind.y*PI*0.75f - PI*0.25f));
//	mat4 modelWindApply = mat4(1);

	// random rotation on Y
	mat4 modelRandY = rotationY(random(base_position.zx)*PI);

	// loop of billboard creation
	for(int i = 0; i < 4; i++) {
//		if (i == 2 ) modelWindApply = modelWind;
	    gl_Position = p3d_ProjectionMatrix * p3d_ViewMatrix *
            (gl_in[0].gl_Position + modelRandY*crossmodel*(vertexPosition[i]*grass_size));

	    gs_out.textCoord = textCoords[i];
		gs_out.colorVariation = fbm(gl_in[0].gl_Position.xz);
	    EmitVertex();
    }
    EndPrimitive();
}

void createGrass(int numberQuads){
	mat4 model0, model45, modelm45;
	model0 = mat4(1.0f);
	model45 = rotationY(radians(45));
	modelm45 = rotationY(-radians(45));

	switch(numberQuads) {
		case 1: {
			createQuad(gl_in[0].gl_Position.xyz, model0);
			break;
		}
		case 2: {
			createQuad(gl_in[0].gl_Position.xyz, model45);
			createQuad(gl_in[0].gl_Position.xyz, modelm45);
			break;
		}
		case 3: {
			createQuad(gl_in[0].gl_Position.xyz, model0);
			createQuad(gl_in[0].gl_Position.xyz, model45);
			createQuad(gl_in[0].gl_Position.xyz, modelm45);
			break;
		}
	}
}

/* MAIN */
void main()
{
	vec3 distance_with_camera = gl_in[0].gl_Position.xyz - u_cameraPosition;
	float dist_length = length(distance_with_camera); // distance of position to camera
	grass_size = random(gl_in[0].gl_Position.xz) * (1.0f - c_min_size) + c_min_size; 	// for random size

	// distance of position to camera
	float t = 6.0f; if (dist_length > LOD2) t *= 1.5f;
	dist_length += (random(gl_in[0].gl_Position.xz)*t - t/2.0f);

	// change number of quad function of distance
	int lessDetails = 3;
	if (dist_length > LOD1) lessDetails = 2;
	if (dist_length > LOD2) lessDetails = 1;
	if (dist_length > LOD3) lessDetails = 0;

	// create grass
	if (lessDetails != 1
		|| (lessDetails == 1 && (int(gl_in[0].gl_Position.x * 10) % 1) == 0 || (int(gl_in[0].gl_Position.z * 10) % 1) == 0)
		|| (lessDetails == 2 && (int(gl_in[0].gl_Position.x * 5) % 1) == 0 || (int(gl_in[0].gl_Position.z * 5) % 1) == 0)
	)
		createGrass(lessDetails);
}


// *******************************************************************
//                            UTILS
// *******************************************************************
mat4 rotationX( in float angle ) {
	return mat4(	1.0,		0,			0,			0,
			 		0, 	cos(angle),	-sin(angle),		0,
					0, 	sin(angle),	 cos(angle),		0,
					0, 			0,			  0, 		1);
}

mat4 rotationY( in float angle )
{
	return mat4(	cos(angle),		0,		sin(angle),	0,
			 				0,		1.0,			 0,	0,
					-sin(angle),	0,		cos(angle),	0,
							0, 		0,				0,	1);
}

mat4 rotationZ( in float angle ) {
	return mat4(	cos(angle),		-sin(angle),	0,	0,
			 		sin(angle),		cos(angle),		0,	0,
							0,				0,		1,	0,
							0,				0,		0,	1);
}

float random (vec2 st) {
    return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);
}

// 2D Noise based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 st) {
	vec2 i = floor(st);
	vec2 f = fract(st);

	// Four corners in 2D of a tile
	float a = random(i);
	float b = random(i + vec2(1.0, 0.0));
	float c = random(i + vec2(0.0, 1.0));
	float d = random(i + vec2(1.0, 1.0));

	// Smooth Interpolation

	// Cubic Hermine Curve.  Same as SmoothStep()
	vec2 u = f*f*(3.0-2.0*f);
	// u = smoothstep(0.,1.,f);

	// Mix 4 coorners percentages
	return mix(a, b, u.x) +
	(c - a)* u.y * (1.0 - u.x) +
	(d - b) * u.x * u.y;
}
#define NUM_OCTAVES 5
float fbm ( in vec2 _st) {
	float v = 0.0;
	float a = 0.5;
	vec2 shift = vec2(100.0);
	// Rotate to reduce axial bias
	mat2 rot = mat2(cos(0.5), sin(0.5),
	-sin(0.5), cos(0.50));
	for (int i = 0; i < NUM_OCTAVES; ++i) {
		v += a * noise(_st);
		_st = rot * _st * 2.0 + shift;
		a *= 0.5;
	}
	return v;
}

Fragment Shader:

#version 410 core
out vec4 FragColor;

in GS_OUT {
	vec2 textCoord;
    float colorVariation;
} fs_in;

uniform sampler2D u_textgrass;

void main(){
    // very simple but we can also add lighting to get better result
    vec4 color = vec4(0,1,0,1);
    if (color.a < 0.25 ) discard;
    color.xyz = mix(color.xyz, 0.5*color.xyz, fs_in.colorVariation);
	FragColor = color;
}

Finally here is my test code:

import direct.directbase.DirectStart
from panda3d.core import *


card_maker = CardMaker("myCard")
loadPrcFileData("", "gl-debug #t")

# Set the size of the card
width = 1.0
height = 1.0
card_maker.setFrame(-width/2, width/2, -height/2, height/2)

# Create a NodePath for the card
card_np = render.attachNewNode(card_maker.generate())

# Set the color of the card
card_np.setColor(1, 0, 0, 1)  # RGBA values

# Position the card in the scene
card_np.setPos(0, 0, 0)
vertex_shader = "grass.vs.glsl"   #shader path
fragment_shader = "grass.fg.glsl" #shader path
geo_shader = "grass.gs.glsl" #shader path
shader = Shader.load(Shader.SLGLSL, vertex_shader, fragment_shader, geo_shader)
card_np.setShader(shader)
card_np.setShaderInput("u_cameraPosition", base.camera.getPos(render))
card_np.setShaderInput("u_time", 1.0)
# Run the Panda3D main loop
base.run()

In fact, it is difficult to comment on something, but the time should change from frame to frame, and not be static. This also applies to the camera position.

I hope you have checked all the stages of writing the shader. You have received an array of points, according to what is indicated here:

Well, this is one mistake I’m seeing:

layout (location = 0) in vec3 aPos;

You should call this p3d_Vertex, unless you really have a vertex column that is named “aPos”.

1 Like