首页 > 其他分享 >Unity显示 物体的最小uv

Unity显示 物体的最小uv

时间:2023-10-31 16:44:06浏览次数:34  
标签:fieldbuf MainTex 物体 uv vertex Field Unity 1f


开发过程中遇到同一个mesh,同一个shader,但是出现渲染结果不一致的情况。
初步猜测是光栅化后,像素中心对应物体的位置不同,uv通过插值生成,从而导致渲染结果不一致。
下文验证了uv会随着物体的位置不同,而发生改变。

验证

使用了 https://github.com/cinight/MinimalCompute 项目中的 05_1_UAVInShader 例子。

using UnityEngine;
using System.Collections;
using UnityEngine.Rendering;

public class UAVInShader : MonoBehaviour
{
    public Material mat;
    public TextMesh text;

    private int targetID = 6; //match with shader "register(u6)"
    private ComputeBuffer fieldbuf;
    private float[] fdata = new float[3] { 1f, 1f, 1f };


    public int count;

    public bool ResetValue;

    void OnEnable()
    {
        Setup();
    }

    void OnDisable()
    {
        fieldbuf.SetData(new float[] { 1f, 1f, 1f });
            Graphics.ClearRandomWriteTargets(); //this prevent crash
        if (fieldbuf != null)
        {
            fieldbuf.Release();
            fieldbuf.Dispose();
            fieldbuf = null;
        }


    }

    void Setup()
    {
        if (fieldbuf == null)
        {
            fieldbuf = new ComputeBuffer(4, sizeof(float), ComputeBufferType.Default);
        }


    }


    void OnRenderObject()
    {
        Graphics.ClearRandomWriteTargets();
        Setup();
        mat.SetPass(0);

        //名字和shader中的RWBuffer无关
        mat.SetBuffer("Field1", fieldbuf);

        Graphics.SetRandomWriteTarget(targetID, fieldbuf);

        fieldbuf.GetData(fdata);
        text.text = "From shader, the RGB value of rainbow color \n";
        for (int i = 0; i < fdata.Length; i++)
        {
            text.text += i + ":  " + fdata[i] + "\n";
        }



        if(ResetValue)
        {
            fieldbuf.SetData(new float[] { 1f,1f,1f});


        }
    }
}

Shader "UAVTest/VertFrag"
{
	Properties
	{
		_MainTex("_MainTex (RGBA)", 2D) = "white" {}
		_Speed("_Speed",Range(0,0.5)) = 0.5
	}
	SubShader
	{
		Tags{ "RenderType" = "Opaque" }

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 5.0

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;

			float _Speed;

			#ifdef UNITY_COMPILER_HLSL
				RWStructuredBuffer<float> Field : register(u6); //match with C# script "targetID"
			#endif

			v2f vert(appdata v)
			{

				//Field[0] = 1;
				//Field[1] = 1;
				//Field[2] = 1;


				Count[0] = 0;
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				//Rainbow color
				float3 c;
				c.r = frac(sin(_Time.x*_Speed));
				c.g = frac(sin(_Time.z*_Speed));
				c.b = frac(sin(_Time.w*_Speed));

				#ifdef UNITY_COMPILER_HLSL
// 最终结果会是正确的
				if(i.uv.x < Field[1])
				{
					Field[0] = i.vertex.x;
					Field[1] = i.uv.x;
					Field[2] = i.uv.y;
				}
				#endif


				float4 col = tex2D(_MainTex, i.uv);
				col.rgb *= c;
				return col;
			}
			ENDCG
		}
	}
}

shader中的比较并赋值,虽然会有竞争的问题,但通过每帧的计算,缓冲池中存储的最小的uv会达到最终的正确性。

显示结果

1 存储了最小u的值 2存储了u对应v的值
可以看到拖动物体,该物体显示最小u的像素中的u的值随之发生变化。

标签:fieldbuf,MainTex,物体,uv,vertex,Field,Unity,1f
From: https://www.cnblogs.com/dewxin/p/17800576.html

