Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize Cartoon Sketch rendering with Unity Shader

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the relevant knowledge of "how to achieve cartoon sketch style rendering with Unity Shader". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Cartoon style rendering

Cartoon style rendered game screen usually has a clear color demarcation of the object, with black line strokes. There are many methods to realize cartoon rendering, and the shading technology based on hue is one of them. In the process of realization, the diffuse hue is controlled by using the diffuse reflection coefficient to sample the one-dimensional texture. Previously, a cartoon-style rendering was achieved by using a gradient texture to control the diffuse color. The highlight effect of the cartoon style is often a well-defined color block, while the edge of the object is usually stroked. In this section, you will do the strokes in a model-based way, rather than the previous on-screen post-processing.

Contour rendering

The rendering of contour lines is a widely used effect in real-time rendering. At present, there are five commonly used methods to draw the outline of the model:

Contour rendering based on viewing Angle and Surface normal

The contour information is obtained by using the point multiplication results of the viewing angle direction and the surface normal. Simple and fast, a Pass can get the result, but it has great limitations and can not get a satisfactory stroke effect.

Front and back rendering

Use two Pass, one to render the back and the other to render the front patch. Fast and effective, suitable for most models with smooth surfaces.

Contours based on image processing

This is the approach used in previous screen post-processing and the use of depth textures. It can be used for any model, but contours with little change in depth and normals cannot be detected, such as a thin plane close to each other.

Contour Detection based on Contour Edge

Through the calculation to get the accurate outline edge, and then directly render, render a unique style. To detect whether an edge is a contour edge, you only need to check whether the triangular patch adjacent to the edge satisfies:

(N0roomV > 0)! = (N1roomV > 0)

N0 and N1 are the normal directions of adjacent patches, respectively. Because the contour is extracted in a single frame, the jump between frames will occur when the number of frames is low.

The last one is the above comprehensive rendering method.

First of all, find the accurate contour edges, render the model and contours to the texture, then identify the contours by graphic processing, and render stylized in the image space.

The following uses the front and back rendering method to outline the contour lines. In the previous front and back rendering, the vertices were directly offset in the crop space to the normal direction under the crop space. Here, the observation space is used to offset the vertices in the observation space, the difference is that the observation space is a linear space, although the previous effect basically meets the requirements, but the results of processing in the linear space will be more consistent. In order to prevent the back of some concave models from obscuring the front after using the front, the z component of the vertex normal is fixed, and then the normals are normalized and expanded. This makes the back flatter after expansion, reducing the possibility of obscuring the front patch. That is:

ViewNormal.z=-0.5;viewNormal=normalize (viewNormalize); viewPos=viewPos+viewNormal*_Outline

Cartoon-style highlights are usually represented by clearly delimited blocks of color on the model. In order to achieve this effect, the previous specular calculation model is no longer used. In the previous Blinn-Phong, the normal direction point was multiplied by half of the sum of the viewing angle and lighting direction, and then the coefficient was obtained by exponential operation with the _ Gloss parameter:

Float spec=pow (max (0ddot (normal,halfDir)), _ Gloss)

For the cartoon-style specular lighting model, it is also necessary to calculate the dot multiplication results of normal and halfDir, and then compare them directly with a threshold, which returns 1 when it is greater than the threshold and 0 if it is less than the threshold to form a clearly delimited color block boundary:

Float spec=dot (normal,halfDir); spec=step (threshold,spec)

The step function implementation of CG and the threshold comparison return the result of 0 quotient 1, the first is the reference value, and the second parameter is greater than the first parameter, return 1, otherwise return 0.

This direct zero zero 1 value will form a sawtooth in the edge area of the highlight, due to a sudden change from 0meme1. In order to get the effect that the specular edge is called smoothing, smoothing can be done in a small area at the boundary.

Float spec=dot (normal,halfDir); spec=lerp (0rect 1pm smoothstep (- wrec wwmcc threshold))

Using the smoothstep function of CG, w is a small value. When spec-threshold is less than-w, 0 is returned, and when it is greater than w, 1 is returned, otherwise interpolation is performed between 0 and 1. The effect is to make a smooth transition from 0 to 1 in the [- w] range, the specular edge, to prevent aliasing. The value of w can be obtained by using the fwidth function of CG to obtain the approximate derivative (the degree of variation between pixels) between neighborhood pixels.

