PerfectVector
โดย Irene Kim

ฟิลเตอร์แสง SVG: ใส่เงาตราและเก็บช่องกลางไว้

สร้างแสง diffuse และ specular จากอัลฟาของตราโปร่งกลาง จำกัดผลในเงารูปร่าง และเก็บต้นฉบับเวกเตอร์แบนแยก

อ่าน 4 นาที
ในหน้านี้

หากต้องการโลโก้ SVG ที่ดูนูน ให้ทำ SourceAlpha นุ่มลง ส่งอัลฟานั้นเข้า feDiffuseLighting หรือ feSpecularLighting รวมแสงกับสีต้นฉบับ แล้วจบด้วยการประกอบ in กับ SourceAlpha เดิม ขั้นสุดท้ายเก็บผลไว้ภายในตราและรักษาช่องกลาง บันทึกสำเนาเส้นไม่ใส่ฟิลเตอร์เป็นต้นฉบับแบน

ผลนี้เปลี่ยนรูปลักษณ์เรนเดอร์ ไม่ได้สร้างวัตถุทึบนูน เส้นขอบใหม่ หรือไฟล์ผลิต คู่มือนี้ใช้ตราวงข้าวหลามตัดต้นฉบับที่เขียนเป็น SVG โดยตรงเพื่อเทียบขั้นแสงกับอัลฟา

ใช้อัลฟาเป็นพื้นผิวรับแสง

feDiffuseLighting ใช้อัลฟาอินพุตเป็นแผนที่ผิวนูนและให้แผนที่แสงทึบ รูปลักษณ์ขึ้นกับแสงและผิวอินพุต เอกสารแสง diffuse ของ MDN อธิบายพฤติกรรมนี้ ในตัวอย่าง ส่วนทึบของวงเป็นพื้นที่สูงและช่องกลางเป็นพื้นที่ต่ำ

เราเบลอเพียง SourceAlpha โดยเก็บเส้นสีเดิมเป็น SourceGraphic อัลฟาที่นุ่มทำให้การคำนวณแสงมีการเปลี่ยนระดับค่อยเป็นค่อยไปที่ขอบในและนอก feGaussianBlur ควบคุมความนุ่มผ่าน stdDeviation ตัวอย่างใช้ 2.5 ในฟิลเตอร์ที่ระบุพื้นที่ผู้ใช้ชัดเจน

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

คัดลอกตัวอย่างตราใส่เงาครบชุด

บันทึกเป็น emblem-lighting.svg แล้วเปิดในเบราว์เซอร์ มีเส้นประกอบหนึ่งเส้นและไม่พึ่งภาพภายนอก

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200">
  <defs>
    <filter id="relief" filterUnits="userSpaceOnUse" primitiveUnits="userSpaceOnUse" x="0" y="0" width="200" height="200" color-interpolation-filters="linearRGB">
      <feGaussianBlur in="SourceAlpha" stdDeviation="2.5" result="bump"/>
      <feDiffuseLighting in="bump" surfaceScale="4" diffuseConstant="1" lighting-color="#ffffff" result="diffuse">
      <feDistantLight azimuth="225" elevation="45"/>
      </feDiffuseLighting>
      <feComposite in="SourceGraphic" in2="diffuse" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" result="lit"/>
      <feSpecularLighting in="bump" surfaceScale="4" specularConstant=".7" specularExponent="18" lighting-color="#ffffff" result="shine">
      <feDistantLight azimuth="225" elevation="45"/>
      </feSpecularLighting>
      <feComposite in="lit" in2="shine" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="paint"/>
      <feComposite in="paint" in2="SourceAlpha" operator="in"/>
    </filter>
  </defs>
  <path d="M100 20 L180 100 L100 180 L20 100 Z M100 58 L142 100 L100 142 L58 100 Z" fill="#dc795f" fill-rule="evenodd" filter="url(#relief)"/>
</svg>

ฟิลเตอร์ตั้งชื่อผลระหว่างทางแต่ละตัวเพื่อให้ตรวจหน้าที่ได้:

ขั้นอินพุตและผลจุดประสงค์
เบลอSourceAlpha → bumpทำการเปลี่ยนความสูงให้นุ่ม
Diffusebump → diffuseคำนวณแสงกระจายกว้าง
คูณSourceGraphic × diffuse → litใส่เงาสีต้นฉบับ
Specularbump → shineคำนวณส่วนสะท้อน
บวกlit + shine → paintรวมเงาและแสงเน้น
จำกัดขอบpaint in SourceAlphaคืนเงารูปร่างและช่องเดิม

การคูณเชิงคณิตศาสตร์ใช้ k1="1" และสัมประสิทธิ์อื่นศูนย์ การบวกใช้ k2="1" k3="1" และที่เหลือศูนย์ feComposite นิยามการทำงานพิกเซลเหล่านี้กับตัวดำเนินการ in หากต้องการขอบเดิม ให้คงอินพุตที่สองของการประกอบท้ายเป็น SourceAlpha แทน bump ที่เบลอ

