Search Unity

Question Project Blender 3d Mesh to RenderTexture?

Discussion in 'General Graphics' started by oldhighscore, Jun 7, 2023.

  1. oldhighscore

    oldhighscore

    Joined:
    Nov 28, 2020
    Posts:
    79
    I have a sculpted 3d object from blender and I would like to project it into a texture for further use. What would be your approach in solving this problem? Some use cases might be to create a map, or to gain a heightmap set of data for further use (i.e. find the highest point).
     
  2. oldhighscore

    oldhighscore

    Joined:
    Nov 28, 2020
    Posts:
    79
    I was able to create a render texture and orthographic camera to produce what I was looking for as a starting point however it doesn't resolve how I might get the top layer of height data for processing. It seems like I would need some sort of sampling & projecting to get this grid of data into a heightmap (i.e. a 2 dimensional matrix with a height as value).

    upload_2023-6-7_9-55-51.png
     
  3. oldhighscore

    oldhighscore

    Joined:
    Nov 28, 2020
    Posts:
    79
  4. oldhighscore

    oldhighscore

    Joined:
    Nov 28, 2020
    Posts:
    79
    I have something close but appear to be having issues getting the depth height value not being correct & overlapping geoemtry. Anyone with shader experience able to help? Really just trying to get a grayscale heightmap output to the SV_TARGET and just view the texture in the editor.

    I was able to get this reference code working, but have since struggled to apply it properly for my use case William Chyr | Unity Shaders - Depth and Normal Textures (Part 1)

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. [RequireComponent(typeof(MeshFilter))]
    5. public class DepthTextureGenerator : MonoBehaviour
    6. {
    7.     public int textureResolution = 512;
    8.     public Shader depthShader;
    9.  
    10.     [HideInInspector]
    11.     public Texture2D InspectorDepthTexture;
    12.  
    13.     private Camera depthCamera;
    14.  
    15.     public void RenderDepthTexture()
    16.     {
    17.         Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
    18.         if (mesh == null)
    19.             return;
    20.  
    21.         if (depthCamera == null)
    22.             depthCamera = CreateDepthCamera();
    23.  
    24.         RenderTexture previousActiveTexture = RenderTexture.active;
    25.         RenderTexture depthRenderTexture = new RenderTexture(textureResolution, textureResolution, 0, RenderTextureFormat.ARGB32);
    26.         RenderTexture.active = depthRenderTexture;
    27.  
    28.         depthCamera.targetTexture = depthRenderTexture;
    29.         depthCamera.RenderWithShader(depthShader, "");
    30.  
    31.         InspectorDepthTexture = new Texture2D(textureResolution, textureResolution, TextureFormat.ARGB32, false);
    32.         InspectorDepthTexture.ReadPixels(new Rect(0, 0, textureResolution, textureResolution), 0, 0);
    33.         InspectorDepthTexture.Apply();
    34.  
    35.         RenderTexture.active = previousActiveTexture;
    36.         DestroyImmediate(depthRenderTexture);
    37.  
    38.     }
    39.  
    40.     private Camera CreateDepthCamera()
    41.     {
    42.         GameObject depthCameraObject = new GameObject("DepthCamera");
    43.         depthCameraObject.transform.parent = transform;
    44.         depthCameraObject.transform.localPosition = new Vector3(0f, CalculateOrthographicSize() * 2f, 0f);
    45.         depthCameraObject.transform.rotation = Quaternion.Euler(90f, 0f, 0f);
    46.  
    47.         Camera depthCam = depthCameraObject.AddComponent<Camera>();
    48.         depthCam.depthTextureMode = DepthTextureMode.Depth;
    49.         depthCam.enabled = false;
    50.         depthCam.orthographic = true;
    51.         depthCam.orthographicSize = CalculateOrthographicSize();
    52.         depthCam.clearFlags = CameraClearFlags.SolidColor;
    53.         depthCam.backgroundColor = Color.cyan;
    54.  
    55.         return depthCam;
    56.     }
    57.  
    58.     private float CalculateOrthographicSize()
    59.     {
    60.         Bounds bounds = GetComponent<MeshFilter>().sharedMesh.bounds;
    61.         float maxBoundsSize = Mathf.Max(bounds.size.x, bounds.size.z);
    62.         return maxBoundsSize * 0.5f;
    63.     }
    64. }
    65.  
    66.  
    Code (csharp):
    1.  
    2.  
    3. Shader "Custom/DepthShader" {
    4.     SubShader{
    5.         Tags { "RenderType" = "Opaque" }
    6.         Pass {
    7.             CGPROGRAM
    8.  
    9.             #pragma vertex vert
    10.             #pragma fragment frag
    11.             #include "UnityCG.cginc"
    12.  
    13.             struct v2f {
    14.                 float4 pos : SV_POSITION;
    15.                 float2 depth : TEXCOORD0;
    16.             };
    17.  
    18.             v2f vert(appdata_base v) {
    19.                 v2f o;
    20.                 o.pos = UnityObjectToClipPos(v.vertex);
    21.                 UNITY_TRANSFER_DEPTH(o.depth);
    22.                 return o;
    23.             }
    24.  
    25.             half4 frag(v2f i) : SV_Target {
    26.                 UNITY_OUTPUT_DEPTH(i.depth);
    27.             }
    28.             ENDCG
    29.         }
    30.     }
    31. }
    32.  
    33.  
    upload_2023-6-13_7-33-10.png
     
    Last edited: Jun 13, 2023
  5. oldhighscore

    oldhighscore

    Joined:
    Nov 28, 2020
    Posts:
    79
    In the end I went with a physics ray casting solution. I created a plane with the same planar bound as my blend and then casted away at the blend to get the resulting 2-dimensional grid I was looking for. All other approaches were to complex or didn't provide the accuracy needed. Now onto the fun part of using this grid of data, first stop creating a map!

    The depth based solution I was able to get to work after tweaking the min/max range of the camera depth to get a gradient range.
     
    Last edited: Jun 26, 2023