# Update a custom uniform in a modified shader

**URL:** https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366
**Category:** Support
**Created:** [July 17, 2019, 12:35pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366 "2019-07-17T12:35:19Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Jellby](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jellby/32/135_2.png) [@Jellby](https://discourse.vtk.org/u/Jellby)
#### Post date: [July 17, 2019, 12:35pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366/1 "2019-07-17T12:35:19Z")

</div>

I have modified the default `vtkOpenGLPolyDataMapper` along the lines of [https://github.com/dmreagan/vtk-shaders](https://github.com/dmreagan/vtk-shaders) (case 1). I have also added a new uniform, which I can set as it is done for `diffuseColor` in [https://github.com/Kitware/VTK/blob/master/Rendering/OpenGL2/Testing/Python/TestUserShader2.py](https://github.com/Kitware/VTK/blob/master/Rendering/OpenGL2/Testing/Python/TestUserShader2.py). However, as far as I can see, that sets a hardcoded fixed value for `diffuseColor`, and I would like something I can change “live” (with e.g. a slider on a GUI). This works fine for default uniforms like Opacity: I just call `actor.GetProperty().SetOpacity(value)` and the mapper udates automatically. How can I do the same with a custom uniform?

This was already asked in [http://vtk.1045678.n5.nabble.com/Update-Custom-Uniforms-for-Shaders-td5739937.html](http://vtk.1045678.n5.nabble.com/Update-Custom-Uniforms-for-Shaders-td5739937.html), but the “solution” is basically the same code as above, it seems to be giving a fixed value to `diffuseColor`.

---

<div class="post-metadata">

### Author: ![dmreagan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dmreagan/32/7489_2.png) [@dmreagan](https://discourse.vtk.org/u/dmreagan)
#### Post date: [July 25, 2019, 4:18pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366/2 "2019-07-25T16:18:22Z")

</div>

In the example from _TestUserShader2.py_, the value of `diffuseColor` is set inside the callback, as follows:

```python
@vtk.calldata_type(vtk.VTK_OBJECT)
def vtkShaderCallback(caller, event, calldata):
    program = calldata
    if program is not None:
        diffuseColor = [0.4, 0.7, 0.6]
        program.SetUniform3f("diffuseColorUniform", diffuseColor)

```

…

```python
mapper.AddObserver(vtk.vtkCommand.UpdateShaderEvent, vtkShaderCallback)

```

`vtkShaderCallback` runs each time an `UpdateShaderEvent` is observed, and each time `diffuseColorUniform` is being set to [0.4, 0.7, 0.6]. So you want to assign `diffuseColor`'s value somewhere outside of `vtkShaderCallback`, like in your GUI slider callback. This way, each time `vtkShaderCallback` runs, it will fetch the new value for `diffuseColor` and set the uniform accordingly.

---

<div class="post-metadata">

### Author: ![Jellby](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jellby/32/135_2.png) [@Jellby](https://discourse.vtk.org/u/Jellby)
#### Post date: [July 25, 2019, 4:38pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366/3 "2019-07-25T16:38:20Z")

</div>

Thanks. I have solved it by subclassing `vtkOpenGLPolyDataMapper`:

```
class AOIMapper(vtk.vtkOpenGLPolyDataMapper):
    def __init__ (self, *args, **kwargs):
        super(). __init__ (*args, **kwargs)
        self.MyCustomUniform = 0.0
        self.AddShaderReplacement(...)
        self.AddObserver(vtk.vtkCommand.UpdateShaderEvent, self.update_shader)
    @vtk.calldata_type(vtk.VTK_OBJECT)
    def update_shader(self, caller, event, program):
        if program is not None:
            program.SetUniformf("MyCustomUniform", self.MyCustomUniform)

```

And then in the rest of the code, something like:

```
actor.GetProperty().SetOpacity(opacity_value)
actor.GetMapper().MyCustomUniform = custom_value
```

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [July 25, 2019, 4:47pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366/4 "2019-07-25T16:47:29Z")

</div>

Are you aware of the recently introduced [vtkUniforms](https://vtk.org/doc/nightly/html/classvtkUniforms.html) class that allows you to get/set custom uniforms anytime, anywhere, without worrying about adding callback functions, etc. Uniforms are accessible via [vtkShaderProperty::Get…CustomUniforms()](https://vtk.org/doc/nightly/html/classvtkShaderProperty.html) methods.

@Simon are there some simple standalone examples?

---

<div class="post-metadata">

### Author: ![Jellby](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jellby/32/135_2.png) [@Jellby](https://discourse.vtk.org/u/Jellby)
#### Post date: [July 25, 2019, 4:57pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366/5 "2019-07-25T16:57:29Z")

</div>

How recently? I need it to work with VTK 8.1.2 (pip version). I remember I’ve seen the stuff, but either it wasn’t working or I couldn’t figure out how.

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [July 25, 2019, 5:25pm UTC](https://discourse.vtk.org/t/update-a-custom-uniform-in-a-modified-shader/1366/6 "2019-07-25T17:25:16Z")

</div>

It was added a few months ago, so it is not included in VTK 8.1.2.

If you need a Python distribution that contains recent VTK then you can use Python included in a recent Preview Release of [3D Slicer](https://download.slicer.org/). VTK is already bundled and you can pip install any other packages.
