Jiangman (Lobi) Zhao
Project
Unity Shading
Car painting
- Shading in Unity engine.
 
        - Using Substance create a distance map, shading to mimic the shape of a flame.
 
         
        //////////////////// fragment shader snippet ////////////////////
...
float speed = frac(_Time.x * + _lavaSpeed);
float4 wave = tex2D(_lavawaveTex, (i.texcoord.zw + float2(0, speed)) * 2) * 2 - 1;
wave = wave.r * _lavaWave;
float4 gas = tex2D(_lavawaveTex, float2(i.texcoord.z * _gasOffset.x, i.texcoord.w * _gasOffset.y + frac(_Time.y * + _gasOffset.z)));
float4 lava = tex2D(_lavaTex, float2(i.texcoord.zw + wave.xy));
float4 mask = tex2D(_lavaTex, i.texcoord.zw);
lava = (lava.r + gas.g * _gasOffset.w) * _lavaCol * mask.g;
...- Other types of car paint.
 
         
         
         
        - Stylized cloud material.
 
         
        //////////////////// vertex shader snippet ////////////////////
...
// make noise in worldSpace
float speed = frac(_Time.y * _speed);
float3 blend = v.vertex.xyz * _scale;
float4 noiseXY = tex2Dlod(_Noise, float4(blend.xy + speed, 0, 0));
float4 noiseYZ = tex2Dlod(_Noise, float4(blend.yz + speed, 0, 0));
float4 noiseXZ = tex2Dlod(_Noise, float4(blend.xz + speed, 0, 0));
float4 noise = noiseXY;
// lerp
noise = lerp(noise, noiseXZ, o.normal.y);
noise = lerp(noise, noiseYZ, o.normal.x);
o.color = v.color;
noise *= o.color;
//noise plus v.vertex
v.vertex += v.normal * (noise * _range);
o.pos = UnityObjectToClipPos(v.vertex);
...- Liquid wave material.
 
         
        fixed4 frag(v2f i) : SV_Target
{
    // WAVE cubemap
    float speed = frac(_Time.y * _speed);
    float3 flowDir = tex2D(_fmap, float2(i.texcoord.x * _offset.x + speed, i.texcoord.y * _offset.y)) * 2 - 1;
    flowDir *= _strength;
    float offset0 = frac(_Time.w * 0.5 + 0.5);
    float offset1 = frac(_Time.w * 0.5 + 1.0);
    float offsetlerp = abs((0.5 - offset0) / 0.5);
    fixed4 msk = tex2D(_MaskTex, i.texcoord);
    fixed4 refl0 = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl) + float4(flowDir.xy * offset0, 0, 0));
    fixed4 refl1 = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl) + float4(flowDir.xy * offset1, 0, 0));
    fixed4 refl = lerp(refl0, refl1, offsetlerp);
    refl.a *= msk.r * _Alpha * i.color.a;
    return refl;
}Card battle
- In game low cost dynamic shadow
 
         
        Tools Development
- Organize assets and generate USD files. Built with Python.Link
 
         
        - Developed a C++ image processing tool that supports multithreading for efficient performance.Link
 
        - 
Designed and implemented a Python-based Qt tool to export cache files into Unreal Engine, improving workflow efficiency. 
- 
Implemented a Python-based Qt interface for a hair plugin, facilitating seamless integration and user interaction. 
 
         
        - Developed a curve editor supporting linear and cubic Bézier curves using C++ and CMake.
 
        - Created a Qt-based 2D drawing tool using OpenGL and C++.
 
        rigging
Facial rigging
- Base on Unreal MetaHuman, rigging facial mesh in maya, modifying and generating new DNA source.
Dynamic bone
- Set in game hair Dynamic Bone.
 
         
         
        Grooming
- Create by maya tool that made by our TA team. Creating hair card maps base on XGen and modeling FurCard by self developed tool.
 
        - Hair Rendering in Unreal Engine.
 
        - Animal fur test. Baking vertex color on FurCard mesh blend base color fo body model in unreal engine
 
        Modeling
chess Game Online
- Modeling and drawing texture rendered in unity engine
 
         
         
         
         
        substance workflow
- Substance Designer work flow. Quickly create textures using only SmartMaterial.
 
         
         
         
        PhotoScan workflow
- Create textures using PhotoScan workflow.
 
         
         
        Patent
- As main Inventor-shadow in SNS game : CN110517346B
 
        terrain shadow case
- Set a camera as the light position, get a renderTexture
 
         
        - Shading and sampling RT
// project RenderTexture in world position v2f vert(appdata v) { fixed4 tex = tex2D(_MainTex, i.texcoord); fixed spec = tex.a; float2 shadow_uv = mul(_ShadowVPMatrix, i.worldPos).xy * 0.5 + 0.5; fixed atten = tex2D(_CurrentShadowmap, shadow_uv).r; fixed4 shadow_color = lerp(_ShadowCol, fixed4(1, 1, 1, 1), atten); //blend shadow and texture tex = _MainColor * _DirectionalLightColor * shadow_color * tex; half4 normalMap = tex2D(_BumpMap, i.texcoord); half3 normalDir = normalize(UnpackNormal(normalMap)); half3 viewDir = normalize(i.viewDir); half3 lightDir = normalize(i.lightDir); half3 h = normalize(viewDir + lightDir); float r = max(0, dot(h, normalDir)); tex += _SpecularCol * spec * pow(r, 48); return tex; }element shadow case  Cabin Building - Bake 4 directional shadow in solo channel
   Directional Shadow - Shading and sampling RGBA channel shadow, and then dye color to them
fixed4 frag(v2f i) : COLOR { fixed4 tex = tex2D(_MainTex, i.texcoord.xy); //added shadow information fixed4 lm = tex2D(_ShasowTex, i.texcoord.zw); fixed shadowvalue = dot(lm, _ShadowDir); tex = lerp(tex * shadowvalue * _ShadowCol, tex, shadowvalue); tex = lerp(tex, tex * _LightPower, shadowvalue * 1.8); #ifdef _GRADIENT_ON tex *= i.gradient; #endif return tex; }elements batch- Generating UV3 to show shadow channel, and then to deal static batch.
   Player Building   Running Batched about meEducationUniversity of Pennsylvania. USA, PA- 
Computer Graphics and Game Technology Sep 2024 - Oct 2026 
- 
Computer and Information Technology Sep 2023 - Jul 2024 
 SkillsProgramming Skills- C++, C, Assembly, Python, Java, OpenGL, GLSL
 DevTools- Snapdragon Profiler, Unity, Unreal Engine5, Qt creator, cMake, Maya, Substance Designer
 Core Skills- Computer Graphic, Developed and optimized mobile application, Scripting, Shader-Programming
 Contact