ฟิลเตอร์ระบุ color-interpolation-filters="linearRGB" ชัดเจน ซึ่งเป็นค่าเริ่มต้นของการทำงานฟิลเตอร์ SVG เรื่องนี้แยกจากการคำนวณสีระบายทั่วไป เอกสาร color-interpolation-filters ของ MDN อธิบายความต่าง ตัวอย่างแสงที่วัดทั้งหมดใช้ค่าเดียวกันนี้

เทียบเงา diffuse กับความเงา specular

แสง diffuse ทำให้สีเดิมมืดและสว่างตามแผนที่แสง ขั้น specular เพิ่มส่วนสะท้อน feSpecularLighting อธิบายผลที่ขึ้นกับแสงและพารามิเตอร์ ตัวอย่างใช้ค่าคงที่พอเหมาะ .7 กับเลขชี้กำลัง 18 ปรับหลังได้ผล diffuse ที่ใช้ได้แล้ว

หากต้องการตรวจ diffuse อย่างเดียว คงขั้นเบลอ diffuse และคูณ แล้วเปลี่ยนอินพุตแรกของการประกอบสุดท้ายจาก paint เป็น lit ลบขั้น specular และบวก

หากต้องการตรวจ specular อย่างเดียวบนสีแบน คงเบลอและ specular เปลี่ยนอินพุตแรกของการบวกจาก lit เป็น SourceGraphic ลบ diffuse และคูณ แล้วเก็บการประกอบท้าย paint in SourceAlpha ทั้งสองการเทียบคงเส้นเดิมและทิศแสงเดียวกัน

แสงไกลของเราใช้ azimuth="225" elevation="45" feDistantLight เป็นองค์ประกอบแหล่งแสงให้ฟิลเตอร์แสงทั้งคู่ มุมเหล่านี้เป็นองศา ไม่ใช่ตำแหน่งพิกเซล เปลี่ยนทิศในสองขั้นแสงพร้อมกันเมื่อเทียบผลรวม

ผลการควบคุมต้นฉบับในเบราว์เซอร์

เราเปิดตัวอย่าง SVG ที่สร้างหกไฟล์ใน Chrome ที่ 80 × 80 และ 160 × 160 พิกเซล CSS ต้นฉบับแบน ผล diffuse, specular และรวมยังเห็นต่างกันชัด surfaceScale ของ diffuse ที่สูงขึ้นทำให้คอนทราสต์ขอบแรงขึ้นในไฟล์ทดสอบนี้ ตัวควบคุม diffuse ดิบแสดงสี่เหลี่ยมเทาที่ช่องถูกเติมแทนเงารูปร่างโปร่งใส

การอ่านพิกเซลแยกใช้ขนาด Canvas ต้นฉบับ 200 × 200 ตัวอย่างแถบอยู่ที่ (100, 38) ขอบที่ (101, 22) ช่องที่ (100, 100) และภายนอกที่ (10, 10)

ตัวอย่างRGB แถบRGB ขอบอัลฟาช่อง / ภายนอก
ต้นฉบับแบน220, 121, 95220, 121, 950 / 0
แผนที่แสง diffuse ดิบ สเกล 4219, 219, 219214, 214, 214255 / 255
สี diffuse สเกล 4 จำกัดขอบ189, 102, 81185, 101, 790 / 0
สี diffuse สเกล 12 จำกัดขอบ189, 102, 81155, 83, 640 / 0
Specular บนสีแบน สเกล 4 จำกัดขอบ242, 162, 145221, 122, 960 / 0
ผลรวม สเกล 4 จำกัดขอบ214, 149, 137185, 102, 810 / 0

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

แสงกับต้นฉบับแบน
ภาพแนวคิดของตราข้าวหลามตัดโปร่งกลางที่เหมือนกัน แต่ใช้สีแบน เงากว้าง และแสงเน้นเฉพาะจุด
ภาพอธิบาย: เงา diffuse และความเงา specular ปรับเส้นขอบเดียวกันได้โดยช่องยังว่าง นี่ไม่ใช่ตัวอย่างเบราว์เซอร์ ผลลอกลาย หรืองานนูนจริง

ปรับสนามความสูงก่อนเปลี่ยนเส้นขอบ

surfaceScale ตั้งสเกลความสูงผิวที่ใช้คำนวณแสง ไม่ได้ขยายเส้น ตัวควบคุม diffuse 4 กับ 12 ของเราเปลี่ยนเฉพาะค่านี้ แถบแบนที่อ่านมีสีเดิม แต่จุดขอบมืดขึ้นที่ 12

ใช้ลำดับที่ควบคุมไว้:

  1. ตรวจเงารูปร่างโปร่งใสและช่องต้นฉบับโดยไม่ใส่ฟิลเตอร์
  2. เลือกความนุ่มอัลฟาและทิศแสง
  3. เทียบ surfaceScale เล็กกับใหญ่โดยคงค่าอื่น
  4. เพิ่มความเงา specular แล้วจำกัดสีด้วยอัลฟาเดิมเป็นขั้นสุดท้าย
  5. ตรวจภาพส่งจริงที่ขนาดแสดงจริงและบนพื้นหลังตัดกัน

