Home Unreal Engine

Generell Refraction based on Snell's Law

Hi,
I want to create a general refraction shader based on physical laws like Snell's one. I alredy tried to transform his term n1 * sin(a) = n2 * sin(b) while n1 equals the IOR of the surrounding substance and n2 the IOR of the actual Object, a being the input degrees of the light and b the output degrees.
(Source of my thoughts : http://en.wikipedia.org/wiki/Snell%27s_law)

So I came up with sin(b) = n1 * sin (a) / n2 - nothing special.
My problem is having just b on the left part. for that I should have
b = arcsin[n1 * sin(a) / n2]. But UDK does not have an arcsine node inside the material editor and I cannot find the correct mathematic therm (or some which is able to be put inside the material editor) of arcsine anywhere on the web.
This step is not completly necessary because of just having b= n1 * a / n2 creats very near results to the ones with the sinenodes in a calculator.
But still it is not working correctly, because of distorting to less and taking to less weight at the actual form of the object.

In this case I am using glass as an example but my goal is creating a shader which is usable for most or better all materials I would like to produce (Like the physical Laws are mostly guilty for all substances).

So how can I make this working physicly correct?



My distortion-shader at the moment:
Shader.JPGShader.JPGShader.JPG


Current result while using with IOR of Glass (1.52):
Example.JPGExample.JPGResult_1.JPG


Results I would like to achieve:
GraphicDemo_3.JPGGraphicDemo_3.JPGhttp://3.bp.blogspot.com/_pjMcWzh34dg/Sfo2kfbVUTI/AAAAAAAAAAU/BzeYJ-MHhiI/s1600-h/GraphicDemo_3.JPG

Also does anyone have a great source for palmfrond textures? Everyone I find is either looking terrible or even able for being in use for a good texture. :poly124:

Replies

  • Drew++
    Options
    Offline / Send Message
    Drew++ polycounter lvl 14
    Seems like there would be some long steps you need to do to get an inverse sine, tangent or cosine. Definitely not practical anyways...

    If you really need this, you could always use a custom code node like this...
    ss%20%282012-10-10%20at%2002.14.02%29.png
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Unless I misunderstood, couldn't you just use the Custom Node and put in "refraction" instead of making out the entire code manually? Same cost last I checked around.
  • StirriX
    Options
    Offline / Send Message
    Drew++:
    Thank you, I did not know this was possible through the custom node.

    Ace-Angel:
    Everything I read until now told me to use custom nodes as less as possible, because of them being so hard to compute compared to the standard nodes. So i would rather translate it to the usual nodes. Or is there already an implemented function for the refraction?

    Sorry for such questions I have never done something with custom nodes and have still few experience with UDK and generall 3d engines.

    Also I noticed another issue:

    Depending on the direction of view the distortion is changing between refracting up and down.

    View in X-direction:
    XDirection.JPG

    View in opposite X-direction:
    OppositeXDirection.JPG

    I also notices that this happened before - it only changes the axis of this event from y to x through the asin. Is it possible that the reflection vector, through which i wanted to get the angel of view to the object , is causing this?

    Edit: sorry for the bugs with the images. I am also new to this forum and I cannot get the preview working properly.

    Edit2: got it :)!
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    For one off functions like Drew mentioned it's totally fine, also, stuff like refractions or any other code that's already available to your engine or OS is also fine: http://msdn.microsoft.com/en-us/library/windows/desktop/ff471376%28v=vs.85%29.aspx

    However, now that I look at it, it seems like you don't need Environment Refraction, since the Refraction I'm talking about turns cubemaps and such upside down, so just forget about it.

    Your Refraction is the one where it bends what the user sees through it, right?

    In that case, I don't know if it's possible to use Snell's Law in UDK, since UDK doesn't seem to recognize the environment as a 3D Space when using said Law, it well always end up bending one side differently to the other, without respecting the Normals.

    Also, I think if you look 'up' with the Law, it will actually create an circle/black hole kind of issue.

    The cheapest solution is to either use a Fresnel, or a Reflection Vector OR, use a Spherical Mapping with a round Normal Map to 'fake' the bend, these will give you the most 'stable' results.

    If anyone wants to correct me, please do, it's been a couple of months since I last tried to get Snell's refraction working, and it didn't work too well.
  • StirriX
    Options
    Offline / Send Message
    Ace-Angel wrote:
    Your Refraction is the one where it bends what the user sees through it, right?
    Exactly.

    Also thanks for the helpful link :).
    Ace-Angel wrote:
    In that case, I don't know if it's possible to use Snell's Law in UDK, since UDK doesn't seem to recognize the environment as a 3D Space when using said Law, it well always end up bending one side differently to the other, without respecting the Normals.
    But why then is UDK calculating the distortion differently when using this material with a cube and a glass?

    CalculationCube.JPG

    As you can see the distortion has no bending when used with a cube. only with round objects like spheres or my example-glass. So this should not be caused by the normals.
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Hmm, that's stranger then before. Do you have a Normal Map applied to your other model and not a 0,0,1 Constant?

    Also, do you mind posting up an image of your Snell shader setup, because in my case, almost always one side of the cube looked like a black-hole.
  • StirriX
    Options
    Offline / Send Message
    I did not plug in anything into the normal slot, but now I tried it and it does not change anything.

    My settings for the material:
    Translucent
    Phong
    TwoSided: true


    The current shader (The one from the start of the threat but with the asin added):
    Shader_2.JPG


    Results with an noise-normal map applied:
    Shader_2_normal.JPG
    As you can see it does not change anything serious in comparison to the earlier
    screenshots. A constant-3-vector changes nothing.

    If I use a fresnel instead of the reflection-vector it reduces the distortion to a minimum. Even with a normal applied to the slot of the fresnel does not change anything noticable. But it cleares the issue with the changing distortion depending on the view direction. Only the edges off the horizon are a little bit bent (changing the values of the fresnel also has no nice effects):

    Shader_2_fresnel.JPG

    Also would you also like to post up your old snell shader? Maybe we get something decent if we combine both somehow togther.
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    This is where I got it from: http://thangnguyendemo.blogspot.ca/2009/04/new-beginning.html

    rw8oA.jpg

    MkV4B.jpg

    As you can see, it doesn't make a huge amount of difference from a Fresnel to this, it could be because I have a mistake in my setup maybe.

    Here what happens when I try instead to sample the scene using SceneTexture with this setup (since UDK can only sample the scene in 2D, you get this):
    wZKa0.jpg

    If anyone has advice, please do tell, I have no idea how this kind of refraction is supposed to look correctly.
  • StirriX
    Options
    Offline / Send Message
    Hmm, I doubt this shader not beeing able to be converted from hlsl to udk. I also cannot see any connection between snells formula and this hlsl-code.

    The effect simliar to the fresnel is caused by the dot-product of the camera vector and the 3-constant-vector.
    Example:
    DotProductExample.jpg
    (http://udn.epicgames.com/Three/rsrc/Three/MaterialsCompendium/DotProductExample.jpg)

    Sorry, I am not able to take my own screenshots, because of my computer not working anymore and my replacement cannot handle udk.
  • StirriX
    Options
    Offline / Send Message
    After what seemed like ages of work with this shader I also believe udk not recognizing the objects as 3D. Would there be any possibility to gain access to the vertex positions of the meshes to create something like a displacement map or a normal map, created in realtime inside the material editor, so we could fake a 3-dimensional detection?
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    No, even with source-code, it wouldn't feasible (which is what I have been trying tell you for the past 2 posts.
  • StirriX
    Options
    Offline / Send Message
    Hm ok that is sad. Sorry for being so stubborn.
  • JamesWild
    Options
    Offline / Send Message
    JamesWild polycounter lvl 8
    I'd argue physically accurate refractions aren't needed for today's use cases anyway. Things like glasses are too small for the inaccuracies to be easy to spot. Heat haze and water move making the inaccuracies hard to spot. Windows are largely flat and don't noticeably refract a great deal. They're nice in raytraced environments because they demonstrate how raytracing approximates the physical model of lighting.

    If you can specify what it is you're refracting, how it will be seen in the engine, and so on, perhaps a solution can be found that fits.
  • StirriX
    Options
    Offline / Send Message
    Finally it should be used within a water shader, returning a pretty accurate refraction depending on the waves. Optional this shader should be able to be used within other materials only with changing the IOR. But after considering what you said this seems pretty useless.
  • Drew++
    Options
    Offline / Send Message
    Drew++ polycounter lvl 14
    StirriX wrote: »
    After what seemed like ages of work with this shader I also believe udk not recognizing the objects as 3D. Would there be any possibility to gain access to the vertex positions of the meshes to create something like a displacement map or a normal map, created in realtime inside the material editor, so we could fake a 3-dimensional detection?

    If you want any normals, just do this. For reflections you'll probably want view space(screen space) normals.

    normals.jpg
    If you want normal maps in there, use a normal map, instead of that constant3(0,0,1)
  • JamesWild
    Options
    Offline / Send Message
    JamesWild polycounter lvl 8
    Yep that's the way I've always done it too. Implementation note: if you're feeding this into distortion, do not include the boxed bit that moves it from -1 to 1 space into 0 to 1 space. The distortion input is a vector2 input that scrolls the framebuffer around and packing it into 0 to 1 space makes it only distort in one direction and off centre. Instead multiply it by a vector1 to set the intensity of the effect.

    You might be able to fudge some extra "realism" by altering it by destdepth for variable convergeance, but I imagine that would cause more problems than anything else with doubling of objects in the scene and such.

    Experiment! Enjoy.
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    That's the problem, isn't it? No matter what you do, you simply cannot achieve the 'real' result as you would wish in any way.

    Example: http://www.animations.physics.unsw.edu.au/jw/light/Snells_law_and_refraction.htm

    There are way too many things to consider, and since UDK doesn't even allow the scene-normal buffer to be exposed easily or at all in some cases, or it only sees the environment behind the objects as a 2D scene, you might as well do things manually.

    Besides, no one is going to care about your glass shader if it doesn't cast the typical 'rainbow' caustics, which no real-time engine does, last I checked. So you enter an uncanny valley issues where your material looks realistic, but the subtleties which bring it to life like those mentioned are non-existent, and you end up having this weird 'dead' material.
  • StirriX
    Options
    Offline / Send Message
    Thanks for all your help! I will try some possible solutions and will answer as soon as I am done :).
  • StirriX
    Options
    Offline / Send Message
    Already my first try returned some strange results.


    BumpMappedSceneTextureShader.JPG

    (Transform : Tangent -> View)


    1: With this shader I reached a scene-texture, which rotated itself with the object. This means if a object is rotated about 180 degrees it gives some effects similiar to a reflection:

    BumpMappedSceneTexture.JPG

    2:
    Not surprisingly this setup produces huge artefacts:

    BumpMappedSceneTextureArtifacts.JPG

    Inside the custom node is this code:

    return normalize( cross(ddy(inWorldPosition.xyz), ddx(inWorldPosition.xyz)) );

    (Source: http://www.volumesoffun.com/polyvox/documentation/dokuwiki/computing_normals_in_a_pixel_shader)
  • StirriX
    Options
    Offline / Send Message
    Just forget about my last post. It only displays the objects between the camera and the object.
Sign In or Register to comment.