Pass the normals please

Space_ShamanSpace_Shaman Posts: 8Member

So, I'm working on a 3d project that uses heavily stylized rendering. My problem is that I need to post-process the normals of every surface on screen. I intend to filter these. Think like a sobel filter but with dot products between the center and the 8 surrounding pixels. The 4 albedo channels just aren't enough, or id use those. I could always pack the colors and normals into 2 channels each using some dumb algorithm. NORMAL_TEXTURE in the canvas item shaders doesnt do what you'd hope it does on a viewport.

Best Answer

  • Space_ShamanSpace_Shaman Posts: 8
    Accepted Answer

    I have worked out a workaround. What you do is set up an extra camera as a child of it's own viewport inside a viewport container. Turn the camera 180 degrees on the z-axis and set the scale of the viewport container to (-1, -1) to reverse the rotation. In the shader of each object pass in the transform of both cameras. You need to run a test in the vertex function to tell which camera is being drawn. Using this information you can draw the normals as the albedo whenever the normal-camera is being drawn. You can now use the extra viewport texture for post processing. Congrats.

Answers

  • SIsilicon28SIsilicon28 Posts: 757Moderator

    Yeah... About that. There's currently no way of accessing the screen size normals in a 3D scene in Godot 3.2. :(

  • Space_ShamanSpace_Shaman Posts: 8Member

    I assume you mean, not without doing so instead of the albedo. I've been trying to devise a decent workaround.

  • SIsilicon28SIsilicon28 Posts: 757Moderator

    The only work around would be to approximate it using the DEPTH_TEXTURE. This would not take into account normal maps, and smooth shading. That's all you've got for now.

  • Space_ShamanSpace_Shaman Posts: 8Member

    But you cant write to the depth texture. Although you can write to the depth. But thats just a single float. Its still one channel more. The stylization I'm developing basically throws any built in light processing out the window. Thank you though. I really appreciate the help.

  • Space_ShamanSpace_Shaman Posts: 8Member
    Accepted Answer

    I have worked out a workaround. What you do is set up an extra camera as a child of it's own viewport inside a viewport container. Turn the camera 180 degrees on the z-axis and set the scale of the viewport container to (-1, -1) to reverse the rotation. In the shader of each object pass in the transform of both cameras. You need to run a test in the vertex function to tell which camera is being drawn. Using this information you can draw the normals as the albedo whenever the normal-camera is being drawn. You can now use the extra viewport texture for post processing. Congrats.

  • SIsilicon28SIsilicon28 Posts: 757Moderator

    Insightful! Good work. 👍
    How can the shader tell which camera's being used if you don't mind me asking.

  • Space_ShamanSpace_Shaman Posts: 8Member
    edited August 23

    The camera for the normals is flipped upside down. This means that CAMERA_MATRIX will be different for that camera. CAMERA_MATRIX is then compared in the vertex function with the camera transforms which you pass in by uniform (in gdscript). I tested this all and it all works.
    Edit: for clarity

  • Space_ShamanSpace_Shaman Posts: 8Member
    edited August 22


    I should mention that ive run a sobel over the normals with depth in the alpha channel

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file