Houdini程序化模型
- 整体思路:先生成一个基础模型,再基于该模型进行cutoff、控制拐角,随后转换为低模,最后uv映射、物体的像素密度、贴图大小
基础模型
- 基础形状采用Box,再使用Point Jitter改变形状,最后添加normal为后续的cutoff做铺垫
- 大致形状如下
基础形状
- 基于point个数使用for loop循环进行cutoff,因为cut后可以看到物体内部,所以需要polyfill
- 重点在于cutoff,核心是随机化
- 大致效果如下
进一步修改模型形状
- 接下来是进一步修改物体形状,resolution对point和point之间进行插值增加新的point,fuse融合重复的point,polybevel沿边缘和拐角生成倒角
- 大致效果如下
生成低模
- 将之前的属性转换为VDB,再转换为polygon,最后使用polyreduce减面
Game Asset
- 对模型进行uv映射,然后控制模型的纹素密度,及纹理贴图大小,最后使用Normal基于face进行平滑
SP烘培石头贴图
- 为了加快产生,可以使用SP来制作烘培贴图,主要思路是使用noise纹理+blur+控制整体颜色+打灯
- 具体思路可以参考这个视频how to make anime rocks
SD制作风格化草贴图
- 最终效果如下
- 整体思路:先制作长草和花的形状,再使用tile sampler添加随机性来覆盖整个面,最后添加颜色
- 基础形状
- 花的形状
- 颜色:颜色也是基于之前创建的形状mask,可以在网上下载一些好康的草笔刷来丰富
- 基础形状
Unity
-
shader的重点在于石头如何和青苔、雪之类的纹理进行混合,这里用到了高度混合,具体参考的这个项目
-
实现
-
管线设定:石头这玩意用不透明的即可
-
法线混合
half3 baseNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_NormalTex, sampler_NormalTex, uv), _NormalScale * 0.5h); half3 topNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_TopNormalTex, sampler_TopNormalTex, topUV), _TopNormalScale * 0.5h); surfaceData.normalTS = WhiteOutBlendNormal(baseNormalTS, topNormalTS);
-
世界空间下物体顶部的映射。这部分是最重要的
half TopMask(half3 baseNormalTSUnNor) { half result = abs(saturate(baseNormalTSUnNor.y) + _TopOffset); result = pow(result, _TopContrast); result *= _TopIntensity; result = saturate(result); return result; } half TopHeight(float3 positionWS) { half result = RemapFloat(positionWS.y, -100, 1, 0, 1); return saturate(result); } half TopWorldMapping(half3 baseNormalTSUnNor, float positionWS) { half result = 0.h; result = TopMask(baseNormalTSUnNor) * TopHeight(positionWS); return result; } // 将normal从切线空间转换至世界空间 psInput.tangentWS = SafeNormalize(psInput.tangentWS); psInput.bitTangentWS = SafeNormalize(psInput.bitTangentWS); psInput.normalWS = SafeNormalize(psInput.normalWS); half3x3 TBN = half3x3(psInput.tangentWS, psInput.bitTangentWS, psInput.normalWS); lightData.normalWS = SafeNormalize(TransformTangentToWorld(surfaceData.normalTS, TBN)); // 计算顶部mask half finalTopMask = TopWorldMapping(lightData.normalWS, lightData.positionWS);
-
计算Albedo:使用finalTopMasklerp
half4 albedo = GetSurfaceAlbedo(_AlbedoTex, sampler_AlbedoTex, uv, _AlbedoTint); half4 topAlbedo = GetSurfaceAlbedo(_TopAlbedoTex, sampler_TopAlbedoTex, topUV, _TopAlbedoTint); surfaceData.albedo = lerp(albedo.rgb, topAlbedo, finalTopMask); surfaceData.opacity = 1.h;
-
计算AO
half4 MOS = SAMPLE_TEXTURE2D(_MetallicR_OcclusionG_SmoothnessA_Tex, sampler_MetallicR_OcclusionG_SmoothnessA_Tex, uv); surfaceData.occlusion = lerp(1.h, MOS.g, _BaseAOIntensity); half baseAO = surfaceData.occlusion; surfaceData.occlusion = lerp(baseAO, lerp(baseAO, 1.h, 0.8h), finalTopMask);
-
计算Smoothness
surfaceData.smoothness = 1 - MOS.b; half baseSmoothness = surfaceData.smoothness + RemapFloat(_BaseSmoothnessOffset, 0.h, 1.h, -1.h, 1.h); half topSmoothness = 1.h - topMOS.b + RemapFloat(_TopSmoothnessOffset, 0.h, 1.h, -1.h, 1.h); surfaceData.smoothness = lerp(baseSmoothness, topSmoothness, finalTopMask);
-
-
效果
Reference
Procedural Stylized Rock - Sidefx Houdini
标签:psInput,sampler,surfaceData,SP,形状,风格化,Unity,result,half From: https://www.cnblogs.com/chenglixue/p/18062998