Shaders Question

Hi,

I’ve been using JME3 for a few months, and have run into a bit of a wall writing a shader. Shaders always seem to throw me off because I’m never quite sure what parameters are, and without any sort of console, they are very difficult to test.



I want the shader to effect the opacity of the geometry based on their normal relative to the camera, so that things are less visible at an angle. So essentially, I figured I’d take the dot product of the normal and a normalized vector pointing from the camera to the surface. So I wrote a vertex shader:



uniform mat4 g_WorldViewProjectionMatrix;

uniform vec3 g_CameraPosition;



attribute vec2 inTexCoord;

attribute vec3 inPosition;



attribute vec3 inNormal;



varying vec3 normal;

varying vec3 camAngle;



void main(){

gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition,1.0);

texCoord = vec3(inTexCoord.x, inTexCoord.y, g_Time * 0.125);



camAngle = (g_WorldViewProjectionMatrix * vec4((inPosition + -1.0 * g_CameraPosition), 1.0)).xyz;

normal = inNormal;

}





in my vertex shader, and a fragment shader as well:



uniform vec4 m_Color;

varying vec3 normal;

varying vec3 camAngle;



void main(){

vec4 color = m_Color;

color.w = dot(normalize(normal), normalize(camAngle));

gl_FragColor= color;

}



Unfortunately, something went wrong somewhere along the way. I’m not sure if it’s something to do with rotation that I missed or a fundamental miscomprehension of shaders or something entirely different. Any assistance would be greatly appreciated.

i think this should be in the fragment shader…

more about shaders: http://code.google.com/p/jme-glsl-shaders/

When you say something went wrong… are you saying the shader doesn’t compile? Or that the output is not as expected?



And… not completely sure about this, because I’m a little confused on normalize and which axis it “normalizes” against.



Have you tried:

color.w = dot(normal, camAngle);

instead of:

color.w = dot(normalize(normal), normalize(camAngle));

Please note that if you’re using the alpha parameter of the color, you need to set the blend mode of the material to alpha

(from code material.getAditionalRenderState().setBlendMode(Alpha) or directly in a j3m file)



then you have to place the object in the transparent bucket.



On the shader now,

this line is strange :

camAngle = (g_WorldViewProjectionMatrix * vec4((inPosition + -1.0 * g_CameraPosition), 1.0)).xyz;



inPosition is in model space, g_CameraPosition is in world space so it can’t work like this. Whatever you do you have to compute the cam direction and the normal in the same space to be able to compare them.

i don’t know if you read this https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:jme3_shaders but please do if my space transform thing gibberish means nothing to you. :stuck_out_tongue:



I recommend transforming your vectors in view space.

to do this you need 3 global parameters : g_ViewMatrix, g_NormalMatrix, g_WorldViewMatrix

The view matrix transforms a vector from world space to view space.

The normalMatrix is kinda special because it’s a 3x3 matrix that transforms the normals from model space to view space.

The g_WorldViewMatrix transforms a vector from model space to view space.



to have them in your shader, you need to declare the ViewMatrix, the NormalMatrix and the WorldViewMatrix in the WorldParameters section of your technique in the j3md file.

Then declare them in the vert shader as uniforms mat4 g_ViewMatrix , mat3 g_NormalMatrix and mat4 g_WorldViewMatrix .



then :

the gl_Position and texcoord calculation can stay as they are now it’s fine.



you have to compute, the vertex position, the camera position and the normal in view space and in the end the cam direction.

vec4 posView = g_WorldViewMatrix * inPosition;

vec4 camView = g_ViewMatrix * g_CameraPosition;

normal= g_NormalMatrix * inNormal;

camAngle = posView - camView;



this should work.

Hello Everyone.



I am trying to do something simmilar to what the1610 does. I have a shader designed in ShaderDesigner that works and gives me this result:

http://i.imgur.com/ZqqwJ.jpg

And it’s code is:

[java]

//Vertex:

varying float angle;



void main()

{

vec4 P = gl_ModelViewMatrix * gl_Vertex;



vec3 N = gl_NormalMatrix * gl_Normal;



angle = max(dot(normalize(-N), normalize(P.xyz)), 0.0);

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}

[/java]

[java]

//Pixel:

varying float angle;



void main()

{

gl_FragColor = vec4(angle, angle, angle, 1.0);

}

[/java]



Now I am trying to port this to JME3 Shader. My source looks like this:

[java]

//Vertex:

uniform mat4 g_WorldViewProjectionMatrix;

uniform mat4 g_WorldViewMatrix;

uniform mat3 g_NormalMatrix;



attribute vec3 inPosition;

attribute vec3 inNormal;



varying float angle;



void main(){



vec4(inPosition, 1.0);

vec4 position = vec4(inPosition, 1.0);



vec4 eposition = g_WorldViewMatrix * position;

vec3 enormal = g_NormalMatrix * inNormal;

angle=max(dot(normalize(-enormal), normalize(eposition.xyz)), 0.0);



gl_Position = g_WorldViewProjectionMatrix * position;

}

[/java]

[java]

//Pixel:

varying float angle;



void main(){

gl_FragColor = vec4(angle, angle, angle, 1.0);

}

[/java]



And the result is very far from what i could see in ShaderDesigner:



The sphere is plain black.

http://i.imgur.com/71wrK.png



Coul you please explain me what I am doing wrong ? Thank you.

Can we see your j3md file?

Thanks a lot. By having a look at j3md I found what was the issue:



[java]

MaterialDef Solid Color {

MaterialParameters {

}

Technique {

VertexShader GLSL100: shader/SolidColor.vert

FragmentShader GLSL100: shader/SolidColor.frag

WorldParameters {

WorldViewProjectionMatrix

//Those two were missing:

WorldViewMatrix

NormalMatrix

}

}

Technique FixedFunc {

}

}

[/java]

:slight_smile: That’s where I was going with the question. :slight_smile: