Unity渲染 3 Combining Textures 学习笔记

Of course, we could use a larger texture. More texels means more details. But there's a limit to a texture's size. And it is kind of wasteful to store a lot of extra data that is only noticeable up close.

Another way to increase the texel density is to tile a texture. Then you can get as small as you want, but you will obviously get a repeating pattern. This might not be noticeable up close, though. After all, when you're standing with your nose touching a wall, you'll only see a very small section of the entire wall.

So we should be able to add details by combining an untiled texture with a tiled texture.

That's right, the compiler removed the unnecessary code for us! Basically, it works its way back from the end result, and discards anything that ends up unused. The compiler detected the duplicate code and optimized it. So the texture is only sampled once. The result is stored in a register and reused. The compiler is smart enough to detect such code duplications, even when you use intermediary variables and such.

When you multiply two textures together, the result will be darker. Unless at least one of the textures is white. That's because each color channel of a texel has a value between 0 and 1. To brighten the original texture, you need values that are greater than 1. Let's say up to 2, which would double the original color.

The idea of adding details was that they improve the material's appearance up close or zoomed in. They're not supposed to be visible far away or zoomed out, because that makes the tiling obvious. So we need a way to fade the details away as the display size of the texture decreases. We can do so by fading the detail texture to gray, as that results in no color change.

Gamma space refers to gamma-corrected colors. Gamma correction is an adjustment of the intensity of light. The simplest approach is to raise the original value to some power, so valuegamma. A gamma of 1 means that there is no change. A gamma of 2 means that the original value is squared.

What is gamma space?

Gamma space refers to gamma-corrected colors. Gamma correction is an adjustment of the intensity of light. The simplest approach is to raise the original value to some power, so valuegamma. A gamma of 1 means that there is no change. A gamma of 2 means that the original value is squared.

This conversion was originally introduced to accommodate the nonlinear nature of CRT display monitors. An added benefit is that it also roughly corresponds to how sensitive our eyes are to different light intensities. We notice differences between dark colors more than differences between bright colors. So it makes sense to dedicate more bits of a digital number to darker values than to lighter ones. Exponentiation allows use to do so, by stretching lower values over a larger range, while squashing higher values.

The most widely used image color format is sRGB. It uses a more complex formula than simple exponentiation, but it stores colors with an average gamma of 1/2.2. This is a reasonable approximation in many cases. To convert this data back to its original color, apply a gamma correction of 2.2.

Encoding with gamma 1/2.2 and decoding with gamma 2.2.

Encoding with gamma 1/2.2 and decoding with gamma 2.2.

Unity assumes that textures and colors are stored as sRGB. When rendering in gamma space, shaders directly access the raw color and texture data. This is what we assumed up to this point.

When rendering in linear space, this is no longer true. The GPU will convert texture samples to linear space. Also, Unity will convert material color properties to linear space as well. The shader then operates with these linear colors. After that, the output of the fragment program will be converted back to gamma space.

One of the advantages of using linear colors is that it enables more realistic lighting calculations. That's because light interactions are linear in real life, not exponential.

Because we double the detail texture sample, a value of ½ results in no change to the main texture. However, the conversion to linear space changes this to something near ½2.2 ≈ 0.22[decode]. Doubling that is roughly 0.44, which is much less that 1. That explains the darkening.

We could solve this error by enabling Bypass sRGB Sampling in the detail texture's import settings. This prevents the conversion from gamma to linear space, so the shader will always access the raw image data. However, the detail texture is an sRGB image, so the result would still be wrong.

The best solution is to realign the detail colors so they're centered around 1 again. We can do that by multiplying by 1 / ½2.2 ≈ 4.59, instead of by 2. But we must only do this when we are rendering in linear space.

Fortunately, UnityCG defines a uniform variable which will contain the correct numbers to multiply with. It is a **float4** which has either 2 or roughly 4.59 in its rgb components, as appropriate. As gamma correction is not applied to the alpha channel, it is always 2.

color *= tex2D(_DetailTex, i.uvDetail) * unity_ColorSpaceDouble;

A limitation of detail textures is that the same details are used for the entire surface. This works fine for a uniform surface, like a slab of marble. However, if your material does not have a uniform appearance, you don't want to use the same details everywhere.

Binary splat map.

After adding it to your project, switch its import type to advanced. Enable Bypass sRGB Sampling and indicate that its mipmaps should be generated In Linear Space. This is required because the texture doesn't represent sRGB colors, but choices. So it should not be converted when rendering in linear space.

We have a functional splat material, but it only supports two textures. Can we support more? We're only using the R channel, so what about we add the R and G channels as well? Then (1,0,0) represents the first texture, (0,1,0) represents the second texture, and (0,0,1) represents a third texture. To get a correct interpolation between those three, we just have to make sure that the RGB channels always add up to 1.

But wait, when we used only one channel, we could support two textures. That's because the weight of the second texture was derived via 1 - R. This same trick works for any number of channels. So it is possible to support yet another texture, via 1 - R - G - B.

转载于:https://my.oschina.net/u/918889/blog/1827244

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值