I’m trying to use some one else grass code with it shader but it doesn’t seem to draw correctly.
It doesn’t draw completely transparent on a side and the other way it will not be transparent at all.
I may have done a mistake some where… It s not the first time i have a hard time with the Transparency. I did try to put Transparent bucket or Translucent. I ve tryed every alpha mode possible too.
Undesired result:
The code I testing the grass with:
package LostWorld.grass;
import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.TranslucentBucketFilter;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
import java.util.Random;
import jme3tools.optimize.GeometryBatchFactory;
public class CustomGrassTest extends SimpleApplication {
public static void main(String[] args) {
CustomGrassTest app = new CustomGrassTest();
app.start();
}
private float elapsedTime = 0;
private Material grassShader;
private Geometry grassGeom;
private Node allGrass = new Node("all grass");
private Vector2f windDirection = new Vector2f();
private float windStrength;
private Random random = new Random();
private Geometry ground;
public void simpleInitApp() {
// FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
// TranslucentBucketFilter tbf = new TranslucentBucketFilter();
// tbf.setEnabled(true);
// fpp.addFilter(tbf);
DirectionalLight light = new DirectionalLight();
light.setColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.9f));
light.setDirection(new Vector3f(0.7f, 0.8f, 0.7f));
this.getRootNode().addLight(light);
DirectionalLight otherlight = new DirectionalLight();
otherlight.setColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.9f));
otherlight.setDirection(new Vector3f(-0.7f, 0.8f, -0.7f));
this.getRootNode().addLight(otherlight);
this.getFlyByCamera().setMoveSpeed(10);
ground = new Geometry("ground", new Quad(10, 10));
ground.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"));
ground.getMaterial().setColor("Color", ColorRGBA.Brown);
//Texture t = assetManager.loadTexture("Textures/Terrain/grass.dds");
//t.setWrap(Texture.WrapMode.Repeat);
//ground.getMaterial().setTexture("ColorMap", t );
ground.setLocalTranslation(0, 0, 10);
ground.rotate(-90 * FastMath.DEG_TO_RAD, 0, 0);
rootNode.attachChild(ground);
windDirection.x = random.nextFloat();
windDirection.y = random.nextFloat();
windDirection.normalize();
grassGeom = new Geometry("grass", new Quad(2, 2));
grassShader = new Material(assetManager, "MatDefs/Grass/MovingGrass.j3md");
Texture grass = assetManager.loadTexture("Textures/Grass/grass.png");
grass.setWrap(Texture.WrapAxis.S, Texture.WrapMode.Repeat);
grassShader.setTexture("Texture", grass);
grassShader.setTexture("Noise", assetManager.loadTexture("Textures/Grass/grass.png"));
// set wind direction
grassShader.setVector2("WindDirection", windDirection);
windStrength = 1.0f;
grassShader.setFloat("WindStrength", windStrength);
grassShader.setTransparent(true);
grassShader.getAdditionalRenderState().setAlphaTest(true);
grassShader.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);
grassShader.getAdditionalRenderState().setAlphaFallOff(1f);
//
grassShader.setColor("Color", new ColorRGBA(0.53f, 0.83f, 0.53f, 1f));
grassShader.setFloat("Time", 0);
grassShader.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
grassGeom.setQueueBucket(Bucket.Opaque);
grassGeom.setMaterial(grassShader);
grassGeom.center();
Node[][] grassArray = new Node[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grassArray[i][j] = new Node(i+"-"+j);
for (int y = 0; y < 10; y++) {
for (int x = 0; x < 10; x++) {
Geometry grassInstance = grassGeom.clone();
grassInstance.setLocalTranslation(x+i*10 + (float) (Math.random() * 1f), 0, y+j*10 + (float) (Math.random() * 1f));
grassInstance.scale(0.4f, 0.4f + random.nextFloat() * .2f, 0.4f);
grassArray[i][j].attachChild(grassInstance);
Vector3f v3f = grassInstance.getLocalTranslation();
grassInstance = grassGeom.clone();
grassInstance.setLocalTranslation(v3f.add(0.4f, 0, 0.4f));
grassInstance.scale(0.4f, 0.4f + random.nextFloat() * .2f, 0.4f);
grassInstance.rotate(0, FastMath.DEG_TO_RAD * 90, 0);
grassArray[i][j].attachChild(grassInstance);
}
}
allGrass.attachChild(grassArray[i][j]);
}
}
Spatial grassNode = GeometryBatchFactory.optimize(allGrass);
grassNode.setQueueBucket(Bucket.Translucent);
grassNode.setMaterial(grassShader);
// grassNode.updateModelBound();
rootNode.attachChild(grassNode);
}
@Override
public void simpleUpdate(float tpf) {
elapsedTime += 0.001;
grassShader.setFloat("Time", elapsedTime);
}
}
The Shader Frag:
#ifdef TEXTURE
uniform sampler2D m_Texture;
varying vec2 texCoord;
#endif
uniform vec4 m_Color;
void main(void)
{
#ifdef TEXTURE
vec4 texVal = texture2D(m_Texture, texCoord);
gl_FragColor = texVal * m_Color;
#else
gl_FragColor = m_Color;
#endif
}
The Shader Vert:
uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_WorldViewMatrix;
uniform vec4 g_LightColor;
uniform float m_Time;
uniform float m_WindStrength;
uniform vec2 m_WindDirection;
uniform vec3 m_ObjectCenter;
uniform vec3 m_CamPos;
uniform sampler2D m_Texture;
uniform sampler2D m_Noise;
uniform vec4 m_Color;
attribute vec2 inTexCoord;
attribute vec3 inPosition;
//this is erroring
uniform float moveFactor = 0.06; // Play around with this
varying vec2 texCoord;
varying vec4 color;
#ifdef VERTEX_COLOR
attribute vec4 inColor;
#endif
void main()
{
vec3 displacedVertex;
displacedVertex = inPosition;
texCoord = inTexCoord;
float len = length( displacedVertex );
float noiseCoord = m_Time;
int totalTime = int(m_Time);
if (totalTime > 4096) totalTime -= 4096;
int pixelY = int(totalTime/64);
int pixelX = totalTime/ -pixelY;
float noiseFactor = texture2D(m_Noise, vec2( pixelX*10, pixelY*10 ) ).r;
// get pixel from noise map based on time. use to create additional variation
vec3 wvPosition = (g_WorldViewProjectionMatrix * vec4(displacedVertex, 1.0)).xyz;
if(inPosition.y>=0.1)
{
displacedVertex.x += moveFactor * sin(m_Time * texture2D(m_Noise, wvPosition.xz*50.0).r + len) + (m_WindStrength * noiseFactor * m_WindDirection.x)/10.0;
displacedVertex.z += moveFactor * cos(m_Time * texture2D(m_Noise, wvPosition.zx*50.0).r + len) + (m_WindStrength * noiseFactor * m_WindDirection.y)/10.0;
}
gl_Position = g_WorldViewProjectionMatrix * vec4(displacedVertex, 1.0);
#ifdef VERTEX_COLOR
color = m_Color * inColor;
color.rgb *= g_LightColor.rgb;
#else
color = m_Color;
color.rgb *= g_LightColor.rgb;
#endif
}