ข้อมูลเบื้องต้นเกี่ยวกับตัวกรองที่กำหนดเอง (หรือที่เรียกว่า CSS Shaders)

ตัวกรองที่กำหนดเองหรือตัวปรับแสงเงา CSS ตามที่เคยถูกเรียก ช่วยให้คุณใช้ศักยภาพของตัวให้เฉดสีของ WebGL กับเนื้อหา DOM ของคุณได้ เนื่องจากในการใช้งานปัจจุบัน ตัวให้เฉดสีที่ใช้นั้นแทบจะเหมือนกับใน WebGL คุณจึงต้องถอยหลังไป 1 ก้าวเพื่อทำความเข้าใจคำศัพท์เกี่ยวกับ 3 มิติบางส่วนและไปป์ไลน์กราฟิกเล็กน้อย

ฉันได้รวมงานนำเสนอเวอร์ชันที่บันทึกไว้ที่ฉันส่งไปให้ที่ LondonJS เมื่อเร็วๆ นี้ ในวิดีโอ ผมจะพูดถึงภาพรวมของคำศัพท์แบบ 3 มิติที่คุณต้องทำความเข้าใจ ตัวแปรประเภทต่างๆ ที่จะเจอ และวิธีเริ่มเล่นตัวกรองที่กำหนดเองในวันนี้ นอกจากนี้ คุณควรเตรียมสไลด์ไว้เพื่อจะได้เล่นเดโมด้วยตนเอง

ข้อมูลเบื้องต้นเกี่ยวกับเครื่องมือให้เฉดสี

เราได้เขียนข้อมูลเบื้องต้นเกี่ยวกับตัวให้เฉดสีซึ่งจะให้รายละเอียดที่ดีว่าเครื่องมือให้เฉดสีคืออะไรและคุณจะใช้อย่างไรจากมุมมองของ WebGL หากคุณไม่เคยใช้ตัวให้เฉดสีมาก่อน เราจำเป็นต้องอ่านก่อนที่จะเรียนรู้เพิ่มเติม เพราะแนวคิดของตัวกรองที่กำหนดเองและภาษาที่ขึ้นอยู่กับคำศัพท์ของตัวปรับแสงเงา WebGL ที่มีอยู่

ด้วยเหตุนี้ มาเปิดใช้งานตัวกรองที่กำหนดเองและดําเนินการกัน

การเปิดใช้ตัวกรองที่กำหนดเอง

ตัวกรองที่กำหนดเองมีให้ใช้งานทั้งใน Chrome และ Canary รวมทั้ง Chrome สำหรับ Android เพียงไปที่ about:flags และค้นหา "CSS Shaders" จากนั้นเปิดใช้และรีสตาร์ทเบราว์เซอร์ คุณพร้อมเริ่มต้นใช้งานแล้ว

ไวยากรณ์

ตัวกรองที่กำหนดเองจะขยายชุดตัวกรองที่คุณใช้กับองค์ประกอบ DOM ได้อยู่แล้ว เช่น blur หรือ sepia Eric Bidelman ได้เขียนเครื่องมือสนามเด็กเล่นที่ยอดเยี่ยมไว้ให้คุณนำไปใช้ดู

หากต้องการใช้ตัวกรองที่กำหนดเองกับองค์ประกอบ DOM ให้ใช้ไวยากรณ์ต่อไปนี้

.customShader {
    -webkit-filter:

    custom(
        url(vertexshader.vert)
        mix(url(fragment.frag) normal source-atop),

    /* Row, columns - the vertices are made automatically */
    4 5,

    /* We set uniforms; we can't set attributes */
    time 0)
}

คุณจะเห็นได้ว่า เราจะประกาศตัวสร้างเฉดสีแบบจุดยอดและตัวแบ่งส่วน จำนวนแถวและคอลัมน์ที่ต้องการให้แยกองค์ประกอบ DOM ไปจนถึงชุดเครื่องแบบที่เราต้องการส่งต่อ

เรื่องสุดท้ายที่ต้องพูดถึงคือ เราใช้ฟังก์ชัน mix() รอบๆ ตัวปรับแสงเงาส่วนด้วยโหมดผสาน (normal) และโหมดผสม (source-atop) เราลองมาดูตัวปรับเฉดสีส่วนย่อยเพื่อหาสาเหตุที่เราต้องใช้ฟังก์ชัน mix() กัน

พุช Pixel

หากคุณคุ้นเคยกับเครื่องมือให้เฉดสีของ WebGL คุณจะเห็นว่าในตัวกรองที่กำหนดเองมีความแตกต่างเล็กน้อย สำหรับตัวอย่างหนึ่ง เราจะไม่สร้างพื้นผิวที่ตัวปรับเฉดสีของเราใช้ในการเติมพิกเซล แต่เนื้อหา DOM ที่มีการใช้ตัวกรองจะถูกแมปกับพื้นผิวโดยอัตโนมัติ ซึ่งหมายความว่ามี 2 สิ่งต่อไปนี้

  1. เพื่อความปลอดภัย เราไม่สามารถค้นหาค่าสีแต่ละพิกเซลของพื้นผิว DOM ได้
  2. เราไม่ได้กำหนดสีพิกเซลสุดท้ายด้วยตัวเอง (อย่างน้อยก็ในการติดตั้งใช้งานปัจจุบัน) กล่าวคือ จำกัดการใช้งาน gl_FragColor แต่จะมีสมมติฐานว่าคุณต้องการแสดงผลเนื้อหา DOM และสิ่งที่คุณต้องทําคือการจัดการพิกเซลของออบเจ็กต์ทางอ้อมผ่าน css_ColorMatrix และ css_MixColor

ซึ่งหมายความว่า Hello World ของตัวสร้างเฉดสีส่วนย่อยจะมีลักษณะเช่นนี้

void main() {
    css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
                            0.0, 1.0, 0.0, 0.0,
                            0.0, 0.0, 1.0, 0.0,
                            0.0, 0.0, 0.0, 1.0);

    css_MixColor = vec4(0.0, 0.0, 0.0, 0.0);

    // umm, where did gl_FragColor go?
}

พิกเซลแต่ละพิกเซลของเนื้อหา DOM จะคูณด้วย css_ColorMatrix ซึ่งในกรณีข้างต้นจะไม่มีผลใดๆ ในเมทริกซ์ตัวตน และไม่ได้เปลี่ยนแปลงค่า RGBA ใดๆ ถ้าเราต้องการ ให้คงค่าสีแดงไว้ เราจะใช้ css_ColorMatrix ดังนี้

// keep only red and alpha
css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 1.0);

คุณจะเห็นได้ว่าเมื่อคุณคูณค่าพิกเซล 4 มิติ (RGBA) ด้วยเมทริกซ์ คุณจะได้ค่าพิกเซลที่ผ่านการดัดแปลงจากอีกด้านหนึ่ง และในกรณีนี้คือค่าที่ทำให้องค์ประกอบสีเขียวและสีน้ำเงินเป็นศูนย์

css_MixColor จะใช้เป็นสีพื้นฐานที่คุณต้องการเป็นหลัก โดยจะผสมกับเนื้อหา DOM ของคุณ การผสมจะกระทำผ่านโหมดการผสมที่คุณจะคุ้นเคยจากแพ็กเกจศิลปะ ไม่ว่าจะเป็นการซ้อนทับ หน้าจอ การหลบสี แสงที่แข็ง และอื่นๆ

มีหลายวิธีที่ตัวแปรสองตัวนี้สามารถจัดการพิกเซล ดูข้อกำหนดของเอฟเฟกต์ตัวกรองเพื่อให้เข้าใจวิธีการทำงานของโหมดผสานและโหมดผสมได้ดีขึ้น

การสร้าง Vertex

ใน WebGL เรารับผิดชอบอย่างเต็มที่ในการสร้างจุด 3 มิติของ Mesh แต่ในตัวกรองที่กำหนดเอง คุณเพียงแค่ระบุจำนวนแถวและคอลัมน์ที่คุณต้องการ และเบราว์เซอร์จะแยกเนื้อหา DOM ของคุณออกเป็นรูปสามเหลี่ยมชุดหนึ่งโดยอัตโนมัติ ดังนี้

การสร้าง Vertex
รูปภาพแบ่งออกเป็นแถวและคอลัมน์

จากนั้นจุดยอดแต่ละจุดจะส่งผ่านไปยังตัวปรับแสงเงาจุดยอดเพื่อไปจัดการ และนั่นหมายความว่าเราสามารถเริ่มย้ายภาพเหล่านี้ไปรอบๆ พื้นที่ 3 มิติได้ตามต้องการ อีกไม่ช้าคุณ! จะสร้างเอฟเฟ็กต์เจ๋งๆ ได้

เอฟเฟกต์แอคคอร์เดียน
รูปภาพที่ถูกทำให้บิดเบี้ยวด้วยเอฟเฟกต์แอคคอร์เดียน

การสร้างภาพเคลื่อนไหวด้วยเฉดสี

การใส่ภาพเคลื่อนไหวลงในตัวให้เฉดสีเป็นสิ่งที่ทำให้ภาพสนุกและน่าสนใจ วิธีการคือใช้การเปลี่ยนหน้า (หรือภาพเคลื่อนไหว) ใน CSS เพื่ออัปเดตค่าที่เป็นแบบเดียวกัน

.shader {
    /* transition on the filter property */
    -webkit-transition: -webkit-filter 2500ms ease-out;

    -webkit-filter: custom(
    url(vshader.vert)
    mix(url(fshader.frag) normal source-atop),
    1 1,
    time 0);
}

    .shader:hover {
    -webkit-filter: custom(
    url(vshader.vert)
    mix(url(fshader.frag) normal source-atop),
    1 1,
    time 1);
}

ดังนั้น สิ่งที่ควรสังเกตในโค้ดด้านบนคือ เวลาจาก 0 เป็น 1 จะง่ายขึ้นในช่วงการเปลี่ยนผ่าน ภายในตัวปรับเฉดสี เราจะประกาศ time แบบเดียวกันและใช้ค่าปัจจุบันของค่าใดก็ได้ดังนี้

    uniform float time;

uniform mat4 u_projectionMatrix;
attribute vec4 a_position;

void main() {
    // copy a_position to position - attributes are read only!
    vec4 position = a_position;

    // use our time uniform from the CSS declaration
    position.x += time;

    gl_Position = u_projectionMatrix * position;
}

เริ่มเล่น!

การใช้ฟิลเตอร์ที่กำหนดเองนั้นสนุกมาก หากไม่มีฟิลเตอร์เหล่านี้ เอฟเฟกต์ที่น่าทึ่งที่คุณสร้างได้ก็ทำได้ยาก (และในบางกรณีก็ใช้ไม่ได้) นี่ยังคงเป็นเพียงช่วงเริ่มต้นและสิ่งต่างๆ ก็เปลี่ยนแปลงไม่น้อย แต่การเพิ่มสิ่งเหล่านั้นจะเพิ่มความน่าสนใจให้กับโปรเจ็กต์ของคุณนิดหน่อย ไม่งั้นก็ไม่มีประโยชน์ใช่ไหมล่ะ

แหล่งข้อมูลเพิ่มเติม