【问题标题】:Pixelated lighting shader像素化光照着色器
【发布时间】:2016-09-27 04:09:32
【问题描述】:

我已经编写了一个用于 Unity3D 的 GLSL 着色器和我的像素化 iOS 应用程序。它有两个一个问题:

1) 效果并不总是停留在月球上,而且 2) 灯光看起来没有像素化。

我会稍微解释一下。着色器旨在当月亮在其后面时对前景对象产生照明效果。我有一个通常显示为全黑(如剪影)的精灵,但是当月亮对象足够靠近它时,它会显示纹理的细节,如下所示:

实际的精灵(没有着色器)看起来像这样:

我以这种方式制作效果的原因是我可以拥有一个只有一个纹理的光照贴图。但是,它有两个问题:

1) 当我靠近屏幕边缘时,灯光效果并没有完全跟随月亮。我不确定这是否与我对 TEXCOORD1 变量的错误使用有关。我制作了一个覆盖整个屏幕的精灵,这样你就可以看到它是如何不跟随月亮的。这是我的测试场景中的问题图片效果。有一个带有黑色条纹和 alpha 的全屏精灵,可以始终准确地显示效果的位置。我想摆脱这种不同步,因为它使照明看起来不真实。

2) 产生的光照效果非常锐利——我认为,如果每个像素单独点亮,就像SpriteLamp 那样,看起来会更好。我知道这与着色器中的片段坐标四舍五入有关,但由于我从来不知道着色器中的变量值是什么,我似乎无法让它正常工作。

我可以对距离进行四舍五入,但后来我得到了这个,它服从与月球的距离,但不服从原始精灵中的像素。有像素化,但如果你明白我的意思,我们最终会得到一条跨越应该只有一个像素的奇怪曲线......

我正在寻找的更像是这样的。看看原始纹理的各个像素是如何被点亮的?

这是着色器本身的链接:http://pastebin.com/0zbqrP57。它主要是默认的统一精灵着色器,但在 SampleSpriteTexture 函数的末尾添加了一些代码。

这里是一个统一包的链接,您可以使用它来查看正在运行的着色器。只需在场景播放时尝试移动月亮即可。

https://drive.google.com/open?id=0BxCQjUHiAAQWZGpPZ3R2SExTcXc

我的问题:您对如何解决这些问题或解决方案有什么建议吗?

【问题讨论】:

  • 我了解您的问题,但您没有提出具体问题。您是否想了解为什么会发生不同步?期待有关解决方法的建议?这里的目标到底是什么?请编辑。
  • 嗨,@AlmightyR,感谢您的建议。我期待建议和解决方案。我已经更新了这个问题。目标是实现问题 #2 中的效果(因为它看起来比当前设置更好),并解决不同步问题。
  • 哇,它就像一个魅力。谢谢
  • 哈哈,享受你损坏的着色器吧!修好后再回来。
  • @CaTLard:要实现像素化照明,您应该以较低的分辨率渲染,然后使用最近邻进行上采样。

标签: unity3d glsl shader pixel fragment-shader


【解决方案1】:

变化

OUT.worldSpacePosition = mul(_Object2World, OUT.vertex);

OUT.worldSpacePosition = mul(_Object2World, IN.vertex);

应该修复月球错位。

对于第二个问题,我想出了这个:

aS = floor(aS * 100) / 100;
bS = floor(bS * 100) / 100;
float dist = sqrt((aS * aS) + (bS * bS));
float percentClose = 1 - (dist / _LightStrength);
float rounded = floor(percentClose * 10) / 10;

if (color.r + color.g + color.b > 0) {
    color.r = lerp(0, color.r, rounded);
    color.g = lerp(0, color.g, rounded);
    color.b = lerp(0, color.b, rounded);
}

我认为您可以将 if 语句和 lerps 删除为:

aS = floor(aS * 100) / 100;
bS = floor(bS * 100) / 100;
float dist = sqrt((aS * aS) + (bS * bS));
float percentClose = 1 - (dist / _LightStrength);
float rounded = floor(percentClose * 10) / 10;
color.rgb *= rounded;

但在这种情况下,您应该在您的终端设备上对其进行测试,并检查它是否能提高性能。

【讨论】:

  • 第一个修复很棒!你能解释为什么它不同吗?但是像素化的照明方案并不是我真正想要的。抱歉没有更具体。我已经更新了这个问题。
  • 明确地说,我理解我们如何/为什么要摆脱条件,但为什么 IN.vertex 与 OUT.vertex 不同?那里发生了什么事?你看到我的更新了吗?如果您真的不明白,请告诉我。
  • 我真的不知道为什么不一样。即使您将OUT.vertex = UnityObjectToClipPos(IN.vertex); 更改为OUT.vertex = IN.vertex; 并摆脱UnityPixelSnap(),它也无法正常工作。也许有经验的人可以解释一下。你能再上传一次unitypackage吗?我破坏了月球材料和/或精灵。
猜你喜欢
  • 1970-01-01
  • 2011-08-31
  • 2012-04-04
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
相关资源
最近更新 更多