Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Magicorange

#1
Support / Re: Animated shader
April 20, 2014, 07:28:53 PM
Ok, I'll do this tomorrow and see if the problem occurs again.
#2
Support / Re: Animated shader
April 20, 2014, 07:14:24 PM
I'm not sure, this is a student project, I'm not meant to give it to anyone till it's finished :/
The quoted parts of the code are the only ones where I used the uniforms on this object, only at its creation, and only a simple call to setUniform in the onDrawFrame method.
#3
Support / Re: Animated shader
April 20, 2014, 06:54:14 PM
Ok, as I said when I create my objects, I basically do this  :


Object3D towerTop = Primitives.getSphere(1);
//choosing the texture stuff here
//..
towerTop.setTexture(topTex); //texture chosen previously
towerTop.calcTextureWrapSpherical();
//towerTop.setSpecularLighting(true);
towerTop.build();

String uniformTime = mContext.getResources().getString(R.string.global_uniform_time);

ArrayList<ShaderUniform> uniformsTop = new ArrayList<ShaderUniform>();
uniformsTop.add(new ShaderUniform("colorMap", 1));
uniformsTop.add(new ShaderUniform("noiseMap", 1));
uniformsTop.add(new ShaderUniform(uniformTime, currentTime));
uniformsTop.add(new ShaderUniform("alpha", 1.0));
uniformsTop.add(new ShaderUniform("baseSpeed", 0.005));
uniformsTop.add(new ShaderUniform("noiseScale", 0.1337));
uniformsTop.add(new ShaderUniform("invRadius", 0.0005f));


ShaderUtils.setShader(mContext, towerTop, shadersDir+"towers/"+"vertexShader.glsl", shadersDir+"towers/"+"fragmentShader.glsl", uniformsTop);

//then I add the object to the world etc



At this point, I have created wrappers and added them to the arraylist, the wrapper class looks like that :


public class ShaderUniform<T> {
private String name;
private T value;

public ShaderUniform(String name, T value) {
super();
this.name = name;
this.value = value;
}

//getters & setters...



Then I call my setShader method :


ShaderUtils.setShader(mContext, towerTop, shadersDir+"towers/"+"vertexShader.glsl", shadersDir+"towers/"+"fragmentShader.glsl", uniformsTop);



And this method does what I have posted before, it just takes the value attribute of the ShaderUniform and checks its class, if it's an integer it will call the setStaticUniform method that takes an integer parameter, if it's a float, the float method etc.

I'm not 100% sure that the line s.getValue() instanceof Float works perfectly, as I'm giving a float primitive parameter as the value when I create a ShaderUniform. I suppose that it's working as I'm getting the Log messages (UNIFORM INTEGER,FLOAT etc...).

And when I'm trying to update the uniform, I do it directly using the setUniform method of JPCT, not mine (I'm lazy ^^, this would force me to make another method that takes a single ShaderUniform parameter, check its class again and update it with setUniform, while I can directly do it in the render loop :p )
#4
Support / Re: Animated shader
April 20, 2014, 04:44:51 PM
Actually it's a float, there may be some precision loss as nanoTime() returns a long though. I've tried a cast to float but it doesn't change the result.

private float currentTime, startTime;


currentTime = (float)( System.nanoTime() - startTime);

My setShader method, called when the object is created, looks like this :


