Search Unity

Bug Sampling custom textures not working in DOTS 1.0

Discussion in 'Graphics for ECS' started by Vacummus, Jan 2, 2023.

  1. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    I just recently upgraded from DOTS 0.17 to 1.0 for a URP project. I am using a ForwardRenderer to render some custom textures and then I have shaders read from those textures like so (called from shader graph):

    Code (CSharp):
    1. TEXTURE2D(_DepthNormalsTexture);
    2. SAMPLER(sampler_DepthNormalsTexture);
    3.  
    4. void GetDepthNormal_float(float3 screenPosition, out float3 OUT)
    5. {
    6.     OUT = SAMPLE_TEXTURE2D(_DepthNormalsTexture, sampler_DepthNormalsTexture, screenPosition);
    7. }
    Nothing out of the ordinary here, pretty standard stuff. However, for objects within a subscene (which get converted to entities), it is failing to read my custom textures. This works fine if the objects are not in the subscene. The preview window for my material of this shader also renders fine. It even worked in DOTS 0.17 with the old hybrid renderer. So this looks like a bug for the new entites.graphics package, unless I am missing something here?
     
    charleshendry likes this.
  2. charleshendry

    charleshendry

    Joined:
    Jan 7, 2018
    Posts:
    97
    Ah, I might have a similar issue with my texture 2D arrays then. Was working fine for previous entities release. Nothing is rendering from the subscene now and couldn't work out what the issue was.
     
  3. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    How is this texture set? Is it set on the Material, or set globally? However, in either case it would be expected to work, so it's possible you have discovered a bug.
     
  4. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    It's set globally with the ScriptableRenderFeature below:

    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;

    public class RenderToTextureByMaterial: ScriptableRendererFeature
    {
    [Serializable]
    public class Settings
    {
    public Material material;
    public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPrePasses;
    public string textureName = "_textureName";
    }

    [SerializeField]
    private Settings settings = new Settings();
    RenderToTexturePass pass;

    public override void Create()
    {
    pass = new RenderToTexturePass(settings.material, settings.textureName);
    pass.renderPassEvent = settings.renderPassEvent;
    }

    // Here you can inject one or multiple render passes in the renderer.
    // This method is called when setting up the renderer once per-camera.
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
    renderer.EnqueuePass(pass);
    }
    }

    class RenderToTexturePass: ScriptableRenderPass
    {
    RenderTargetHandle depthNormalsTexture;
    private Material material;
    private FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
    List<ShaderTagId> shaderTags = new List<ShaderTagId>() {
    new ShaderTagId("DepthOnly")
    };

    public RenderToTexturePass(Material material, string textureName)
    {
    this.material = material;
    depthNormalsTexture.Init(textureName);
    }

    public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
    {
    cmd.GetTemporaryRT(depthNormalsTexture.id, cameraTextureDescriptor, FilterMode.Point);
    ConfigureTarget(depthNormalsTexture.Identifier());
    ConfigureClear(ClearFlag.All, Color.black);
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
    var drawSettings = CreateDrawingSettings(shaderTags, ref renderingData, renderingData.cameraData.defaultOpaqueSortFlags);
    drawSettings.overrideMaterial = material;
    context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filteringSettings);
    }

    public override void FrameCleanup(CommandBuffer cmd)
    {
    cmd.ReleaseTemporaryRT(depthNormalsTexture.id);
    }
    }

    I also tried it on a fresh new project (Unity 2022.2.0f1, Entities 1.0.0-pre.15) and am still seeing the issue. Next, I plan to give RenderTextures a go as a workaround for this.
     
  5. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    I can't see any code in the sample which sets that texture for sampling (e.g. Material.SetTexture, Shader.SetGlobalTexture, CommandBuffer.SetGlobalTexture). I'm assuming it should happen automatically due to the .Init() call (which in this snippet seems to use the name "_textureName" and not "_DepthNormalsTexture") ?

    If the code works for GameObjects but not Entities, then I would recommend submitting a bug with a repro project so we can investigate why it doesn't work. There hasn't been any intentional change in 1.0 which would cause this to fail.
     
  6. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    Yup, I also assume it gets set globally with the init call. And "_textureName" is just the default name that gets overridden in the inspector of the forward renderer, like so:



    Yup, when I get a chance today I'll report the bug.
     

    Attached Files:

  7. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    JussiKnuuttila likes this.