WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Custom Effect Shading (https://forum.worldviz.com/showthread.php?t=5804)

Vaquero 08-01-2016 01:55 AM

Custom Effect Shading
 
Hey!
I'm trying to change they way models get shaded, so I was looking into the custom effects. The documentation only gives very simple examples.

When things get more complicated I need helper functions, but I suspect these are not supported to work with vizard's effects framework?
Let's do a really simple dummy example.

Assume inside the shader code I want to use this helper function:
Code:

float halve(float k)
{
    return k*0.5;
}

Of course, in a real world example it will be much more complicated than this.

But whereever I put this function, it throws some error. Inside Shader, but outside Units:
Code:

# Setup model
logo = vizfx.addChild('logo.osgb')

code = """
Effect CustomShadingModel {
       
        Shader {
            float halve(float k)
                {
                  return k*0.5;
                }
               
            BEGIN FinalColor
            float half_r = halve(gl_FragColor.r);
            gl_FragColor.rgb = vec3(half_r, 1.0, 1.0);       
            END               
    }
}
"""
customEffect = viz.addEffect(code)

# Apply effect specifically to a model
logo.apply(customEffect)

throws:
Quote:

** WARNING: Invalid character when parsing "", line 8:
float halve(float k)
If I put it in the properties, I get the same error, and if I put it inside the Unit section I get another error message.

So is this really not possible with the effects framework?

If not, I would have to use a custom GLSL fragment shader? But the documentation on this is very sparse (just a make-a-uniform-color-example). How do I get the ViewDirection, the surface normal, the light direction, etc. to be used inside the shader code? And how can I apply the shader to all osgb models loaded and reference their texures inside the code? Because I don't want to set all textures for a hundred objects via script.

Vaquero 08-01-2016 07:29 PM

Could someone please post a simple example that shows how to access the variables for normal, eyevec, viewDir etc. in a custom GLSL fragment shader?
The make-it-all-red sample in the documentation isn't helping:
Code:

fragCode = """
void main()
{
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
"""

shader = viz.addShader(frag=fragCode)

That's just TOO simple.

Jeff 08-02-2016 04:52 AM

Quote:

When things get more complicated I need helper functions, but I suspect these are not supported to work with vizard's effects framework?
I'll check with a developer. Do you need a separate function or can you include the operations directly in the shader code? In the last example on the Example Effects page a number of operations are applied in sequence. Perhaps you can achieve the same result this way. What is the effect you are trying to create?

Vaquero 08-03-2016 11:20 AM

The effect I'm trying to achieve is a modern approach to energy conserving shading, but there's an extra thread for that (http://forum.worldviz.com/showthread.php?t=5535). Here, I'd like to get information on how to use the custom effects and shaders in general, because it's unclear to me what's supported and what is not.

I tried using the addShader function instead of the effects framework, but this doesn't seem to work in Vizard as I would expect it to, whereas the exact same code produces visible results in ShaderMaker (http://cgvr.cs.uni-bremen.de/teaching/shader_maker/), though the shader code must contain some errors in the calculations of _normalDir, _viewDir or light0Dir.

Here's the Vizard script:
Code:

import viz
import vizfx
import vizcam

viz.setMultiSample(8)
viz.fov(60)
viz.go()

# Setup camera navigation
cam = vizcam.PivotNavigate(distance=8.0, center=(0,1,0))

# Setup lighting
viz.MainView.getHeadLight().remove()
light = vizfx.addPointLight(color=viz.WHITE, pos=(4,4,-4))
vizfx.setAmbientColor(viz.BLACK) # disable ambient light

# Setup environment
vizfx.addChild('sky_day.osgb').renderToBackground()

# Setup models
logo1 = vizfx.addChild('logo.osgb')

vertCode = """
varying vec3 _viewDir;
varying vec3 _normalDir;
varying vec3 light0Dir;

void main()
{
        vec4 eyeVertex = gl_Vertex;
        vec3 eyeNormal = gl_Normal;

        eyeVertex = gl_ModelViewMatrix * eyeVertex;
        eyeNormal = normalize(gl_NormalMatrix * eyeNormal);
        vec4 eyeViewDir = vec4(eyeVertex.xyz,0.0);
        _viewDir = eyeViewDir.xyz;
        _normalDir = eyeNormal;
        vec3 dir = gl_LightSource[0].position.xyz - eyeVertex.xyz;
        light0Dir = dir;

        gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
}
"""

# PBR Calculations
fragCode = """
uniform float roughness;

varying vec3 _viewDir;
varying vec3 _normalDir;
varying vec3 light0Dir;

const float PI = 3.14159265358979323846;

float sqr(float x) { return x*x; }

float GGX(float alpha, float cosThetaM)
{
    float CosSquared = cosThetaM*cosThetaM;
    float TanSquared = (1.0-CosSquared)/CosSquared;
    return (1.0/PI) * sqr(alpha/(CosSquared * (alpha*alpha + TanSquared)));
}

vec3 BRDF( vec3 L, vec3 V, vec3 N)
{
    vec3 H = normalize( L + V );
    float D = GGX(roughness, dot(N,H));
    return vec3(D);
}

void main()
{
        vec3 color = BRDF(light0Dir, _viewDir, _normalDir);
        gl_FragColor.rgb = color;
}
"""
pbrShader = viz.addShader(vert=vertCode, frag=fragCode)
logo1.apply(pbrShader)

roughnessUniform = viz.addUniformFloat('roughness',0.6)
logo1.apply(roughnessUniform)

The model doesn't show up at all!


I saw that in the composer.vizfx file matrices like gl_ModelViewProjectionMatrix are used, that's why I used them here and because I have no idea how to get the matrices from vizard. But these matrices are deprecated since GLSL version 4.1. So which version is Vizard using?

Are varying variables between vertex and fragment shader supported?

Vaquero 08-03-2016 12:20 PM

I just realized that varying is also deprecated in newer versions and in/out are used instead.
It's confusing since most tutorials for glsl seem to rely on older versions.

Vaquero 08-03-2016 02:32 PM

Even the global variable gl_FragColor is deprecated after version 120.

I would really appreciate a more complete example for the custom vertex and shader implementation, where something gets actually lit instead of just turned red.

Until then, I see if I can sort through it, but it's difficult not knowing what's supported and what is not.

Jeff 08-04-2016 03:45 AM

I'll ask a developer to take a look at your questions and try to help here.

Vaquero 08-04-2016 07:27 AM

Thanks a lot, Jeff!

Vaquero 08-06-2016 06:51 PM

I have further questions. Is there a way in Vizard to retrieve a normal buffer? I can get a depth buffer for post-process effects (vizpp_InputDepthTex), but what I need is a texture with the object's/fragment's normals.
How do I do that?

Another question: The help states that the osg_ViewMatrix is available to all shaders used with vizard. Can someone please tell me, how I would get the current view position and the view direction from that matrix?
Thanks!


All times are GMT -7. The time now is 08:18 AM.

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