public static void setShader(Context mContext, Object3D obj, String vertPath, String fragPath, ArrayList<ShaderUniform> uniforms)
{

InputStream fragShader;
InputStream vertShader;
try
{
fragShader = mContext.getAssets().open(fragPath);
vertShader = mContext.getAssets().open(vertPath);

String fragmentShader = Loader.loadTextFile(fragShader);
String vertexShader = Loader.loadTextFile(vertShader);

GLSLShader shader = new GLSLShader(vertexShader, fragmentShader);
obj.setShader(shader);

for(ShaderUniform s : uniforms)
{
if (s.getValue() instanceof Integer)
{
Log.d("TAG", "UNIFORM INTEGER : "+s.getName());
shader.setStaticUniform(s.getName(), (Integer)s.getValue());
}

else if (s.getValue() instanceof Float)
{
Log.d("TAG", "UNIFORM FLOAT: "+s.getName());
shader.setStaticUniform(s.getName(), (Float)s.getValue());
}

else if (s.getValue() instanceof Float[])
{
shader.setStaticUniform(s.getName(), (float[])s.getValue());
}

...



I have tried to replace the uniform's primitives values set during the creation with wrappers like (uniformName, new Float(float value)) but it still does not solve the problem.
#5
Support / Animated shader
April 19, 2014, 06:09:57 PM
Hello,

I'm trying to animate a texture on my objects using a time variable, the problem is that it doesn't move.
This is where I update the time variable (in the onDrawFrame method ) :


...
if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
currentTime = System.nanoTime() - startTime;//startTime is initialized in the class' constructor with : startTime = System.nanoTime();
animateTextures();
}
fps++;
...



Here we set the uniforms in the method that creates the object :


...
String uniformTime = mContext.getResources().getString(R.string.global_uniform_time);

ArrayList<ShaderUniform> uniformsTop = new ArrayList<ShaderUniform>();
uniformsTop.add(new ShaderUniform("colorMap", 1));
uniformsTop.add(new ShaderUniform("noiseMap", 1));
uniformsTop.add(new ShaderUniform(uniformTime, currentTime));
uniformsTop.add(new ShaderUniform("alpha", 1.0));
uniformsTop.add(new ShaderUniform("baseSpeed", 0.005));
uniformsTop.add(new ShaderUniform("noiseScale", 0.1337));
uniformsTop.add(new ShaderUniform("invRadius", 0.0005f));


ShaderUtils.setShader(mContext, towerTop, shadersDir+"towers/"+"vertexShader.glsl", shadersDir+"towers/"+"fragmentShader.glsl", uniformsTop);

...



ShaderUniform is a class I've made that has a type parameter, and ShaderUtils.setShader is a method that will iterate through the arraylist and choose the right setStaticUniform method according to this type parameter.

And in the animateTextures method, this is how the shader should update the currentTime uniform:

  t.getTop().getShader().setUniform(uniformTime, currentTime); //uniformTime is the name of the variable




If needed, the fragment shader :


precision mediump float;

varying vec3 lightVec[2];
varying vec3 eyeVec;
varying vec2 texCoord;

uniform sampler2D colorMap;
uniform sampler2D noiseMap;
uniform float time;
uniform float baseSpeed;
uniform float noiseScale;
uniform float invRadius;
uniform float alpha;

uniform vec3 diffuseColors[8];
uniform vec3 specularColors[8];
uniform vec4 ambientColor;


float coef = 10.0;

void main ()
{
//Speed & direction of the texture
vec2 uvTimeShift = texCoord + vec2( -0.4, 0.5 ) * time * baseSpeed;
vec4 noise = texture2D( noiseMap, uvTimeShift );
vec2 uvNoisyTimeShift = texCoord + noiseScale * vec2( noise.r, noise.g ); //noise quantity
vec4 baseColor = texture2D( colorMap, uvNoisyTimeShift );
baseColor.a = alpha;

//...
gl_FragColor = baseColor;
}


Note that I got this working on another project that used Three.JS and WebGL, I have simply taken this code again and slightly modified it, but the time variable thingy has not changed (in the javascript version, the time uniform was updated in the renderLoop using a delta provided by a ThreeJS method).
It's meant to animate water textures using a noisemap,  I use it for a kind of lava effect.

Is it possible to update a uniform in a shader (then the way I do it is probably wrong), or does the problem comes from my time variable ?
I can't figure out yet why this is not working (and I have already searched if someone had the same problem, but it didn't help me that much), any help would be appreciated.

Thanks in advance for your answer.
#6
Support / Re: Moving the camera (on scrolling)
February 27, 2014, 06:40:20 PM
Ok, I've tried to do as you said, it seems to be working now :)
I post my code in case someone wants to do the same thing :



deltaX = xEnd - xStart;
deltaY = yEnd - yStart;
cameraChanged = true;



@Override
public void onDrawFrame(GL10 gl) {

if(deltaX != 0)
{
SimpleVector xAxisVec = map.getCam().getXAxis();
map.getCam().moveCamera(xAxisVec, deltaX/50f);
deltaX = 0;
}

if(deltaY != 0)
{
SimpleVector yAxisVec = map.getCam().getYAxis();
map.getCam().moveCamera(yAxisVec, deltaY/50f);
deltaY = 0;
}
...
}



At first I thought it was still not working because it scrolled again the wrong way (going up/down instead of left for example), you know why ? When the listener detects a scroll event it calls the function that does the calculation with the parameters in this order :  xStart,yStart, xEnd, yEnd, and the said function was expecting the parameters in that order : xStart,xEnd,yStart,yEnd,  :o
Lol !

Anyway, thanks for your help, your method works fine, that's easier without vectors for sure (I'll retry mine anyway, just to see if the wrong parameters order had a big influence), I might post in this thread again if I have questions about camera.
I will try to set bounds for the camera, in order not to let it go outside of the map, so if I have a problem I'll ask you :)

And good job for JPCT/AE, I'm beginning with it, I find it really nice (even if I'm awkward with maths & vectors and such ^^) ;)
#7
Support / Re: Moving the camera (on scrolling)
February 27, 2014, 05:56:03 PM
Well, the camera hasn't been rotated, just slightly moved on its Z axis when it's been created.
But I'm not sure to get it, do you mean I should directly make a vector using the x,y of the touch positions (something like [xEnd-xStart, yEnd-yStart,0]) and add it to the X/Y axis vectors to translate the camera ?
#8
Support / Moving the camera (on scrolling)
February 27, 2014, 12:36:54 PM
Hello,

I would like to move the camera on the x/y axis using the onScroll listener, but I'm having difficults using the camera.moveCamera method :


SimpleVector touchOrigin = Interact2D.reproject2D3DWS(map.getCam(), fb, (int)xStart, (int)yStart).normalize();
SimpleVector touchEnd = Interact2D.reproject2D3DWS(map.getCam(), fb, (int)xEnd, (int)yEnd).normalize();
SimpleVector moveDist = touchEnd.calcSub(touchOrigin);
cameraMovement = moveDist;
cameraChanged = true;


The idea is to project the touch origin (xStart yStart) and the current touch position (xEnd yEnd) in the world space so I can calculate the distance between both and use it to move the camera.



if(cameraChanged)
{
map.getCam().moveCamera(cameraMovement, 2);
cameraChanged = false;
}



The thing is that I'm getting incoherent results, like the camera going upwards while I'm scrolling to the left etc.
It's probably an easy math problem but I really can't figure what exactly it is, I thought that substracting the two vectors would work but maybe I'm wrong.
I've tried to use camera.moveCamera using the already defined directions (Camera.CAMERA_MOVERIGHT, CAMERA_MOVELEFT ...) when we have xStart < or > xEnd, yStart < > yEnd but I'm getting more or less the same problem.

I'm still trying to find a solution, and I've already searched for this in other topics but I couldn't find a real solution at the moment.

Any idea on how I could do this please ?

Thanks in advance ! :)

Edit : I just noticed I've posted in the wrong section (I'm using JPCT AE !), sorry !