Texture distortion shader on a 3D mesh

Started by
2 comments, last by mikiex 11 years ago

Hi all, I'm trying to implement an effect in a shader at the moment. The basic premise of it is that a user will click on a point on a 3D mesh, then a texture distortion effect will spread out from that point. I've seen example code for other distortion effects such as ripples but I'm having difficulty with implementing something similar as they all seem to assume you know the texture coordinate center that the effect is originating from, however I only currently know the point in 3D space where it originates from and I'm not sure how to properly translate that into a usable 2D texture coordinate for the current fragment. Can anybody offer any help? :) Thanks.

PS. Sorry if I'm missing something completely obvious here. I'm still pretty new to graphics programming! :)

Advertisement

It sounds like you have a way to determine a point on the 3d mesh where the user clicked. So presumably you have access mesh data. Presumably you're ray casting against the mesh's triangles? You should be able to pick up the texture coordinate from the vertex data for that triangle.

However - typically there isn't a tight correlation between the point to point distance over a mesh surface, and the texture coordinates used at those points. Textures are squares/rectangles, and don't map smoothly on complex surfaces. So if you're expecting to have some effect that ripples out from a point across the surface of an arbitrary mesh, it's not going to be as trivial as a ripple effect across a flat plane. If you just have simple geometry though, you might be able to get something convincing (if I'm understanding what you want).

You may be able to do this with a 3D distortion texture. Just input the vertex positions (scaled by some appropriate amount) as texcoords and it should work well. Using this kind of system the answer to your question becomes obvious - the point in 3D space that the distortion originates from gives the texcoords for your distortion center point.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

To further what Mhagain is saying:

You might want to also consider doing a distortion in screen space, or world space

You could:

input a float3 constant of the world position you want the centre of the effect from into a shader.

In the shader use the world position of a pixel (you can work this out in the vertex shader and output it to the pixel shader)

Now you can do some sort of effect in worldspace.

For instance (ugly - pseudocode! - some things maybe the wrong way around!):

in the pixel shader:

WorldGradient = distance(CentreOfEffect,WorldPixelPos) //a float result of a gradient in worldspace

ripple = sin((WorldGradient*Freq)+(Time*Speed)) //sine wave out from the centre of your effect that moves with Time (input that as a constant)

ripple = ripple*gradient //fade off effect

//So now you have a greyscale ripple in worldspace, combine this into the texture coords of the texture you want to distort

texture = tex2d(tex.xy+ripple,sampler)

//Freq is whatever looks good, this could be multiplied in some way by the distance to make the ripples get larger as they go out.

This topic is closed to new replies.

Advertisement