WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Shader problems (https://forum.worldviz.com/showthread.php?t=5863)

Strannix 10-06-2016 02:50 PM

Shader problems
 
Dear Shader Experts

For an outdoor scene I am trying to get a vertex / fragment shader bundle working that allows for rendering a dynamic sky model.

The project can be found here: https://github.com/kosua20/opengl-skydome

While I have basic knowledge of GLSL and shaders I am having a hard time to get this running. In fact, when I import the sky sphere and apply the shaders, the sphere gets transparent, i.e. disappears.

I assume that the problem might have to do with a missing uniform. For example, I am not sure whether it is possible to submit my uniforms as "vizmat" variables as I currently do for "mvp" and "star_pos"

I attach my code together with the vertex and fragment shaders below. I really appreciate any kind of help! :-)

Many thanks,

Andreas


################ PYTHON CODE ################
import viz
import vizfx
import vizcam

viz.setMultiSample(4)
viz.go()

logo = vizfx.addChild('logo.osgb')

cam = vizcam.PivotNavigate(distance=3.5)
cam.centerNode(logo)

# add sky sphere
mySphere = viz.add('sphere.obj')

# import textures
tint = viz.add('./img/tint.tga')
tint2 = viz.add('./img/tint2.tga')
sun = viz.add('./img/sun.tga')
moon = viz.add('./img/moon.tga')
clouds1 = viz.add('./img/clouds1.tga')
clouds2 = viz.add('./img/clouds2.tga')

# apply textures to buffers
mySphere.texture(tint,'',0)
mySphere.texture(tint2,'',1)
mySphere.texture(sun,'',2)
mySphere.texture(moon,'',3)
mySphere.texture(clouds1,'',4)
mySphere.texture(clouds2,'',5)

# import shaders
myVert = viz.addVertexProgram('skydome_vshader.glsl')
myFrag = viz.addFragmentProgram('skydome_fshader.glsl')

# apply shaders to sphere
mySphere.apply(myVert)
mySphere.apply(myFrag)

# Use static clip plane so projection matrix doesn't change
viz.MainWindow.clip(0.1,100)
m = viz.MainWindow.getProjectionMatrix()

# assign uniforms to shaders
starPos = vizmat.Transform()
starPos.makeEuler(0,0,0)

sunPos = viz.addUniformFloat('sun_pos', [0,1,0])
mvp = viz.addUniformMatrix('mvp', m)
time = viz.addUniformFloat('time', 0)
weather = viz.addUniformFloat('weather', 0.5)
starPos = viz.addUniformMatrix('star_pos', starPos)

mySphere.apply(sunPos)
mySphere.apply(mvp)
mySphere.apply(time)
mySphere.apply(weather)
mySphere.apply(starPos)

# update sky model based on current time stamp
def ontimer(num):
time=viz.addUniformFloat('time', viz.FRAME_TIMESTAMP)
mySphere.apply(time)
#sky_vp.param(0,viz.get(viz.FRAME_TIMESTAMP)*CLOUD _SPEED)

viz.callback(viz.TIMER_EVENT,ontimer)
viz.starttimer(0,0,viz.FOREVER)

# add some ground
ground = viz.add('tut_ground.wrl')
ground.setPosition(0,-5,0)


################ VERTEX SHADER ################
#version 330 core
//---------IN------------
in vec3 vpoint;
in vec3 vnormal;
//---------UNIFORM------------
uniform vec3 sun_pos;//sun position in world space
uniform mat4 mvp;
uniform mat3 rot_stars;//rotation matrix for the stars
//---------OUT------------
out vec3 pos;
out vec3 sun_norm;
out vec3 star_pos;