Code example:

Shader "Custom/Chapter14_ToonShading" {Properties {_ MainTex ("MainTex", 2D) = "white" {} _ Color ("Color", Color) = (1je 1jue 1jue 1) _ RampTex ("Ramp", 2D) = "white" {} _ Outline ("Outline", Range (0Pol 1)) = 0.1OutlineColor ("OutlineColor", Color) = (0pc0Pol 1) _ Specular ("SpecularColor", Color) = (1JI) 1Pass 1) _ SpecularScale ("SpecularScale", Range (0min0.1)) = 0.01} SubShader {Pass {NAME "OUTLINE" Cull Front CGPROGRAM # pragma vertex vert # pragma fragment frag # include "UnityCG.cginc" fixed _ Outline Fixed4 _ OutlineColor; struct a2v {float4 vertex:POSITION; float3 normal:NORMAL;}; struct v2f {float4 pos:SV_POSITION;} V2f vert (a2v) {v2fo; float4 pos=mul (UNITY_MATRIX_MV,v.vertex); float3 normal=mul ((float3x3) UNITY_MATRIX_IT_MV,v.normal); normal.z=-0.5; pos=pos+float4 (normalize (normal), 0) * _ Outline O.pos=mul (UNITY_MATRIX_P,pos); return o;} fixed4 frag (V2f I): SV_Target {return fixed4 (_ OutlineColor.rgb,1) } ENDCG} Pass {Tags {"LightMode" = "ForwardBase"} Cull Back CGPROGRAM # pragma vertex vert # pragma fragment frag # pragma multi_compile_fwdbase # include "Lighting.cginc" # include "UnityCG.cginc" # include "AutoLight.cginc" sampler2D _ MainTex Float4 _ MainTex_ST; fixed4 _ Color; sampler2D _ RampTex; fixed4 _ Specular; fixed _ SpecularScale; struct a2v {float4 vertex:POSITION; float3 normal:NORMAL; float2 texcoord:TEXCOORD0 }; struct v2f {float4 pos:SV_POSITION; float2 uv:TEXCOORD0; float3 worldNormal:TEXCOORD1; float3 worldPos:TEXCOORD2; SHADOW_COORDS (3)} V2f vert (a2v) {v2fo; o.pos=UnityObjectToClipPos (v.vertex); o.uv=TRANSFORM_TEX (v.texcoordordmingling MainTex); o.worldNormal=mul (v.normal, (float3x3) unity_WorldToObject); o.worldPos=mul (unity_ObjectToWorld,v.vertex) .xyz TRANSFER_SHADOW (o); return o;} fixed4 frag (v2f I): SV_Target {fixed3 worldNormal=normalize (i.worldNormal); fixed3 worldLightDir=normalize (UnityWorldSpaceLightDir (i.worldPos)); fixed3 worldViewDir=normalize (UnityWorldSpaceViewDir (i.worldPos)) Fixed3 worldHalf=normalize (worldLightDir+worldViewDir); fixed4 c=tex2D (_ MainTex,i.uv); fixed3 albedo=c.rgb*_Color.rgb; fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo; UNITY_LIGHT_ATTENUATION (atten,i,i.worldPos) Fixed diff=dot (worldNormal,worldLightDir); diff= (diff*0.5+0.5) * atten; fixed3 diffuse=_LightColor0.rgb*albedo*tex2D (_ RampTex,float2 (diff,diff)) .RGB; fixed spec=dot (worldNormal,worldHalf); fixed w=fwidth (spec) * 2.0 Fixed3 specular=_Specular.rgb*lerp * step (0.0001graded speculative SpecularScale); / / the last added step (0.0001graded specular SpecularScale) is used to control the specular effect return fixed4 (ambient+diffuse+specular,1.0) when the Specular is zero. } ENDCG}} FallBack "Diffuse" / / the callback here needs to be careful to include a special Pass that can handle shadows.

The effect of an example:

Sketch style rendering

Sketch style rendering is also popular in non-realistic rendering. At present, real-time sketch style rendering is realized by using sketch textures generated in advance.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report