首页 > 其他分享 >Blend+ZWrite Off在某些情况下也有问题:半透模型自身遮挡关系渲染错乱

Blend+ZWrite Off在某些情况下也有问题:半透模型自身遮挡关系渲染错乱

时间:2023-03-04 23:46:04浏览次数:34  
标签:Off MainTex 写入 fixed3 半透 ZWrite worldNormal 深度 RenderQueue

左侧是错误的,右侧是我们想要的

 

分析原因

因为关闭了深度写入,所有顶点都会被渲染,在重叠的地方就发生混合(颜色较深的区域)。

 

深度写入打开,会是什么效果?

和上面差不多,只是深色区域稍微变小了点。变小的就是没通过深度测试被丢弃的像素,有些区域视觉上明显是前面挡住后面了还是存在混合是因为内部顶点顺序存在跳跃造成的(就是离相机远的顶点先绘制了)

 

解决方法

深度写入得开启,但深度写入不是渲染一个顶点写入一下,而是先把物体当作一个整体把他所有顶点的深度先写入,然后再渲染颜色。

在shader中的体现就是多一个Pass只写深度,不写出颜色。

Shader "My/Blend/Diffuse_Blend_ZWriteOn" {
    Properties{
        _Color("Color Tint", Color) = (1, 1, 1, 1)
        _MainTex("Main Tex", 2D) = "white" {}
        _AlphaScale("Alpha Scale", Range(0, 1)) = 1
    }
        SubShader{
            Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}

            // 只写深度, 不渲染
            Pass {
                ZWrite On
                ColorMask 0
            }

            Pass {
                Tags { "LightMode" = "ForwardBase" }

                ZWrite On
                Blend SrcAlpha OneMinusSrcAlpha

                CGPROGRAM

                #pragma vertex vert
                #pragma fragment frag

                #include "Lighting.cginc"

                fixed4 _Color;
                sampler2D _MainTex;
                float4 _MainTex_ST;
                fixed _AlphaScale;

                struct a2v {
                    float4 vertex : POSITION;
                    float3 normal : NORMAL;
                    float4 texcoord : TEXCOORD0;
                };

                struct v2f {
                    float4 pos : SV_POSITION;
                    float3 worldNormal : TEXCOORD0;
                    float3 worldPos : TEXCOORD1;
                    float2 uv : TEXCOORD2;
                };

                v2f vert(a2v v) {
                    v2f o;
                    o.pos = UnityObjectToClipPos(v.vertex);

                    o.worldNormal = UnityObjectToWorldNormal(v.normal);

                    o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

                    return o;
                }

                fixed4 frag(v2f i) : SV_Target {
                    fixed3 worldNormal = normalize(i.worldNormal);
                    fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));

                    fixed4 texColor = tex2D(_MainTex, i.uv);

                    fixed3 albedo = texColor.rgb * _Color.rgb;

                    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

                    fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));

                    return fixed4(ambient + diffuse, texColor.a * _AlphaScale);
                }

                ENDCG
            }
        }
        FallBack "Transparent/VertexLit"
}

 

一些备忘

深度测试就是到相机的距离与z-buffer比较,如果小与则保留,否则丢弃。

 

不透明的物体先绘制,深度测试+深度写入。

半透明物体绘制,只有深度测试,所有半透明物体只要在不透明物体前面,全都会被绘制,半透明之间相互叠加。

 

1.RenderQueue 2500以下(不透明物体)

a.RenderQueue 越小越优先 b.RenderQueue 相等,由近到远排序优先,直接绘制近的,远的被遮挡的直接丢弃
2.RenderQueue 2500以上(半透明物体) a.RenderQueue 越小越优先 b.RenderQueue 相等,由远到近排序优先,一层一层绘制,层与层之间会混合    

参考

《shader入门精要》 8.5节

标签:Off,MainTex,写入,fixed3,半透,ZWrite,worldNormal,深度,RenderQueue
From: https://www.cnblogs.com/sailJs/p/17171578.html

相关文章

  • DateTimeOffset vs DateTime
    很多时候在开发过程中DateTimeOffset和DateTime混淆不知道如何用,这里总结一下DateTimeOffset可以反映出相对于UTC的时间偏移量。1、用DateTimeOffset表示local时间var......
  • 每日一练(剑指offer)二进制中1的个数
    描述输入一个整数n,输出该数32位二进制表示中1的个数。其中负数用补码表示。示例输入:10返回值:2说明:十进制中10的32位二进制表示为00000000000000000000000000001010......
  • 携程Java三面面经,已拿 offer!!
    分享一位读者投稿的携程校招Java岗位的面经。下面是正文。个人背景:双非本,机械专业转码。携程在正式面试之前,会有一个性格测试(40分钟)。性格测试之后,大概过一周进行笔试......
  • 收个滴滴Offer:从小伙三面经历,看看需要学点啥?
    说在前面在尼恩的(50+)读者社群中,经常有小伙伴,需要面试大厂。后续结合一些大厂的面试真题,给大家梳理一下学习路径,看看大家需要学点啥?这里也一并把题目以及参考答案,收入咱......
  • 每天一练(剑指offer)剪绳子
    描述给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],...,k[m]。请问k[1]*k[2]*...*k[m]可能的......
  • 剑指 Offer 64. 求 1 + 2 + … + n(java解题)
    目录1.题目2.解题思路3.数据类型功能函数总结4.java代码1.题目求1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C......
  • office图标变白新的处理方法
    https://www.haozhuangji.com/xtjc/133013759.html一般搜索得到的处理方式与上面链接的处理方式差不多,都是通过安装wps或者修改注册表来实现的。 本文是我在无意中发现......
  • 剑指 Offer 55 - II. 平衡二叉树(java解题)
    目录1.题目2.解题思路3.数据类型功能函数总结4.java代码1.题目输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超......
  • 剑指Offer 58-||.左旋转字符串
    题目描述  解法一基本思路:直接移动classSolution{public:stringreverseLeftWords(strings,intn){for(inti=0;i<n;i++){......
  • 转载:pageOffice插件 springboot实现服务器上Word文档在线打开编辑保存
    pageOffice插件springboot实现服务器上Word文档在线打开编辑保存需求:在oa系统上,想实现在线,服务器上doc,docx文档,在web打开,编辑。编辑后,可以再同步保存到服务器端。......