3.8的3d描边shader怎么搞

参照了一个教程搞描边,发现3.8的v_normal搜不到啊,这一堆include 有点懵逼。怎么搞?

到这一步卡壳了

2d还能看懂,3d的有点懵逼

看完 Surface Shader 相关文档,你就会写了。表面着色器(Surface Shader) | Cocos Creator

还是不太懂 :rofl:,有没有应急教程的,原理代码啥的我后面再花时间补上

简单粗暴两个模型,一个模型放大一点,渲染背面,一个正常模型,渲染正面

结点比较多,有好多小结点,需要选中小结点描边。选中外面的话是多个集合小结点组成的大描边

单个物体描边好高,多个物体集合描轮廓需要后处理了

2d的要好搞一点,3d的看不懂。原理很简单就是不知道入口在哪里写

多个的我打算搞个spriteRender了

3d 的片元着色器入口时这里么,不对劲

// Copyright © 2017-2020 Xiamen Yaji Software Co., Ltd.

CCEffect %{

techniques:

  • name: opaque

    passes:

    • vert: unlit-vs:vert

      frag: unlit-fs:frag

      properties: &props

      mainTexture: { value: grey }

      tilingOffset: { value: [1, 1, 0, 0] }

      mainColor: { value: [1, 1, 1, 1], linear: true, editor: { type: color } }

      colorScale: { value: [1, 1, 1], target: colorScaleAndCutoff.xyz }

      alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } }

      color: { target: mainColor, linear: true, editor: { visible: false } } # backward compability

      use_rimLight: {value: 0.0}

      rimColor: {value: [0, 1, 0, 1], linear: true, editor: {type: color }}

      migrations: &migs

      properties:

      mainColor:    { formerlySerializedAs: color }
      
    • &outlinepass

      vert: out-line-vs:vert

      frag: out-line-fs:frag

      properties: *props

      migrations: *migs

      properties: &propss

      mainTexture:    { value: grey }
      
      tilingOffset:   { value: [1, 1, 0, 0] }
      
      mainColor:      { value: [1, 1, 1, 1], linear: true, editor: { type: color } }
      
      colorScale:     { value: [1, 1, 1], target: colorScaleAndCutoff.xyz }
      
      alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } }
      
      color:          { target: mainColor, linear: true, editor: { visible: false } } # backward compability
      
      rimColor:       {value: [0, 1, 0, 1], linear: true, editor: {type: color }}
      
      open_outLine:   {value: 0.0}
      
    • &planar-shadow

      vert: planar-shadow-vs:vert

      frag: planar-shadow-fs:frag

      phase: planar-shadow

      propertyIndex: 0

      depthStencilState:

      depthTest: true

      depthWrite: false

      stencilTestFront: true

      stencilFuncFront: not_equal

      stencilPassOpFront: replace

      stencilRef: 0x80 # only use the leftmost bit

      stencilReadMask: 0x80

      stencilWriteMask: 0x80

      blendState:

      targets:

      • blend: true

        blendSrc: src_alpha

        blendDst: one_minus_src_alpha

        blendDstAlpha: one_minus_src_alpha

    • &deferred-forward

      vert: unlit-vs:vert

      frag: unlit-fs:frag

      phase: deferred-forward

      propertyIndex: 0

  • name: transparent

    passes:

    • vert: unlit-vs:vert

      frag: unlit-fs:frag

      depthStencilState: &d1

      depthTest: true

      depthWrite: false

      blendState: &b1

      targets:

      • blend: true

        blendSrc: src_alpha

        blendDst: one_minus_src_alpha

        blendDstAlpha: one_minus_src_alpha

      properties: *props

      migrations: *migs

    • *planar-shadow

    • &deferred-forward-transparent

      vert: unlit-vs:vert

      frag: unlit-fs:frag

      phase: deferred-forward

      propertyIndex: 0

      migrations: *migs

      depthStencilState: *d1

      blendState: *b1

  • name: add

    passes:

    • vert: unlit-vs:vert

      frag: unlit-fs:frag

      rasterizerState: &r1 { cullMode: none }

      depthStencilState: *d1

      blendState: &b2

      targets:

      • blend: true

        blendSrc: src_alpha

        blendDst: one

        blendSrcAlpha: src_alpha

        blendDstAlpha: one

      properties: *props

      migrations: *migs

    • &deferred-forward-add

      vert: unlit-vs:vert

      frag: unlit-fs:frag

      phase: deferred-forward

      rasterizerState: *r1

      depthStencilState: *d1

      blendState: *b2

      propertyIndex: 0

      migrations: *migs

  • name: alpha-blend

    passes:

    • vert: unlit-vs:vert

      frag: unlit-fs:frag

      rasterizerState: *r1

      depthStencilState: *d1

      blendState: &b3

      targets:

      • blend: true

        blendSrc: src_alpha

        blendDst: one_minus_src_alpha

        blendSrcAlpha: src_alpha

        blendDstAlpha: one_minus_src_alpha

      properties: *props

      migrations: *migs

    • &deferred-forward-alpha-blend

      vert: unlit-vs:vert

      frag: unlit-fs:frag

      phase: deferred-forward

      rasterizerState: *r1

      depthStencilState: *d1

      blendState: *b3

      propertyIndex: 0

      migrations: *migs

}%