//---------MAIN------------
void main(){
gl_Position = mvp * vec4(vpoint, 1.0);
pos = vpoint;

//Sun pos being a constant vector, we can normalize it in the vshader
//and pass it to the fshader without having to re-normalize it
sun_norm = normalize(sun_pos);

//And we compute an approximate star position using the special rotation matrix
star_pos = rot_stars * normalize(pos);






################ FRAGMENT SHADER ################
#version 330 core
//---------IN------------
in vec3 pos;
in vec3 sun_norm;
in vec3 star_pos;
//---------UNIFORM------------
uniform sampler2D tint;//the color of the sky on the half-sphere where the sun is. (time x height)
uniform sampler2D tint2;//the color of the sky on the opposite half-sphere. (time x height)
uniform sampler2D sun;//sun texture (radius x time)
uniform sampler2D moon;//moon texture (circular)
uniform sampler2D clouds1;//light clouds texture (spherical UV projection)
uniform sampler2D clouds2;//heavy clouds texture (spherical UV projection)
uniform float weather;//mixing factor (0.5 to 1.0)
uniform float time;
//---------OUT------------
out vec3 color;

//---------NOISE GENERATION------------
//Noise generation based on a simple hash, to ensure that if a given point on the dome
//(after taking into account the rotation of the sky) is a star, it remains a star all night long
float Hash( float n ){
return fract( (1.0 + sin(n)) * 415.92653);
}
float Noise3d( vec3 x ){
float xhash = Hash(round(400*x.x) * 37.0);
float yhash = Hash(round(400*x.y) * 57.0);
float zhash = Hash(round(400*x.z) * 67.0);
return fract(xhash + yhash + zhash);
}

//---------MAIN------------
void main(){
vec3 pos_norm = normalize(pos);
float dist = dot(sun_norm,pos_norm);

//We read the tint texture according to the position of the sun and the weather factor
vec3 color_wo_sun = texture(tint2, vec2((sun_norm.y + 1.0) / 2.0,max(0.01,pos_norm.y))).rgb;
vec3 color_w_sun = texture(tint, vec2((sun_norm.y + 1.0) / 2.0,max(0.01,pos_norm.y))).rgb;
color = weather*mix(color_wo_sun,color_w_sun,dist*0.5+0.5) ;

//Computing u and v for the clouds textures (spherical projection)
float u = 0.5 + atan(pos_norm.z,pos_norm.x)/(2*3.14159265);
float v = - 0.5 + asin(pos_norm.y)/3.14159265;

//Cloud color
//color depending on the weather (shade of grey) * (day or night) ?
vec3 cloud_color = vec3(min(weather*3.0/2.0,1.0))*(sun_norm.y > 0 ? 0.95 : 0.95+sun_norm.y*1.8);

//Reading from the clouds maps
//mixing according to the weather (1.0 -> clouds1 (sunny), 0.5 -> clouds2 (rainy))
//+ time translation along the u-axis (horizontal) for the clouds movement
float transparency = mix(texture(clouds2,vec2(u+time,v)).r,texture(clou ds1,vec2(u+time,v)).r,(weather-0.5)*2.0);

// Stars
if(sun_norm.y<0.1){//Night or dawn
float threshold = 0.99;
//We generate a random value between 0 and 1
float star_intensity = Noise3d(normalize(star_pos));
//And we apply a threshold to keep only the brightest areas
if (star_intensity >= threshold){
//We compute the star intensity
star_intensity = pow((star_intensity - threshold)/(1.0 - threshold), 6.0)*(-sun_norm.y+0.1);
color += vec3(star_intensity);
}
}

//Sun
float radius = length(pos_norm-sun_norm);
if(radius < 0.05){//We are in the area of the sky which is covered by the sun
float time = clamp(sun_norm.y,0.01,1);
radius = radius/0.05;
if(radius < 1.0-0.001){//< we need a small bias to avoid flickering on the border of the texture
//We read the alpha value from a texture where x = radius and y=height in the sky (~time)
vec4 sun_color = texture(sun,vec2(radius,time));
color = mix(color,sun_color.rgb,sun_color.a);
}
}

//Moon
float radius_moon = length(pos_norm+sun_norm);//the moon is at position -sun_pos
if(radius_moon < 0.03){//We are in the area of the sky which is covered by the moon
//We define a local plane tangent to the skydome at -sun_norm
//We work in model space (everything normalized)
vec3 n1 = normalize(cross(-sun_norm,vec3(0,1,0)));
vec3 n2 = normalize(cross(-sun_norm,n1));
//We project pos_norm on this plane
float x = dot(pos_norm,n1);
float y = dot(pos_norm,n2);
//x,y are two sine, ranging approx from 0 to sqrt(2)*0.03. We scale them to [-1,1], then we will translate to [0,1]
float scale = 23.57*0.5;
//we need a compensation term because we made projection on the plane and not on the real sphere + other approximations.
float compensation = 1.4;
//And we read in the texture of the moon. The projection we did previously allows us to have an undeformed moon
//(for the sun we didn't care as there are no details on it)
color = mix(color,texture(moon,vec2(x,y)*scale*compensatio n+vec2(0.5)).rgb,clamp(-sun_norm.y*3,0,1));
}

//Final mix
//mixing with the cloud color allows us to hide things behind clouds (sun, stars, moon)
color = mix(color,cloud_color,clamp((2-weather)*transparency,0,1));

}


All times are GMT -7. The time now is 01:03 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC