如何混合3ds Max顶点颜色烘焙光照与模型平铺纹理采样?
顶点颜色光照与平铺纹理的混合实现方案
无论是在3ds Max内部预览/渲染,还是导出到游戏引擎中使用,都可以通过以下方式实现顶点颜色(烘焙光照)与平铺纹理的混合:
一、3ds Max 内部材质设置
如果只是在Max里查看效果或渲染输出,直接用内置材质就能搞定:
- 打开材质编辑器,选一个Standard或Physical材质
- 给漫反射通道加一个**混合(Blend)**贴图
- 把你的平铺纹理拖到混合贴图的「颜色1」通道,按需调整纹理的平铺参数(在纹理坐标里改U/V平铺值)
- 从贴图浏览器里选「顶点颜色(Vertex Color)」贴图,拖到混合贴图的「颜色2」通道
- 把混合模式改成相乘(Multiply)——这是最贴合光照逻辑的混合方式,相当于用顶点颜色的明暗来给纹理叠加光照;如果需要更亮的效果,也可以选「叠加(Overlay)」或「线性减淡(Linear Dodge)」
- 要是顶点颜色的明暗不合适,给顶点颜色贴图加个「输出」调整层,调亮度、对比度就行
二、游戏引擎中的实现
Unity 自定义 Shader
写个简单的Shader就能实现可控的混合,核心是采样纹理和顶点颜色后做相乘混合:
Shader "Custom/VertexColorTiledBlend" { Properties { _MainTex ("平铺纹理", 2D) = "white" {} _Tiling ("平铺次数", Vector) = (2,2,0,0) _BlendWeight ("光照强度权重", Range(0,1)) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float4 vertColor : COLOR; }; sampler2D _MainTex; float4 _MainTex_ST; float2 _Tiling; float _BlendWeight; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); // 应用平铺缩放 o.uv = TRANSFORM_TEX(v.uv, _MainTex) * _Tiling; o.vertColor = v.color; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 texCol = tex2D(_MainTex, i.uv); // 混合:纹理颜色 × 顶点光照颜色,可通过权重控制影响程度 fixed4 finalCol = texCol * lerp(float4(1,1,1,1), i.vertColor, _BlendWeight); return finalCol; } ENDCG } } }
- 用法:把Shader拖给材质,指定平铺纹理,调整
_Tiling控制平铺密度,_BlendWeight控制顶点光照的强弱
Unreal Engine 材质节点实现
不用写代码,拖节点就能完成:
- 新建材质,设置渲染类型为「Opaque」
- 拖入Texture Sample节点,选你的平铺纹理,在节点属性里改「UV Scale」来控制平铺次数
- 拖入Vertex Color节点,获取烘焙的光照颜色
- 用Multiply节点把纹理颜色和顶点颜色连起来,输出到材质的「Base Color」通道
- 要调整光照强度的话,加个Scalar Parameter节点和Vertex Color相乘,再和纹理颜色混合
通用HLSL逻辑(自定义渲染管线)
如果是自己写渲染管线,核心逻辑就是在片元着色器里做纹理采样与顶点颜色的混合:
struct VSInput { float3 pos : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; }; struct PSInput { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float4 vertColor : COLOR; }; cbuffer Constants { float4x4 worldViewProj; float2 tiling; }; Texture2D mainTex; SamplerState mainTexSampler; PSInput VS(VSInput input) { PSInput output; output.pos = mul(worldViewProj, float4(input.pos, 1.0)); output.uv = input.uv * tiling; output.vertColor = input.color; return output; } float4 PS(PSInput input) : SV_TARGET { float4 texCol = mainTex.Sample(mainTexSampler, input.uv); // 基础光照混合:纹理颜色 × 顶点颜色 float4 finalCol = texCol * input.vertColor; // 可选:校正顶点颜色的Gamma,让光照更自然 // finalCol.rgb = texCol.rgb * pow(input.vertColor.rgb, 2.2); return finalCol; }
内容的提问来源于stack exchange,提问作者Luis Rivero
相关产品推荐
相关产品推荐