相关文章

  • Unity 创建自定义渲染管线
    可以看官方的https://docs.unity3d.com/Manual/srp-custom-getting-started.html或者这位大佬的https://zhuanlan.zhihu.com/p/378828898......
  • centos7:安装python3.6.8:安装uvicorn、fastapi、pymysql:指定国内的pypi镜像源
    yuminstallpython3python3-develgccmakelibaio-develpip3install-ihttp://mirrors.aliyun.com/pypi/simple--trusted-hostmirrors.aliyun.com"uvicorn[standard]"==0.16.0pymysqlfastapi 关键点:因为centos7的软件仓库中,python3的版本比较低:python3-3.6.8-1......
  • Unity显示一个对象的像素个数
    下图显示了该面片占用的像素个数为147456。因为面片的大小为1,坐标为(0,0.5f,0)。相机为正交视角,OrthoSize为1.面片完全显示且高度为(768/2)^2=384^2=147456。另外,可以推测,pixelshader渲染会在所有对象的vertexshader计算结束后开始。即使面片被遮挡,但如果没做处理依然......
  • Unity学习笔记--入门
    Unity引擎学习入门:Unity中的坐标系:左手坐标系(z轴正方向向里面)x轴:平行屏幕向右正方向y轴:平行屏幕向上正方向Z轴:垂直屏幕向内为正方向【补】openGL是右手坐标系DirectX是左手坐标系窗口:窗口布局Layout:Scene这里我们可以看见所有的场景内容。窗口上的工具栏:有关......
  • Unity进阶开发-FSM有限状态机
    #Unity进阶开发-FSM有限状态机前言我们在进行开发时,到了一定程度上,会遇到数十种状态,继续使用Unity的Animator控制器会出现大量的bool,float类型的变量,而这些错综复杂的变量与Animatator控制器如同迷宫版连线相结合会变得极其的复杂且无法良好维护扩展,出现一个BUG会导致开发过程......
  • Unity进阶提升-2D游戏跳跃手感优化(跳起下落)
    在进行2D游戏开发时,跳跃是不可缺少的一个重要功能。但是我们在Unity开发时Unity本身的物理引擎并不能提供很好的的手感,下落的时候轻飘飘的,这操作起来显然非常不舒服。所以,我们需要自己对跳跃进行优化,以此来获得更好的手感。我们不难发现,在绝大多数2D游戏的跳跃中,下落的速度比上升......
  • UVA1485 Permutation Counting
    传送门description一个长度为\(n\)的排列\(a\),其权值为满足\(a_i>i\)的位置的数量。求权值恰为\(k\)的长度为\(n\)的排列的方案数。\(n,k\leq1000\)solution设\(f_{i,j}\)表示考虑前\(i\)个数,钦定\(j\)个满足\(a_i>i\),这\(j\)个数排列的方案数。有转移......
  • blender模型展uv3.6
    有时候uv贴图直接按U展开效果不理想,不同的模型适合的展开方式也会有一定的差异。以下是几种模型的展开方式,可做参考。在展uv前可以打开uv选区同步,以便更好控制所有网格位置。人物角色面部展开在后面选中中间的那根线一直到发际线标记缝合边。然后A全选U键选择“展开”......
  • 让物体动起来,Unity的几种移动方式
    一、前言在大部分的Unity游戏开发中,移动是极其重要的一部分,移动的手感决定着游戏的成败,一个优秀的移动手感无疑可以给游戏带来非常舒服的体验。而Unity中有多种移动方法,使用Transform,使用刚体Rigidbody,使用CharacterController,使用NavMesh导航系统等等等等。当然,对于新手来说,最常......
  • 如何设置位移贴图模拟物体裂缝?
    1、位移贴图的原理?位移贴图(DisplacementMap)是一种用于增强模型细节的贴图技术,它可以通过改变模型表面的几何形状来实现更加真实的效果。与其他贴图技术不同,位移贴图不仅仅是给模型表面添加纹理和颜色,而是直接改变模型的顶点位置,从而改变模型的形状。位移贴图的原理可以简单地描......