Using a custom shader in Rendered display mode

You can easily create a custom shader and use it to affect the way entities are drawn. Beware that this will override the shaders used by Eyeshot to draw that entity so you will lose all Eyeshot's effects.

The shader code is derived from this article and will work only with OpenGL renderer.

Here's how to do it.

  1. Define a class derived from GLShader class and a class to store the shader parameters:
class MyShaderParameters : ShaderParameters
{
   public readonly Vector3D Direction;

   public MyShaderParameters(Vector3D direction, RenderContextBase shaderParams) : base(shaderParams)
   { 
      Direction = direction;
   } 
} 

private class MyShader : GLShader 
{ 
   public MyShader(string vertexCode, string fragmentCode) : base(vertexCode, fragmentCode) 
   { 
   } 

   public override void SetParameters(object shaderParams) 
   { 
      MyShaderParameters myParams = (MyShaderParameters) shaderParams;

      RenderContextBase renderContext = myParams.renderContext;

      Enable(renderContext);

      Vector3D lightDir = myParams.Direction;

      gl.Uniform3f(GetUniformLocation("lightDir"), (float)lightDir.X, (float)lightDir.Y, (float)lightDir.Z); 

      Disable(renderContext); 
   } 
}

 

  1. Define a derived Entity class that stores the custom shader and uses it inside the Render() method:
class MyMesh : Mesh 
{ 
   public MyShader shader;

   protected override void Render(RenderParams data)
   {
// enable shader shader.Enable(data.RenderContext); base.Render(data); // disable shader data.RenderContext.SetShader(shaderType.None); } }

 

  1. Once the Form has been loaded create the shader, compile it, assing the parameters and assign the shader to the custom entity. Finally, add the entity to the scene:
protected override void OnLoad(EventArgs e)
{
    // Define the strings with the shader programs source code 
    string vertexShaderSource = @"
    
    varying vec3 normal;

    void main()
    {
    	normal = gl_Normal;
    	gl_Position = ftransform();
    
    }";

    string fragmentShaderSource = @"

    uniform vec3 lightDir;

    /* vec3 lightDir = normalize(vec3(gl_LightSource[0].position)); */

    varying vec3 normal;
    
    void main()
    {
    	float intensity;
    	vec4 color;
    	intensity = dot(lightDir,normal);
    
    	if (intensity > 0.95)
    		color = vec4(1.0,0.5,0.5,1.0);
    	else if (intensity > 0.5)
    		color = vec4(0.6,0.3,0.3,1.0);
    	else if (intensity > 0.25)
    		color = vec4(0.4,0.2,0.2,1.0);
    	else
    		color = vec4(0.2,0.1,0.1,1.0);

    	gl_FragColor = color;            
    }";

    Mesh cyl = Mesh.CreateCylinder(8, 20, 16); 
    cyl.Translate(20, 20);
    model1.Entities.Add(cyl, Color.CornflowerBlue); 

    // Create the shader and compile it 
    MyShader myShader = new MyShader(vertexShaderSource, fragmentShaderSource); 
    bool success = myShader.Compile(model1.renderContext); 

    if (success) 
    { 
        // Create the parameters and set them to the shader 
        Vector3D dir = new Vector3D(-1,-2,3);
        dir.Normalize();

        MyShaderParameters shaderParams = new MyShaderParameters(dir, model1.renderContext); 
        myShader.SetParameters(shaderParams); 

        // Create the custom entity and assign the shader to it 
        MyMesh myMesh = Mesh.CreateTorus(10, 4, 16, 16); 
        myMesh.shader = myShader; 
        
        // add the custom entity to the ViewportLayout             
        model1.Entities.Add(myMesh); 
    }

    Mesh box = Mesh.CreateBox(10,20,30); 
    box.Translate(-20, 20);
    model1.Entities.Add(box, Color.OliveDrab);
}

Screenshot:

Untitled-2.png

Previous versions of this article: Eyeshot 8Eyeshot 5

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.