Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Help Wanted How to recalculate vector variables depending on the camera position in a shader?

Discussion in 'Shaders' started by tomekkie2, Jul 29, 2020.

  1. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    578
    I would like to write a shader to clip the space hidden by box from the view of the camera.
    The box data includes the box scale, position and rotation.
    I would also like to use _WorldSpaceCameraPos from the built-in shader constant.

    The space hidden by box is a conjunction of positive sides of up to 9 planes which I would like to calculate inside shader - basing on the four vectors above (rather than calculating in c# script and passing planes on every frame).
    Then the vectors for the planes will be used in the frag function to discard the pixels.

    I know how to write a function for this, but I need some hints how and where to put it in the shader file?
    Or it should be somehow placed inside the vertex function?
     
    Last edited: Jul 29, 2020
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,975
    What form is the scale, position, and rotation in? Ideally you want this to be a matrix you calculate on the CPU and pass to the shader rather than passing them in as separate values. Rotation especially. And really you want an inverse matrix to convert from world space to local box space. There's no need to do anything in the vertex shader, especially since you can't really clip from the vertex shader.

    So, once you have the inverse matrix in the shader, all you need to know is the world position of the fragment and the _WorldSpaceCameraPos, and transform them both from world space to local box space with that matrix, and you can calculate if the object is occluded by it or not. If you only care if the position is inside the box, that's even easier as after transforming the fragment's world position into box space you can do
    clip(abs(boxSpacePos) - 1.0);
    and you're done. (Note: that assumes your box matrix is calculating a 2 unit wide, 1 unit "radius", box. Use
    - 0.5
    if you want it it to be a 1 unit wide box.)
     
    tomekkie2 likes this.
  3. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    578
    Thank you, but what I like to clip is not an inside of the box, but the space hidden from camera by this box.
    This is something like cone, but not a cone precisely.
    When I keep a rubic's cube in my hand - I see that this is a space restricted by 5 or 8 or 9 planes depending on the cube orientation retated to my eye.
    So I would like to calculate this space from the box matrix and _WorldSpaceCameraPos in the shader itself rather than passing these planes from outside.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,975
    Doesn't change anything but the last sentence of my reply. You need to do all of the same work, but use a box intersection function using the box space camera position (aka ray origin) and box space view direction (box space fragment position - box space camera position, aka ray direction). See the box intersection function here:
    https://www.iquilezles.org/www/articles/boxfunctions/boxfunctions.htm
     
    tomekkie2 likes this.
  5. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    578
    Worked great. Your sentences are worth their weight in gold.
     
unityunity