ข้อกำหนด Filter Effects ปัจจุบัน นิยามอัลฟาผล diffuse เป็นหนึ่งทุกจุด ส่วนอัลฟาผล specular มาจากองค์ประกอบสี ไม่ควรคิดว่าผลใดจะเก็บช่องเดิม อีกทั้งระบุการคำนวณแนวตั้งฉากจากจุดอัลฟาเพื่อนบ้าน โค้ดเริ่มต้นไม่ตั้ง kernelUnitLength การตรวจสองขนาดของเราไม่ได้ยืนยันว่าจุดตัวอย่างแสงไม่ขึ้นกับขนาด

หากบัฟเฟอร์ระหว่างขั้นแสงปรากฏเป็นผลสุดท้าย ให้ตรวจอินพุตที่ตั้งชื่อและองค์ประกอบสุดท้าย สำหรับวงนี้ การคืนแผนที่ diffuse โดยตรงเป็นวิธีที่เราทำให้เกิดสี่เหลี่ยมเทาทึบ ขั้นท้าย in SourceAlpha ตั้งใจใส่ แม้การคูณก่อนหน้าดูเหมือนเก็บความโปร่งใสแล้ว

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

ส่งผลบนจอพร้อมต้นฉบับแบน

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

สำหรับผิวงานจริง ใช้ขั้นเตรียมแยก เช่น ภาพเวกเตอร์สำหรับปั๊มนูน พรีเซ็ตแสงบนจอให้รูปลักษณ์ ไม่ใช่รูปทรงแม่พิมพ์หรือความลึกนูนที่วัดได้ คู่มือเส้นขอบด้วย morphology SVG อธิบายการแต่งขอบด้วยฟิลเตอร์อีกแบบโดยไม่ถือว่าเป็นเส้นสร้างใหม่

หากโลโก้มีเพียง PNG หรือ JPG ให้แปลงโลโก้เป็นเวกเตอร์ด้วย PerfectVector ตรวจเส้นนอกและช่องที่กู้ แล้วเก็บต้นฉบับแบนสะอาดก่อนใส่แสงในขั้นตอน SVG บริการกู้รูปทรงเวกเตอร์ ส่วนขั้น diffuse/specular นี้เป็นผลแสดงที่สร้างแยก หากมีต้นฉบับเวกเตอร์แล้ว ให้ใช้และตรวจฟิลเตอร์โดยตรง

คำถามที่พบบ่อย

ฟิลเตอร์แสง SVG ทำให้โลโก้ดูนูนได้หรือไม่? จำลองเงาและแสงเน้นจากสนามความสูงอิงอัลฟาได้ ผลเรนเดอร์ไม่ได้สร้างงานนูนจริง เส้นขอบเพิ่ม หรือไฟล์แม่พิมพ์ผลิต

ทำไมผลแสง SVG เติมช่องโปร่งใส? แผนที่แสง diffuse ดิบทึบทั่วพื้นที่ฟิลเตอร์ รวมแสงกับสีเดิมแล้วจบด้วยการประกอบ in กับ SourceAlpha เดิม เพื่อจำกัดผลในเงารูปร่างเดิม

แสง diffuse กับ specular ใน SVG ต่างกันอย่างไร? Diffuse ให้แสงกว้างสำหรับใส่เงาสีเดิม ส่วน specular ให้ส่วนสะท้อนเพิ่มเป็นความเงา ทั้งคู่ใช้อัลฟาอินพุตเป็นแผนที่ผิวนูนและขึ้นกับแสงกับค่าผิวที่เลือก

surfaceScale เปลี่ยนเส้นโลโก้หรือไม่? ไม่ มันเปลี่ยนสเกลความสูงในการคำนวณแสง ในตัวควบคุม diffuse สองแบบของเรา ข้อมูลเส้นเหมือนเดิมแต่คอนทราสต์ขอบเรนเดอร์เปลี่ยน

แหล่งข้อมูล

  1. MDN feDiffuseLighting — อินพุตแผนที่ผิวนูนอัลฟาและผลแสง diffuse ทึบ
  2. MDN feGaussianBlur — อินพุตนุ่มและประเด็นพื้นที่ฟิลเตอร์
  3. MDN feComposite — การคูณ/บวกเชิงคณิตศาสตร์และจำกัดด้วยอัลฟาต้นฉบับ
  4. MDN color-interpolation-filters — linearRGB เริ่มต้นของการทำงานฟิลเตอร์
  5. MDN feSpecularLighting — ส่วนสะท้อนและตัวควบคุม
  6. MDN feDistantLight — แหล่งแสงสำหรับองค์ประกอบแสงทั้งคู่
  7. MDN surfaceScale — สเกลความสูงผิวสำหรับคำนวณ
  8. ข้อกำหนดแสง Filter Effects — อัลฟาแสง หน่วยมุม และการคำนวณจุดเพื่อนบ้าน

เพิ่มเติมจากบล็อก

PerfectVector

เริ่มต้นด้วย SVG ที่เรียบร้อยขึ้น
และแก้ไขได้ง่ายกว่า

ไม่ต้องใช้บัตรเครดิต