高度纹理用于什么?

huangapple go评论66阅读模式
英文:

What is height texture used for?

问题

从资产商店下载了纹理资产。但是有一个名为XX_height.png的纹理,如下所示。

我明白这大约包含高度信息,但我认为这些信息实际上不会在顶点着色器中调整高度,我想知道它在片段着色器中如何使用。

谢谢。

高度纹理用于什么?

英文:

Downloaded texture asset from asset store. But there's a texture called XX_height.png as shown below.

I understand that there is approximately height information, but I don't think this information will actually adjust the height in the vertex shader, and I'm wondering how it's used in the fragment shader.

Thank you.

高度纹理用于什么?

答案1

得分: 2

以下是翻译好的内容:

"基于视图,它对UV坐标进行了扭曲,以给你深度的错觉。

描绘(抱歉,由于压缩伪像):

高度纹理用于什么?

你在这里看到的是一个四边形网格的动画GIF旋转。阿尔贝多纹理是Godot图标,高度纹理是棋盘格。还有一些压缩伪像

请注意,高度纹理中黑色部分似乎比白色部分更远(它们有额外的视差)。你可以通过改变heightmap_scale来控制它们看起来有多远。当然,这是在不移动顶点的情况下完成的。

由于Godot允许我们将材质转换为着色器材质,我们可以查看获取此效果的代码(已删除未使用的uniform和额外的空格):

// 注意:着色器自动从Godot Engine 4.1.dev1的StandardMaterial3D转换而来。

shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
uniform float roughness : hint_range(0, 1);
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap, repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap, repeat_enable;
uniform float specular;
uniform float metallic;
uniform sampler2D texture_heightmap : hint_default_black, filter_linear_mipmap, repeat_enable;
uniform float heightmap_scale;
uniform vec2 heightmap_flip;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;

void vertex() {
	UV = UV * uv1_scale.xy + uv1_offset.xy;
}

void fragment() {
	vec2 base_uv = UV;
	{
		vec3 view_dir = normalize(normalize(-VERTEX) * mat3(TANGENT * heightmap_flip.x, -BINORMAL * heightmap_flip.y, NORMAL));
		float depth = 1.0 - texture(texture_heightmap, base_uv).r;
		vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale * 0.01;
		base_uv = ofs;
	}
	vec4 albedo_tex = texture(texture_albedo, base_uv);
	ALBEDO = albedo.rgb * albedo_tex.rgb;
	float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel);
	METALLIC = metallic_tex * metallic;
	vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0);
	float roughness_tex = dot(texture(texture_roughness, base_uv), roughness_texture_channel);
	ROUGHNESS = roughness_tex * roughness;
	SPECULAR = specular;
}

关于heightmap_enabled的文档说:

> 如果为true,则启用高度映射(也称为“视差映射”或“深度映射”)。还请参阅[normal_enabled][2]。高度映射是GPU上的一项要求很高的功能,因此只应在对视觉效果产生显著影响的材质上使用。

如果我们还启用[heightmap_deep_parallax][3],Godot将填充高度的悬崖... 我不知道如何更好地表达

再次描绘(对于压缩伪像,我再次表示抱歉):

![enter image description here][4]

这是代码:

// 注意:着色器自动从Godot Engine 4.1.dev1的StandardMaterial3D转换而来。

shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
uniform float roughness : hint_range(0, 1);
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap, repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap, repeat_enable;
uniform float specular;
uniform float metallic;
uniform sampler2D texture_heightmap : hint_default_black, filter_linear_mipmap, repeat_enable;
uniform float heightmap_scale;
uniform int heightmap_min_layers;
uniform int heightmap_max_layers;
uniform vec2 heightmap_flip;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;

void vertex() {
	UV = UV * uv1_scale.xy + uv1_offset.xy;
}

void fragment() {
	vec2 base_uv = UV;
	{
		vec3 view_dir = normalize(normalize(-VERTEX) * mat3(TANGENT * heightmap_flip.x, -BINORMAL * heightmap_flip.y, NORMAL));
		float num_layers = mix(float(heightmap_max_layers), float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));
		float layer_depth = 1.0 / num_layers;
		vec2 P = view_dir.xy * heightmap_scale * 0.01;
		vec2 delta = P / num_layers;
		vec2 ofs = base_uv;
		float depth = 1.0 - texture(texture_heightmap, ofs).r;
		float current_depth = 0.0;
		while (current_depth < depth) {
			ofs -= delta;
			depth = 1.0 - texture(texture_heightmap, ofs).r;
			current_depth += layer_depth;
		}
		vec2 prev_ofs = ofs + delta;
		float after_depth = depth - current_depth;
		float before_depth = (1.0 - texture(texture_heightmap, prev_ofs).r) - current_depth + layer_depth;
		float weight = after_depth / (after_depth - before_depth);
		ofs = mix(ofs, prev_ofs, weight);
		base_uv = ofs;
	}
	vec4 albedo_tex = texture(texture_albedo, base_uv);
	ALBEDO = albedo.rgb * albedo_tex.rgb;
	float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel);
	METALLIC = metallic_tex * metallic;
	vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.

<details>
<summary>英文:</summary>

It warps the uv coordinates based on the view to give you an illusion of depth.

Depicted (sorry by the compression artifacts):

[![enter image description here][1]][1]

What you see here is an animated GIF of a quad mesh rotating. The Albedo texture is the Godot icon, and the height texture is a checkerboard. *Plus compression artifacts.*

Observe that the parts of the height texture that are black appear to be further back (they have extra parallax) than the parts of the height texture that are white. *You can control how back they appear to be by changing the `heightmap_scale`*. This is, of course, accomplished without moving the vertex.

Since Godot allows us to convert the material to a shader material, we can see the code to get this effect (I have removed not used uniforms and extra spacing):

// NOTE: Shader automatically converted from Godot Engine 4.1.dev1's StandardMaterial3D.

shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
uniform float roughness : hint_range(0,1);
uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
uniform float specular;
uniform float metallic;
uniform sampler2D texture_heightmap : hint_default_black,filter_linear_mipmap,repeat_enable;
uniform float heightmap_scale;
uniform vec2 heightmap_flip;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;

void vertex() {
UV=UV*uv1_scale.xy+uv1_offset.xy;
}

void fragment() {
vec2 base_uv = UV;
{
vec3 view_dir = normalize(normalize(-VERTEX)mat3(TANGENTheightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));
float depth = 1.0 - texture(texture_heightmap, base_uv).r;
vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale * 0.01;
base_uv=ofs;
}
vec4 albedo_tex = texture(texture_albedo,base_uv);
ALBEDO = albedo.rgb * albedo_tex.rgb;
float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
METALLIC = metallic_tex * metallic;
vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
ROUGHNESS = roughness_tex * roughness;
SPECULAR = specular;
}


The documentation on `heightmap_enabled` says:
&gt; If `true`, height mapping is enabled (also called &quot;parallax mapping&quot; or &quot;depth mapping&quot;). See also [`normal_enabled`][2]. Height mapping is a demanding feature on the GPU, so it should only be used on materials where it makes a significant visual difference.
---
If we also enable [`heightmap_deep_parallax`][3] Godot will fill the cliffs of the height... *I don&#39;t know how better to express it*.
Depicted (again, sorry for compression artifacts):
[![enter image description here][4]][4]
This is the code:

// NOTE: Shader automatically converted from Godot Engine 4.1.dev1's StandardMaterial3D.

shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
uniform float roughness : hint_range(0,1);
uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
uniform float specular;
uniform float metallic;
uniform sampler2D texture_heightmap : hint_default_black,filter_linear_mipmap,repeat_enable;
uniform float heightmap_scale;
uniform int heightmap_min_layers;
uniform int heightmap_max_layers;
uniform vec2 heightmap_flip;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;

void vertex() {
UV=UV*uv1_scale.xy+uv1_offset.xy;
}

void fragment() {
vec2 base_uv = UV;
{
vec3 view_dir = normalize(normalize(-VERTEX)mat3(TANGENTheightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));
float num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));
float layer_depth = 1.0 / num_layers;
vec2 P = view_dir.xy * heightmap_scale * 0.01;
vec2 delta = P / num_layers;
vec2 ofs = base_uv;
float depth = 1.0 - texture(texture_heightmap, ofs).r;
float current_depth = 0.0;
while(current_depth < depth) {
ofs -= delta;
depth = 1.0 - texture(texture_heightmap, ofs).r;
current_depth += layer_depth;
}
vec2 prev_ofs = ofs + delta;
float after_depth = depth - current_depth;
float before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;
float weight = after_depth / (after_depth - before_depth);
ofs = mix(ofs,prev_ofs,weight);
base_uv=ofs;
}
vec4 albedo_tex = texture(texture_albedo,base_uv);
ALBEDO = albedo.rgb * albedo_tex.rgb;
float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
METALLIC = metallic_tex * metallic;
vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
ROUGHNESS = roughness_tex * roughness;
SPECULAR = specular;
}


---
This effect does not interact with the lighting model. But you can combine it with normal and occlusion textures.
---
See also:
- [Normal mapping](https://en.wikipedia.org/wiki/Normal_mapping).
- [Bump mapping](https://en.wikipedia.org/wiki/Bump_mapping).
- [Parallax mapping](https://en.wikipedia.org/wiki/Parallax_mapping).
[1]: https://i.stack.imgur.com/ZO4OC.gif
[2]: https://docs.godotengine.org/en/stable/classes/class_basematerial3d.html#class-basematerial3d-property-normal-enabled
[3]: https://docs.godotengine.org/en/stable/classes/class_basematerial3d.html#class-basematerial3d-property-heightmap-enabled
[4]: https://i.stack.imgur.com/6HY90.gif
</details>

huangapple
  • 本文由 发表于 2023年5月18日 11:38:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定