CCProgram unlit-vs %{

precision highp float;

#include <legacy/input>

#include <builtin/uniforms/cc-global>

#include <legacy/decode-base>

#include <legacy/local-batch>

#include <legacy/input>

#include <legacy/fog-vs>

out vec3 v_position;

out vec3 v_normal;

#if USE_VERTEX_COLOR

in lowp vec4 a_color;

out lowp vec4 v_color;

#endif

#if USE_TEXTURE

out vec2 v_uv;

uniform TexCoords {

  vec4 tilingOffset;

};

#endif

vec4 vert () {

vec4 position;

CCVertInput(position);

mat4 matWorld, matworldIT;

CCGetWorldMatrixFull(matWorld, matworldIT);

#if USE_TEXTURE

  v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;

  #if SAMPLE_FROM_RT

    CC_HANDLE_RT_SAMPLE_FLIP(v_uv);

  #endif

#endif

#if USE_VERTEX_COLOR

  v_color = a_color;

#endif

CC_TRANSFER_FOG(matWorld * position);

v_position = (matWorld * position).xyz;

v_normal = normalize((matworldIT * vec4(a_normal, 0.0)).xyz);

return cc_matProj * (cc_matView * matWorld) * position;

}

}%

CCProgram unlit-fs %{

precision highp float;

// #include <legacy/output-standard>

#include <legacy/output>

#include <legacy/fog-fs>

in vec3 v_position;

in vec3 v_normal;

#if USE_ALPHA_TEST

#pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b])

#endif

#if USE_TEXTURE

in vec2 v_uv;

uniform sampler2D mainTexture;

#endif

uniform Constant {

vec4 mainColor;

vec4 colorScaleAndCutoff;

vec4 rimColor;

float use_rimLight;

};

#if USE_VERTEX_COLOR

in lowp vec4 v_color;

#endif

vec4 frag () {

vec4 o = mainColor;

o.rgb *= colorScaleAndCutoff.xyz;

#if USE_VERTEX_COLOR

  o.rgb *= SRGBToLinear(v_color.rgb);//use linear

  o.a *= v_color.a;

#endif

#if USE_TEXTURE

  vec4 texColor = texture(mainTexture, v_uv);

  texColor.rgb = SRGBToLinear(texColor.rgb);

  o *= texColor;

#endif

#if USE_ALPHA_TEST

  if (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;

#endif

#if USE_OUTLINE

  if(use_rimLight >= 1.0){

    vec4 colRim = rimColor;

    vec3 viewDir = normalize(cc_cameraPos.xyz - v_position);

    float fRim = 1.0 - abs(dot(normalize(v_normal), viewDir));

    fRim = pow(fRim, 3.0);

    o = mix(o, colRim, fRim);

  }

#endif

// o = o + colRim * fRim;

// if(fRim > 0.85){

//   o = colRim;

// }

CC_APPLY_FOG(o);

return CCFragOutput(o);

}

}%

CCProgram out-line-vs %{

precision highp float;

#include <legacy/input>

#include <builtin/uniforms/cc-global>

#include <legacy/decode-base>

#include <legacy/local-batch>

#include <legacy/input>

#include <legacy/fog-vs>

out vec3 v_position;

out vec3 v_normal;

#if USE_VERTEX_COLOR

in lowp vec4 a_color;

out lowp vec4 v_color;

#endif

#if USE_TEXTURE

out vec2 v_uv;

uniform TexCoords {

  vec4 tilingOffset;

};

#endif

uniform ConstantPass2 {

vec4 mainColor;

vec4 colorScaleAndCutoff;

vec4 rimColor;

float open_outLine;

};

// uniform float open_outLine;

vec4 vert () {

vec4 position;

CCVertInput(position);

mat4 matWorld, matworldIT;

CCGetWorldMatrixFull(matWorld, matworldIT);

#if USE_TEXTURE

  v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;

  #if SAMPLE_FROM_RT

    CC_HANDLE_RT_SAMPLE_FLIP(v_uv);

  #endif

#endif

#if USE_VERTEX_COLOR

  v_color = a_color;

#endif

CC_TRANSFER_FOG(matWorld * position);

if(open_outLine >= 1.0){

  v_position = (matWorld * position).xyz;

  v_normal = normalize((matworldIT * vec4(a_normal, 0.0)).xyz);

  position += vec4(a_normal, 0.0) * 0.0025;

}

return cc_matProj * (cc_matView * matWorld) * position;

}

}%

CCProgram out-line-fs %{

precision highp float;

// #include <legacy/output-standard>

#include <legacy/output>

#include <legacy/fog-fs>

in vec3 v_position;

in vec3 v_normal;

#if USE_ALPHA_TEST

#pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b])

#endif

#if USE_TEXTURE

in vec2 v_uv;

uniform sampler2D mainTexture;

#endif

// uniform vec4 rimColor;

uniform ConstantPass2 {

vec4 mainColor;

vec4 colorScaleAndCutoff;

vec4 rimColor;

float open_outLine;

};

#if USE_VERTEX_COLOR

in lowp vec4 v_color;

#endif

vec4 frag () {

vec4 o = mainColor;

o.rgb *= colorScaleAndCutoff.xyz;

#if USE_VERTEX_COLOR

  o.rgb *= SRGBToLinear(v_color.rgb);//use linear

  o.a *= v_color.a;

#endif

#if USE_TEXTURE

  vec4 texColor = texture(mainTexture, v_uv);

  texColor.rgb = SRGBToLinear(texColor.rgb);

  o *= texColor;

#endif

#if USE_ALPHA_TEST

  if (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;

#endif

#if USE_OUTLINE

  // if(use_rimLight >= 1.0){

  //   vec4 colRim = rimColor;

  //   vec3 viewDir = normalize(cc_cameraPos.xyz - v_position);

  //   float fRim = 1.0 - abs(dot(normalize(v_normal), viewDir));

  //   fRim = pow(fRim, 3.0);

  //   o = mix(o, colRim, fRim);

  // }

#endif

// o = o + colRim * fRim;

// if(fRim > 0.85){

//   o = colRim;

// }

o = rimColor;

CC_APPLY_FOG(o);

return CCFragOutput(o);

}

}%

CCProgram planar-shadow-vs %{

precision highp float;

#include <legacy/input>

#include <builtin/uniforms/cc-global>

#include <legacy/decode-base>

#include <legacy/local-batch>

#include <builtin/uniforms/cc-shadow>

#include <common/lighting/functions>

out float v_dist;

vec4 vert () {

vec4 position;

CCVertInput(position);

// World Space

mat4 matWorld, matWorldIT;

CCGetWorldMatrixFull(matWorld, matWorldIT);

vec3 worldPos = (matWorld * position).xyz;

vec4 shadowPos = CalculatePlanarShadowPos(worldPos, cc_cameraPos.xyz, cc_mainLitDir.xyz, cc_planarNDInfo);

position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);

v_dist = shadowPos.w;

return position;

}

}%

CCProgram planar-shadow-fs %{

precision highp float;

#include <builtin/uniforms/cc-shadow>

#include <legacy/output>

in float v_dist;

vec4 frag () {

if(v_dist < 0.0)

  discard;

return CCFragOutput(cc_shadowColor);

}

}%
我之前拷贝unlit改的,内置的表面着色器我没用,surface shader文档看的很累 :rofl: :joy:

我也不想用的,3.8的模型导入用的就是自带的表面着色器:rofl:。只能复制过来改一改

晚上回去用builtin shader搞一个

不知道换成这个有没有影响,晚点试一下

全部都是法线的各种计算啊

vnormal是计算出来的哈, btw,如果你单纯搞描边的话,内置的toon的shader是有描边的效果的,你把里面描边相关的代码复制到builtin-standard.effect就可以了

builtin-standard-outline.effect.zip (4.8 KB)
在builtin-standard里面抄toon的描边。我同时修改了不显示负法线角度,你要是想显示就把这一段改回去: vec3 dir = normalize(localPos);
float flip = dot(dir, normalize(In.normal)) < 0.0 ? -1.0 : 1.0;
localPos += step(0.0, flip) * normalize(In.normal) * width;