Unity透明遮罩问题!外表面透明,内表面不透明?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity透明遮罩问题!外表面透明,内表面不透明?相关的知识,希望对你有一定的参考价值。

比如说这样一个桶状的模型,我希望箭头所指的外表面是透明的,可以看透过去看到背景,而看不到内表面和里面的东西。而内表面是不透明的,可以看到内表面和里面的东西。
就像哆啦A梦里面的任意门一样,里面是一个特殊的空间,也只能从桶口进出。

如果从桶下方往上面看,则什么都看不到。

如何实现这样的效果呢?求给思路。

参考技术A 试下这个shader. 双面 记深度的

Shader "Custom/2Side"
Properties
_MainTex ("Base (RGB)", 2D) = "white"

SubShader
Tags "RenderType"="Opaque" "Queue"="Background"
LOD 200
cull back
Blend SrcAlpha OneMinusSrcAlpha
//ZTest Less
ZWrite On
CGPROGRAM
#pragma surface surf Lambert

sampler2D _MainTex;

struct Input
float2 uv_MainTex;
;

void surf (Input IN, inout SurfaceOutput o)
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;

ENDCG
//Tags "RenderType"="Opaque" "Queue"="Transparent"
cull front
Blend SrcAlpha OneMinusSrcAlpha
ZTest LEqual
ZWrite On
CGPROGRAM
#pragma surface surf Lambert

sampler2D _MainTex;

struct Input
float2 uv_MainTex;
;

void surf (Input IN, inout SurfaceOutput o)
half4 c =half4(0,1,0,0); tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = 0;

ENDCG

FallBack "Diffuse"
参考技术B 给它新建一个材质,Shader选择Transparent/Diffuse, 其实就是让它单面显示就可以了!
哦,补充一下!复制一个出来让翻转一下法线,并且给个不透明的材质!追问

弄了Transparent后只达到这个效果,还是不太对啊。能不能加QQ指导一下?

追答

你的这个模型,正面是朝内的,翻转一下!

追问

如何反转啊?跪求。。。。。
我试着让高度取负,然后旋转180,度,可是没变化啊。

参考技术C 楼主这个问题解决了吗?我也遇到类似的问题

PyGame:具有每像素 alpha 的半透明精灵

【中文标题】PyGame:具有每像素 alpha 的半透明精灵【英文标题】:PyGame: translucent sprites with per pixel alpha 【发布时间】:2010-11-25 12:05:13 【问题描述】:

是否可以显示具有可控 alpha 的 PyGame 表面?我想采用具有自己的每像素 alpha 的表面并以可变的半透明度显示它而不影响表面数据并保持透明度不变,即表面上的对象将保持其形状但它们的“内容”或多或少半透明。

换句话说,我想将源图像中的每像素 alpha 与运行时计算的每表面 alpha 结合起来。

【问题讨论】:

【参考方案1】:

Pygame documentation 表示您不能将表面 alpha 与每像素 alpha 结合起来,但如果您使用的是 Pygame 1.8.1 或更高版本,您可以通过使用 special_flags 参数来解决此问题 @987654324 @。

我是这样做的:

# Load an image with per-pixel alpha
s = pygame.image.load('spam.png')
s = s.convert_alpha()

# Simulate s.set_alpha(alpha)
alpha_img = pygame.Surface(s.get_rect().size, pygame.SRCALPHA)
alpha_img.fill((255, 255, 255, alpha))
s.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)

其工作方式是创建与第一个相同大小的第二个表面,并使用RGBA multiplication 将其粘贴到第一个表面。通过使第二张图像的 R、G 和 B 分量等于 255,乘法不会影响图像的颜色,但会按给定的 Alpha 因子缩放 Alpha 通道。

请注意,上述方法与调用set_alpha() 的不同之处在于,set_alpha() 可以通过调用set_alpha(255) 来反转。如果使用上面的方法,会导致每个像素的像素 alpha 值发生变化,所以这个过程不能直接颠倒。

【讨论】:

self 应该是s【参考方案2】:

是的,你可以。 documentation of the Surface class 解释了如何做到这一点。它只归结为两种情况: 在 Surface 对象的创建过程中设置一个标志:

s = pygame.Surface((16, 16), flags=pygame.SRCALPHA)

或者你给一个还没有 alpha 通道的表面:

s = pygame.image.load('spam.png')
s.convert_alpha()

pygame.image 模块的文档说,对于具有透明度的 PNG,应用 convert_alpha 是必要的。

如果您愿意,您可以使用模块 draw 和 surfarray 修改每个像素的 alpha 值。指定颜色时,使用四个整数的元组:(红色,绿色,蓝色,alpha)。 alpha 参数范围从 0(完全透明)到 255(完全不透明)。

import pygame
pygame.init()
screen = pygame.display.set_mode((320, 200))
screen.fill((200, 100, 200))
s = pygame.Surface((64, 64), flags=pygame.SRCALPHA)
for i in range(64):
    pygame.draw.line(s, (0, 0, 0, i*4), (0, i), (64, i))

screen.blit(s, (50, 30))
pygame.display.flip()

【讨论】:

+1 示例总是受欢迎的。特别是当它工作时,并显示需要什么:D 嗯,这解释了如何显示具有每像素 alpha 的表面(例如,来自 PNG 文件)。我已经意识到这一点。但我正在寻找一种以代码可控的半透明显示这些表面的方法。例如使这些精灵从完全透明变为原始的每像素透明度。类似于 Surface.set_alpha() 但没有禁用表面中已经存在的每像素透明度。将每像素透明度与整体透明度值混合。【参考方案3】:

在检查了 PyGame 和 SDL 文档后,我得出结论,我提出的问题在 PyGame 中使用标准函数是不可行的。

SDL 文档指出,每像素 alpha 和每表面 alpha 不能与前者结合使用,前者总是优先。实现我想要的效果的唯一方法是编写代码,在 blit 之前更新源表面的每像素 alpha 值。

【讨论】:

【参考方案4】:

如果您的输入图像启用了每像素 alpha,但仅使用一位来实现透明度(例如,具有透明背景或文本的 .png 精灵),您可以将透明背景转换为 colorkey-alpha 背景很容易,然后使用 set_alpha() 将整个纹理混合到任何东西上。

这是我用来淡化文本效果和其他东西的快速而肮脏的辅助函数:

def convert_to_colorkey_alpha(surf, colorkey=pygame.color.Color("magenta")):
    newsurf = surface.Surface(surf.get_size())
    newsurf.fill(colorkey)
    newsurf.blit(surf, (0, 0))
    newsurf.set_colorkey(colorkey)
    return newsurf

其他几个可能解决此问题的技巧可能是:

在 blitting 之前进行逐像素编辑以修改 Alpha 通道 使用 special_flags=BLEND_RGBA_MULT 或 BLEND_RGBA_SUB 将白色或黑色填充的半透明表面粘贴到源表面上。

【讨论】:

以上是关于Unity透明遮罩问题!外表面透明,内表面不透明?的主要内容,如果未能解决你的问题,请参考以下文章

Unity HDRP之次表面散射

Unity Shaders学习笔记之表面着色器

PyGame:具有每像素 alpha 的半透明精灵

如何在pygame中制作具有透明背景的表面

在pygame中的透明表面上渲染抗锯齿文本

如何在 Pygame 中将具有一定透明度的 PNG 粘贴到表面上? [复制]